diff options
Diffstat (limited to 'xorg-server/mi')
47 files changed, 15391 insertions, 16678 deletions
diff --git a/xorg-server/mi/mi.h b/xorg-server/mi/mi.h index 24d1af911..638fc6bc7 100644 --- a/xorg-server/mi/mi.h +++ b/xorg-server/mi/mi.h @@ -22,7 +22,6 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved @@ -62,538 +61,480 @@ SOFTWARE. #define MiBits CARD32 typedef struct _miDash *miDashPtr; + #define EVEN_DASH 0 #define ODD_DASH ~0 /* miarc.c */ -extern _X_EXPORT void miPolyArc( - DrawablePtr /*pDraw*/, - GCPtr /*pGC*/, - int /*narcs*/, - xArc * /*parcs*/ -); +extern _X_EXPORT void miPolyArc(DrawablePtr /*pDraw */ , + GCPtr /*pGC */ , + int /*narcs */ , + xArc * /*parcs */ + ); /* mibitblt.c */ -extern _X_EXPORT RegionPtr miCopyArea( - DrawablePtr /*pSrcDrawable*/, - DrawablePtr /*pDstDrawable*/, - GCPtr /*pGC*/, - int /*xIn*/, - int /*yIn*/, - int /*widthSrc*/, - int /*heightSrc*/, - int /*xOut*/, - int /*yOut*/ -); - -extern _X_EXPORT RegionPtr miCopyPlane( - DrawablePtr /*pSrcDrawable*/, - DrawablePtr /*pDstDrawable*/, - GCPtr /*pGC*/, - int /*srcx*/, - int /*srcy*/, - int /*width*/, - int /*height*/, - int /*dstx*/, - int /*dsty*/, - unsigned long /*bitPlane*/ -); - -extern _X_EXPORT void miGetImage( - DrawablePtr /*pDraw*/, - int /*sx*/, - int /*sy*/, - int /*w*/, - int /*h*/, - unsigned int /*format*/, - unsigned long /*planeMask*/, - char * /*pdstLine*/ -); - -extern _X_EXPORT void miPutImage( - DrawablePtr /*pDraw*/, - GCPtr /*pGC*/, - int /*depth*/, - int /*x*/, - int /*y*/, - int /*w*/, - int /*h*/, - int /*leftPad*/, - int /*format*/, - char * /*pImage*/ -); +extern _X_EXPORT RegionPtr miCopyArea(DrawablePtr /*pSrcDrawable */ , + DrawablePtr /*pDstDrawable */ , + GCPtr /*pGC */ , + int /*xIn */ , + int /*yIn */ , + int /*widthSrc */ , + int /*heightSrc */ , + int /*xOut */ , + int /*yOut */ + ); + +extern _X_EXPORT RegionPtr miCopyPlane(DrawablePtr /*pSrcDrawable */ , + DrawablePtr /*pDstDrawable */ , + GCPtr /*pGC */ , + int /*srcx */ , + int /*srcy */ , + int /*width */ , + int /*height */ , + int /*dstx */ , + int /*dsty */ , + unsigned long /*bitPlane */ + ); + +extern _X_EXPORT void miGetImage(DrawablePtr /*pDraw */ , + int /*sx */ , + int /*sy */ , + int /*w */ , + int /*h */ , + unsigned int /*format */ , + unsigned long /*planeMask */ , + char * /*pdstLine */ + ); + +extern _X_EXPORT void miPutImage(DrawablePtr /*pDraw */ , + GCPtr /*pGC */ , + int /*depth */ , + int /*x */ , + int /*y */ , + int /*w */ , + int /*h */ , + int /*leftPad */ , + int /*format */ , + char * /*pImage */ + ); /* micopy.c */ #define miGetCompositeClip(pGC) ((pGC)->pCompositeClip) -typedef void (*miCopyProc) (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pDstBox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure); +typedef void (*miCopyProc) (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pDstBox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, Pixel bitplane, void *closure); extern _X_EXPORT void -miCopyRegion (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - RegionPtr pDstRegion, - int dx, - int dy, - miCopyProc copyProc, - Pixel bitPlane, - void *closure); + +miCopyRegion(DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + RegionPtr pDstRegion, + int dx, + int dy, miCopyProc copyProc, Pixel bitPlane, void *closure); extern _X_EXPORT RegionPtr -miDoCopy (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - int xIn, - int yIn, - int widthSrc, - int heightSrc, - int xOut, - int yOut, - miCopyProc copyProc, - Pixel bitplane, - void *closure); + +miDoCopy(DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut, miCopyProc copyProc, Pixel bitplane, void *closure); /* micursor.c */ -extern _X_EXPORT void miRecolorCursor( - DeviceIntPtr /* pDev */, - ScreenPtr /*pScr*/, - CursorPtr /*pCurs*/, - Bool /*displayed*/ -); +extern _X_EXPORT void miRecolorCursor(DeviceIntPtr /* pDev */ , + ScreenPtr /*pScr */ , + CursorPtr /*pCurs */ , + Bool /*displayed */ + ); /* midash.c */ -extern _X_EXPORT void miStepDash( - int /*dist*/, - int * /*pDashIndex*/, - unsigned char * /*pDash*/, - int /*numInDashList*/, - int * /*pDashOffset*/ -); +extern _X_EXPORT void miStepDash(int /*dist */ , + int * /*pDashIndex */ , + unsigned char * /*pDash */ , + int /*numInDashList */ , + int * /*pDashOffset */ + ); /* mieq.c */ - #ifndef INPUT_H typedef struct _DeviceRec *DevicePtr; #endif -extern _X_EXPORT Bool mieqInit( - void -); +extern _X_EXPORT Bool mieqInit(void + ); extern _X_EXPORT void mieqFini(void); -extern _X_EXPORT void mieqEnqueue( - DeviceIntPtr /*pDev*/, - InternalEvent* /*e*/ -); - -extern _X_EXPORT void mieqSwitchScreen( - DeviceIntPtr /* pDev */, - ScreenPtr /*pScreen*/, - Bool /*set_dequeue_screen*/ -); - -extern _X_EXPORT void mieqProcessDeviceEvent( - DeviceIntPtr /* dev*/, - InternalEvent* /* event */, - ScreenPtr /* screen*/ -); - -extern _X_EXPORT void mieqProcessInputEvents( - void -); - -extern DeviceIntPtr CopyGetMasterEvent( - DeviceIntPtr /* sdev */, - InternalEvent* /* original */, - InternalEvent* /* copy */ -); +extern _X_EXPORT void mieqEnqueue(DeviceIntPtr /*pDev */ , + InternalEvent * /*e */ + ); + +extern _X_EXPORT void mieqSwitchScreen(DeviceIntPtr /* pDev */ , + ScreenPtr /*pScreen */ , + Bool /*set_dequeue_screen */ + ); + +extern _X_EXPORT void mieqProcessDeviceEvent(DeviceIntPtr /* dev */ , + InternalEvent * /* event */ , + ScreenPtr /* screen */ + ); + +extern _X_EXPORT void mieqProcessInputEvents(void + ); + +extern DeviceIntPtr CopyGetMasterEvent(DeviceIntPtr /* sdev */ , + InternalEvent * /* original */ , + InternalEvent * /* copy */ + ); /** * Custom input event handler. If you need to process input events in some * other way than the default path, register an input event handler for the * given internal event type. */ -typedef void (*mieqHandler)(int screen, InternalEvent* event, DeviceIntPtr dev); +typedef void (*mieqHandler) (int screen, InternalEvent *event, + DeviceIntPtr dev); void _X_EXPORT mieqSetHandler(int event, mieqHandler handler); /* miexpose.c */ -extern _X_EXPORT RegionPtr miHandleExposures( - DrawablePtr /*pSrcDrawable*/, - DrawablePtr /*pDstDrawable*/, - GCPtr /*pGC*/, - int /*srcx*/, - int /*srcy*/, - int /*width*/, - int /*height*/, - int /*dstx*/, - int /*dsty*/, - unsigned long /*plane*/ -); - -extern _X_EXPORT void miSendGraphicsExpose( - ClientPtr /*client*/, - RegionPtr /*pRgn*/, - XID /*drawable*/, - int /*major*/, - int /*minor*/ -); - -extern _X_EXPORT void miSendExposures( - WindowPtr /*pWin*/, - RegionPtr /*pRgn*/, - int /*dx*/, - int /*dy*/ -); - -extern _X_EXPORT void miWindowExposures( - WindowPtr /*pWin*/, - RegionPtr /*prgn*/, - RegionPtr /*other_exposed*/ -); - -extern _X_EXPORT void miPaintWindow( - WindowPtr /*pWin*/, - RegionPtr /*prgn*/, - int /*what*/ -); - -extern _X_EXPORT void miClearDrawable( - DrawablePtr /*pDraw*/, - GCPtr /*pGC*/ -); +extern _X_EXPORT RegionPtr miHandleExposures(DrawablePtr /*pSrcDrawable */ , + DrawablePtr /*pDstDrawable */ , + GCPtr /*pGC */ , + int /*srcx */ , + int /*srcy */ , + int /*width */ , + int /*height */ , + int /*dstx */ , + int /*dsty */ , + unsigned long /*plane */ + ); + +extern _X_EXPORT void miSendGraphicsExpose(ClientPtr /*client */ , + RegionPtr /*pRgn */ , + XID /*drawable */ , + int /*major */ , + int /*minor */ + ); + +extern _X_EXPORT void miSendExposures(WindowPtr /*pWin */ , + RegionPtr /*pRgn */ , + int /*dx */ , + int /*dy */ + ); + +extern _X_EXPORT void miWindowExposures(WindowPtr /*pWin */ , + RegionPtr /*prgn */ , + RegionPtr /*other_exposed */ + ); + +extern _X_EXPORT void miPaintWindow(WindowPtr /*pWin */ , + RegionPtr /*prgn */ , + int /*what */ + ); + +extern _X_EXPORT void miClearDrawable(DrawablePtr /*pDraw */ , + GCPtr /*pGC */ + ); /* mifillrct.c */ -extern _X_EXPORT void miPolyFillRect( - DrawablePtr /*pDrawable*/, - GCPtr /*pGC*/, - int /*nrectFill*/, - xRectangle * /*prectInit*/ -); +extern _X_EXPORT void miPolyFillRect(DrawablePtr /*pDrawable */ , + GCPtr /*pGC */ , + int /*nrectFill */ , + xRectangle * /*prectInit */ + ); /* miglblt.c */ -extern _X_EXPORT void miPolyGlyphBlt( - DrawablePtr /*pDrawable*/, - GCPtr /*pGC*/, - int /*x*/, - int /*y*/, - unsigned int /*nglyph*/, - CharInfoPtr * /*ppci*/, - pointer /*pglyphBase*/ -); - -extern _X_EXPORT void miImageGlyphBlt( - DrawablePtr /*pDrawable*/, - GCPtr /*pGC*/, - int /*x*/, - int /*y*/, - unsigned int /*nglyph*/, - CharInfoPtr * /*ppci*/, - pointer /*pglyphBase*/ -); +extern _X_EXPORT void miPolyGlyphBlt(DrawablePtr /*pDrawable */ , + GCPtr /*pGC */ , + int /*x */ , + int /*y */ , + unsigned int /*nglyph */ , + CharInfoPtr * /*ppci */ , + pointer /*pglyphBase */ + ); + +extern _X_EXPORT void miImageGlyphBlt(DrawablePtr /*pDrawable */ , + GCPtr /*pGC */ , + int /*x */ , + int /*y */ , + unsigned int /*nglyph */ , + CharInfoPtr * /*ppci */ , + pointer /*pglyphBase */ + ); /* mipoly.c */ -extern _X_EXPORT void miFillPolygon( - DrawablePtr /*dst*/, - GCPtr /*pgc*/, - int /*shape*/, - int /*mode*/, - int /*count*/, - DDXPointPtr /*pPts*/ -); +extern _X_EXPORT void miFillPolygon(DrawablePtr /*dst */ , + GCPtr /*pgc */ , + int /*shape */ , + int /*mode */ , + int /*count */ , + DDXPointPtr /*pPts */ + ); /* mipolycon.c */ -extern _X_EXPORT Bool miFillConvexPoly( - DrawablePtr /*dst*/, - GCPtr /*pgc*/, - int /*count*/, - DDXPointPtr /*ptsIn*/ -); +extern _X_EXPORT Bool miFillConvexPoly(DrawablePtr /*dst */ , + GCPtr /*pgc */ , + int /*count */ , + DDXPointPtr /*ptsIn */ + ); /* mipolygen.c */ -extern _X_EXPORT Bool miFillGeneralPoly( - DrawablePtr /*dst*/, - GCPtr /*pgc*/, - int /*count*/, - DDXPointPtr /*ptsIn*/ -); +extern _X_EXPORT Bool miFillGeneralPoly(DrawablePtr /*dst */ , + GCPtr /*pgc */ , + int /*count */ , + DDXPointPtr /*ptsIn */ + ); /* mipolypnt.c */ -extern _X_EXPORT void miPolyPoint( - DrawablePtr /*pDrawable*/, - GCPtr /*pGC*/, - int /*mode*/, - int /*npt*/, - xPoint * /*pptInit*/ -); +extern _X_EXPORT void miPolyPoint(DrawablePtr /*pDrawable */ , + GCPtr /*pGC */ , + int /*mode */ , + int /*npt */ , + xPoint * /*pptInit */ + ); /* mipolyrect.c */ -extern _X_EXPORT void miPolyRectangle( - DrawablePtr /*pDraw*/, - GCPtr /*pGC*/, - int /*nrects*/, - xRectangle * /*pRects*/ -); +extern _X_EXPORT void miPolyRectangle(DrawablePtr /*pDraw */ , + GCPtr /*pGC */ , + int /*nrects */ , + xRectangle * /*pRects */ + ); /* mipolyseg.c */ -extern _X_EXPORT void miPolySegment( - DrawablePtr /*pDraw*/, - GCPtr /*pGC*/, - int /*nseg*/, - xSegment * /*pSegs*/ -); +extern _X_EXPORT void miPolySegment(DrawablePtr /*pDraw */ , + GCPtr /*pGC */ , + int /*nseg */ , + xSegment * /*pSegs */ + ); /* mipolytext.c */ -extern _X_EXPORT int miPolyText8( - DrawablePtr /*pDraw*/, - GCPtr /*pGC*/, - int /*x*/, - int /*y*/, - int /*count*/, - char * /*chars*/ -); - -extern _X_EXPORT int miPolyText16( - DrawablePtr /*pDraw*/, - GCPtr /*pGC*/, - int /*x*/, - int /*y*/, - int /*count*/, - unsigned short * /*chars*/ -); - -extern _X_EXPORT void miImageText8( - DrawablePtr /*pDraw*/, - GCPtr /*pGC*/, - int /*x*/, - int /*y*/, - int /*count*/, - char * /*chars*/ -); - -extern _X_EXPORT void miImageText16( - DrawablePtr /*pDraw*/, - GCPtr /*pGC*/, - int /*x*/, - int /*y*/, - int /*count*/, - unsigned short * /*chars*/ -); +extern _X_EXPORT int miPolyText8(DrawablePtr /*pDraw */ , + GCPtr /*pGC */ , + int /*x */ , + int /*y */ , + int /*count */ , + char * /*chars */ + ); + +extern _X_EXPORT int miPolyText16(DrawablePtr /*pDraw */ , + GCPtr /*pGC */ , + int /*x */ , + int /*y */ , + int /*count */ , + unsigned short * /*chars */ + ); + +extern _X_EXPORT void miImageText8(DrawablePtr /*pDraw */ , + GCPtr /*pGC */ , + int /*x */ , + int /*y */ , + int /*count */ , + char * /*chars */ + ); + +extern _X_EXPORT void miImageText16(DrawablePtr /*pDraw */ , + GCPtr /*pGC */ , + int /*x */ , + int /*y */ , + int /*count */ , + unsigned short * /*chars */ + ); /* mipushpxl.c */ -extern _X_EXPORT void miPushPixels( - GCPtr /*pGC*/, - PixmapPtr /*pBitMap*/, - DrawablePtr /*pDrawable*/, - int /*dx*/, - int /*dy*/, - int /*xOrg*/, - int /*yOrg*/ -); +extern _X_EXPORT void miPushPixels(GCPtr /*pGC */ , + PixmapPtr /*pBitMap */ , + DrawablePtr /*pDrawable */ , + int /*dx */ , + int /*dy */ , + int /*xOrg */ , + int /*yOrg */ + ); /* miscrinit.c */ -extern _X_EXPORT Bool miModifyPixmapHeader( - PixmapPtr /*pPixmap*/, - int /*width*/, - int /*height*/, - int /*depth*/, - int /*bitsPerPixel*/, - int /*devKind*/, - pointer /*pPixData*/ -); - -extern _X_EXPORT Bool miCreateScreenResources( - ScreenPtr /*pScreen*/ -); - -extern _X_EXPORT Bool miScreenDevPrivateInit( - ScreenPtr /*pScreen*/, - int /*width*/, - pointer /*pbits*/ -); - -extern _X_EXPORT Bool miScreenInit( - ScreenPtr /*pScreen*/, - pointer /*pbits*/, - int /*xsize*/, - int /*ysize*/, - int /*dpix*/, - int /*dpiy*/, - int /*width*/, - int /*rootDepth*/, - int /*numDepths*/, - DepthPtr /*depths*/, - VisualID /*rootVisual*/, - int /*numVisuals*/, - VisualPtr /*visuals*/ -); +extern _X_EXPORT Bool miModifyPixmapHeader(PixmapPtr /*pPixmap */ , + int /*width */ , + int /*height */ , + int /*depth */ , + int /*bitsPerPixel */ , + int /*devKind */ , + pointer /*pPixData */ + ); + +extern _X_EXPORT Bool miCreateScreenResources(ScreenPtr /*pScreen */ + ); + +extern _X_EXPORT Bool miScreenDevPrivateInit(ScreenPtr /*pScreen */ , + int /*width */ , + pointer /*pbits */ + ); + +extern _X_EXPORT Bool miScreenInit(ScreenPtr /*pScreen */ , + pointer /*pbits */ , + int /*xsize */ , + int /*ysize */ , + int /*dpix */ , + int /*dpiy */ , + int /*width */ , + int /*rootDepth */ , + int /*numDepths */ , + DepthPtr /*depths */ , + VisualID /*rootVisual */ , + int /*numVisuals */ , + VisualPtr /*visuals */ + ); /* mivaltree.c */ -extern _X_EXPORT int miShapedWindowIn( - RegionPtr /*universe*/, - RegionPtr /*bounding*/, - BoxPtr /*rect*/, - int /*x*/, - int /*y*/ -); +extern _X_EXPORT int miShapedWindowIn(RegionPtr /*universe */ , + RegionPtr /*bounding */ , + BoxPtr /*rect */ , + int /*x */ , + int /*y */ + ); -typedef void -(*SetRedirectBorderClipProcPtr) (WindowPtr pWindow, RegionPtr pRegion); +typedef void + (*SetRedirectBorderClipProcPtr) (WindowPtr pWindow, RegionPtr pRegion); typedef RegionPtr -(*GetRedirectBorderClipProcPtr) (WindowPtr pWindow); + (*GetRedirectBorderClipProcPtr) (WindowPtr pWindow); extern _X_EXPORT void -miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip, - GetRedirectBorderClipProcPtr getBorderClip); - -extern _X_EXPORT int miValidateTree( - WindowPtr /*pParent*/, - WindowPtr /*pChild*/, - VTKind /*kind*/ -); - -extern _X_EXPORT void miWideLine( - DrawablePtr /*pDrawable*/, - GCPtr /*pGC*/, - int /*mode*/, - int /*npt*/, - DDXPointPtr /*pPts*/ -); - -extern _X_EXPORT void miWideDash( - DrawablePtr /*pDrawable*/, - GCPtr /*pGC*/, - int /*mode*/, - int /*npt*/, - DDXPointPtr /*pPts*/ -); + +miRegisterRedirectBorderClipProc(SetRedirectBorderClipProcPtr setBorderClip, + GetRedirectBorderClipProcPtr getBorderClip); + +extern _X_EXPORT int miValidateTree(WindowPtr /*pParent */ , + WindowPtr /*pChild */ , + VTKind /*kind */ + ); + +extern _X_EXPORT void miWideLine(DrawablePtr /*pDrawable */ , + GCPtr /*pGC */ , + int /*mode */ , + int /*npt */ , + DDXPointPtr /*pPts */ + ); + +extern _X_EXPORT void miWideDash(DrawablePtr /*pDrawable */ , + GCPtr /*pGC */ , + int /*mode */ , + int /*npt */ , + DDXPointPtr /*pPts */ + ); /* miwindow.c */ -extern _X_EXPORT void miClearToBackground( - WindowPtr /*pWin*/, - int /*x*/, - int /*y*/, - int /*w*/, - int /*h*/, - Bool /*generateExposures*/ -); - -extern _X_EXPORT void miMarkWindow( - WindowPtr /*pWin*/ -); - -extern _X_EXPORT Bool miMarkOverlappedWindows( - WindowPtr /*pWin*/, - WindowPtr /*pFirst*/, - WindowPtr * /*ppLayerWin*/ -); - -extern _X_EXPORT void miHandleValidateExposures( - WindowPtr /*pWin*/ -); - -extern _X_EXPORT void miMoveWindow( - WindowPtr /*pWin*/, - int /*x*/, - int /*y*/, - WindowPtr /*pNextSib*/, - VTKind /*kind*/ -); - -extern _X_EXPORT void miSlideAndSizeWindow( - WindowPtr /*pWin*/, - int /*x*/, - int /*y*/, - unsigned int /*w*/, - unsigned int /*h*/, - WindowPtr /*pSib*/ -); - -extern _X_EXPORT WindowPtr miGetLayerWindow( - WindowPtr /*pWin*/ -); - -extern _X_EXPORT void miSetShape( - WindowPtr /*pWin*/, - int /*kind*/ -); - -extern _X_EXPORT void miChangeBorderWidth( - WindowPtr /*pWin*/, - unsigned int /*width*/ -); - -extern _X_EXPORT void miMarkUnrealizedWindow( - WindowPtr /*pChild*/, - WindowPtr /*pWin*/, - Bool /*fromConfigure*/ -); - -extern _X_EXPORT void miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth); +extern _X_EXPORT void miClearToBackground(WindowPtr /*pWin */ , + int /*x */ , + int /*y */ , + int /*w */ , + int /*h */ , + Bool /*generateExposures */ + ); + +extern _X_EXPORT void miMarkWindow(WindowPtr /*pWin */ + ); + +extern _X_EXPORT Bool miMarkOverlappedWindows(WindowPtr /*pWin */ , + WindowPtr /*pFirst */ , + WindowPtr * /*ppLayerWin */ + ); + +extern _X_EXPORT void miHandleValidateExposures(WindowPtr /*pWin */ + ); + +extern _X_EXPORT void miMoveWindow(WindowPtr /*pWin */ , + int /*x */ , + int /*y */ , + WindowPtr /*pNextSib */ , + VTKind /*kind */ + ); + +extern _X_EXPORT void miSlideAndSizeWindow(WindowPtr /*pWin */ , + int /*x */ , + int /*y */ , + unsigned int /*w */ , + unsigned int /*h */ , + WindowPtr /*pSib */ + ); + +extern _X_EXPORT WindowPtr miGetLayerWindow(WindowPtr /*pWin */ + ); + +extern _X_EXPORT void miSetShape(WindowPtr /*pWin */ , + int /*kind */ + ); + +extern _X_EXPORT void miChangeBorderWidth(WindowPtr /*pWin */ , + unsigned int /*width */ + ); + +extern _X_EXPORT void miMarkUnrealizedWindow(WindowPtr /*pChild */ , + WindowPtr /*pWin */ , + Bool /*fromConfigure */ + ); + +extern _X_EXPORT void miSegregateChildren(WindowPtr pWin, RegionPtr pReg, + int depth); /* mizerarc.c */ -extern _X_EXPORT void miZeroPolyArc( - DrawablePtr /*pDraw*/, - GCPtr /*pGC*/, - int /*narcs*/, - xArc * /*parcs*/ -); +extern _X_EXPORT void miZeroPolyArc(DrawablePtr /*pDraw */ , + GCPtr /*pGC */ , + int /*narcs */ , + xArc * /*parcs */ + ); /* mizerline.c */ -extern _X_EXPORT void miZeroLine( - DrawablePtr /*dst*/, - GCPtr /*pgc*/, - int /*mode*/, - int /*nptInit*/, - DDXPointRec * /*pptInit*/ -); - -extern _X_EXPORT void miZeroDashLine( - DrawablePtr /*dst*/, - GCPtr /*pgc*/, - int /*mode*/, - int /*nptInit*/, - DDXPointRec * /*pptInit*/ -); - -extern _X_EXPORT void miPolyFillArc( - DrawablePtr /*pDraw*/, - GCPtr /*pGC*/, - int /*narcs*/, - xArc * /*parcs*/ -); - -#endif /* MI_H */ +extern _X_EXPORT void miZeroLine(DrawablePtr /*dst */ , + GCPtr /*pgc */ , + int /*mode */ , + int /*nptInit */ , + DDXPointRec * /*pptInit */ + ); + +extern _X_EXPORT void miZeroDashLine(DrawablePtr /*dst */ , + GCPtr /*pgc */ , + int /*mode */ , + int /*nptInit */ , + DDXPointRec * /*pptInit */ + ); + +extern _X_EXPORT void miPolyFillArc(DrawablePtr /*pDraw */ , + GCPtr /*pGC */ , + int /*narcs */ , + xArc * /*parcs */ + ); + +#endif /* MI_H */ diff --git a/xorg-server/mi/miarc.c b/xorg-server/mi/miarc.c index 9fc8f478c..a73bce9e6 100644 --- a/xorg-server/mi/miarc.c +++ b/xorg-server/mi/miarc.c @@ -22,7 +22,6 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved @@ -78,9 +77,9 @@ static double cbrt(double x) { if (x > 0.0) - return pow(x, 1.0/3.0); + return pow(x, 1.0 / 3.0); else - return -pow(-x, 1.0/3.0); + return -pow(-x, 1.0 / 3.0); } #endif @@ -107,30 +106,32 @@ cbrt(double x) #undef max #undef min -_X_INLINE static int max (const int x, const int y) +_X_INLINE static int +max(const int x, const int y) { - return x>y? x:y; + return x > y ? x : y; } -_X_INLINE static int min (const int x, const int y) +_X_INLINE static int +min(const int x, const int y) { - return x<y? x:y; + return x < y ? x : y; } struct bound { - double min, max; + double min, max; }; struct ibound { - int min, max; + int min, max; }; #define boundedLe(value, bounds)\ ((bounds).min <= (value) && (value) <= (bounds).max) struct line { - double m, b; - int valid; + double m, b; + int valid; }; #define intersectLine(y,line) (line.m * (y) + line.b) @@ -140,67 +141,67 @@ struct line { */ struct arc_bound { - struct bound ellipse; - struct bound inner; - struct bound outer; - struct bound right; - struct bound left; - struct ibound inneri; - struct ibound outeri; + struct bound ellipse; + struct bound inner; + struct bound outer; + struct bound right; + struct bound left; + struct ibound inneri; + struct ibound outeri; }; struct accelerators { - double tail_y; - double h2; - double w2; - double h4; - double w4; - double h2mw2; - double h2l; - double w2l; - double fromIntX; - double fromIntY; - struct line left, right; - int yorgu; - int yorgl; - int xorg; + double tail_y; + double h2; + double w2; + double h4; + double w4; + double h2mw2; + double h2l; + double w2l; + double fromIntX; + double fromIntY; + struct line left, right; + int yorgu; + int yorgl; + int xorg; }; struct arc_def { - double w, h, l; - double a0, a1; + double w, h, l; + double a0, a1; }; -# define todeg(xAngle) (((double) (xAngle)) / 64.0) +#define todeg(xAngle) (((double) (xAngle)) / 64.0) -# define RIGHT_END 0 -# define LEFT_END 1 +#define RIGHT_END 0 +#define LEFT_END 1 typedef struct _miArcJoin { - int arcIndex0, arcIndex1; - int phase0, phase1; - int end0, end1; + int arcIndex0, arcIndex1; + int phase0, phase1; + int end0, end1; } miArcJoinRec, *miArcJoinPtr; typedef struct _miArcCap { - int arcIndex; - int end; + int arcIndex; + int end; } miArcCapRec, *miArcCapPtr; typedef struct _miArcFace { - SppPointRec clock; - SppPointRec center; - SppPointRec counterClock; + SppPointRec clock; + SppPointRec center; + SppPointRec counterClock; } miArcFaceRec, *miArcFacePtr; typedef struct _miArcData { - xArc arc; - int render; /* non-zero means render after drawing */ - int join; /* related join */ - int cap; /* related cap */ - int selfJoin; /* final dash meets first dash */ - miArcFaceRec bounds[2]; - double x0, y0, x1, y1; + xArc arc; + int render; /* non-zero means render after drawing */ + int join; /* related join */ + int cap; /* related cap */ + int selfJoin; /* final dash meets first dash */ + miArcFaceRec bounds[2]; + double x0, y0, x1, y1; } miArcDataRec, *miArcDataPtr; /* @@ -209,101 +210,98 @@ typedef struct _miArcData { */ typedef struct _miPolyArc { - int narcs; - miArcDataPtr arcs; - int ncaps; - miArcCapPtr caps; - int njoins; - miArcJoinPtr joins; + int narcs; + miArcDataPtr arcs; + int ncaps; + miArcCapPtr caps; + int njoins; + miArcJoinPtr joins; } miPolyArcRec, *miPolyArcPtr; static void fillSpans(DrawablePtr pDrawable, GCPtr pGC); static void newFinalSpan(int y, int xmin, int xmax); -static void drawArc(xArc *tarc, int l, int a0, int a1, miArcFacePtr right, - miArcFacePtr left); -static void drawZeroArc(DrawablePtr pDraw, GCPtr pGC, xArc *tarc, int lw, - miArcFacePtr left, miArcFacePtr right); +static void drawArc(xArc * tarc, int l, int a0, int a1, miArcFacePtr right, + miArcFacePtr left); +static void drawZeroArc(DrawablePtr pDraw, GCPtr pGC, xArc * tarc, int lw, + miArcFacePtr left, miArcFacePtr right); static void miArcJoin(DrawablePtr pDraw, GCPtr pGC, miArcFacePtr pLeft, - miArcFacePtr pRight, int xOrgLeft, int yOrgLeft, - double xFtransLeft, double yFtransLeft, - int xOrgRight, int yOrgRight, - double xFtransRight, double yFtransRight); + miArcFacePtr pRight, int xOrgLeft, int yOrgLeft, + double xFtransLeft, double yFtransLeft, + int xOrgRight, int yOrgRight, + double xFtransRight, double yFtransRight); static void miArcCap(DrawablePtr pDraw, GCPtr pGC, miArcFacePtr pFace, - int end, int xOrg, int yOrg, double xFtrans, - double yFtrans); + int end, int xOrg, int yOrg, double xFtrans, + double yFtrans); static void miRoundCap(DrawablePtr pDraw, GCPtr pGC, SppPointRec pCenter, - SppPointRec pEnd, SppPointRec pCorner, - SppPointRec pOtherCorner, int fLineEnd, - int xOrg, int yOrg, double xFtrans, double yFtrans); + SppPointRec pEnd, SppPointRec pCorner, + SppPointRec pOtherCorner, int fLineEnd, + int xOrg, int yOrg, double xFtrans, double yFtrans); static void miFreeArcs(miPolyArcPtr arcs, GCPtr pGC); -static miPolyArcPtr miComputeArcs(xArc *parcs, int narcs, GCPtr pGC); -static int miGetArcPts(SppArcPtr parc, int cpt, SppPointPtr *ppPts); +static miPolyArcPtr miComputeArcs(xArc * parcs, int narcs, GCPtr pGC); +static int miGetArcPts(SppArcPtr parc, int cpt, SppPointPtr * ppPts); -# define CUBED_ROOT_2 1.2599210498948732038115849718451499938964 -# define CUBED_ROOT_4 1.5874010519681993173435330390930175781250 +#define CUBED_ROOT_2 1.2599210498948732038115849718451499938964 +#define CUBED_ROOT_4 1.5874010519681993173435330390930175781250 /* * draw one segment of the arc using the arc spans generation routines */ static void -miArcSegment( - DrawablePtr pDraw, - GCPtr pGC, - xArc tarc, - miArcFacePtr right, - miArcFacePtr left) +miArcSegment(DrawablePtr pDraw, + GCPtr pGC, xArc tarc, miArcFacePtr right, miArcFacePtr left) { int l = pGC->lineWidth; int a0, a1, startAngle, endAngle; miArcFacePtr temp; if (!l) - l = 1; + l = 1; if (tarc.width == 0 || tarc.height == 0) { - drawZeroArc (pDraw, pGC, &tarc, l, left, right); - return; + drawZeroArc(pDraw, pGC, &tarc, l, left, right); + return; } if (pGC->miTranslate) { - tarc.x += pDraw->x; - tarc.y += pDraw->y; + tarc.x += pDraw->x; + tarc.y += pDraw->y; } a0 = tarc.angle1; a1 = tarc.angle2; if (a1 > FULLCIRCLE) - a1 = FULLCIRCLE; + a1 = FULLCIRCLE; else if (a1 < -FULLCIRCLE) - a1 = -FULLCIRCLE; + a1 = -FULLCIRCLE; if (a1 < 0) { - startAngle = a0 + a1; - endAngle = a0; - temp = right; - right = left; - left = temp; - } else { - startAngle = a0; - endAngle = a0 + a1; + startAngle = a0 + a1; + endAngle = a0; + temp = right; + right = left; + left = temp; + } + else { + startAngle = a0; + endAngle = a0 + a1; } /* * bounds check the two angles */ if (startAngle < 0) - startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE; + startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE; if (startAngle >= FULLCIRCLE) - startAngle = startAngle % FULLCIRCLE; + startAngle = startAngle % FULLCIRCLE; if (endAngle < 0) - endAngle = FULLCIRCLE - (-endAngle) % FULLCIRCLE; + endAngle = FULLCIRCLE - (-endAngle) % FULLCIRCLE; if (endAngle > FULLCIRCLE) - endAngle = (endAngle-1) % FULLCIRCLE + 1; + endAngle = (endAngle - 1) % FULLCIRCLE + 1; if ((startAngle == endAngle) && a1) { - startAngle = 0; - endAngle = FULLCIRCLE; + startAngle = 0; + endAngle = FULLCIRCLE; } - drawArc (&tarc, l, startAngle, endAngle, right, left); + drawArc(&tarc, l, startAngle, endAngle, right, left); } /* @@ -380,14 +378,11 @@ typedef struct { } miArcSpanData; static void drawQuadrant(struct arc_def *def, struct accelerators *acc, - int a0, int a1, int mask, miArcFacePtr right, - miArcFacePtr left, miArcSpanData *spdata); + int a0, int a1, int mask, miArcFacePtr right, + miArcFacePtr left, miArcSpanData * spdata); static void -miComputeCircleSpans( - int lw, - xArc *parc, - miArcSpanData *spdata) +miComputeCircleSpans(int lw, xArc * parc, miArcSpanData * spdata) { miArcSpan *span; int doinner; @@ -404,58 +399,48 @@ miComputeCircleSpans( dx = 1 - dy; MIWIDEARCSETUP(x, y, dy, slw, e, xk, xm, yk, ym); inslw = parc->width + doinner; - if (inslw > 0) - { - spdata->hole = spdata->top; - MIWIDEARCSETUP(inx, iny, dy, inslw, ine, inxk, inxm, inyk, inym); + if (inslw > 0) { + spdata->hole = spdata->top; + MIWIDEARCSETUP(inx, iny, dy, inslw, ine, inxk, inxm, inyk, inym); } - else - { - spdata->hole = FALSE; - doinner = -y; + else { + spdata->hole = FALSE; + doinner = -y; } spdata->count1 = -doinner - spdata->top; spdata->count2 = y + doinner; span = spdata->spans; - while (y) - { - MIFILLARCSTEP(slw); - span->lx = dy - x; - if (++doinner <= 0) - { - span->lw = slw; - span->rx = 0; - span->rw = span->lx + slw; - } - else - { - MIFILLINARCSTEP(inslw); - span->lw = x - inx; - span->rx = dy - inx + inslw; - span->rw = inx - x + slw - inslw; - } - span++; - } - if (spdata->bot) - { - if (spdata->count2) - spdata->count2--; - else - { - if (lw > (int)parc->height) - span[-1].rx = span[-1].rw = -((lw - (int)parc->height) >> 1); - else - span[-1].rw = 0; - spdata->count1--; - } + while (y) { + MIFILLARCSTEP(slw); + span->lx = dy - x; + if (++doinner <= 0) { + span->lw = slw; + span->rx = 0; + span->rw = span->lx + slw; + } + else { + MIFILLINARCSTEP(inslw); + span->lw = x - inx; + span->rx = dy - inx + inslw; + span->rw = inx - x + slw - inslw; + } + span++; + } + if (spdata->bot) { + if (spdata->count2) + spdata->count2--; + else { + if (lw > (int) parc->height) + span[-1].rx = span[-1].rw = -((lw - (int) parc->height) >> 1); + else + span[-1].rw = 0; + spdata->count1--; + } } } static void -miComputeEllipseSpans( - int lw, - xArc *parc, - miArcSpanData *spdata) +miComputeEllipseSpans(int lw, xArc * parc, miArcSpanData * spdata) { miArcSpan *span; double w, h, r, xorg; @@ -463,8 +448,8 @@ miComputeEllipseSpans( double A, T, b, d, x, y, t, inx, outx = 0.0, hepp, hepm; int flip, solution; - w = (double)parc->width / 2.0; - h = (double)parc->height / 2.0; + w = (double) parc->width / 2.0; + h = (double) parc->height / 2.0; r = lw / 2.0; rs = r * r; Hs = h * h; @@ -479,177 +464,159 @@ miComputeEllipseSpans( K = h + ((lw - 1) >> 1); span = spdata->spans; if (parc->width & 1) - xorg = .5; + xorg = .5; else - xorg = 0.0; - if (spdata->top) - { - span->lx = 0; - span->lw = 1; - span++; + xorg = 0.0; + if (spdata->top) { + span->lx = 0; + span->lw = 1; + span++; } spdata->count1 = 0; spdata->count2 = 0; spdata->hole = (spdata->top && - (int)parc->height * lw <= (int)(parc->width * parc->width) && - lw < (int)parc->height); - for (; K > 0.0; K -= 1.0) - { - N = (K * K + Nk) / 6.0; - Nc = N * N * N; - Vr = Vk * K; - t = Nc + Vr * Vr; - d = Nc + t; - if (d < 0.0) { - d = Nc; - b = N; - if ( (b < 0.0) == (t < 0.0) ) - { - b = -b; - d = -d; - } - Z = N - 2.0 * b * cos(acos(-t / d) / 3.0); - if ( (Z < 0.0) == (Vr < 0.0) ) - flip = 2; - else - flip = 1; - } - else - { - d = Vr * sqrt(d); - Z = N + cbrt(t + d) + cbrt(t - d); - flip = 0; - } - A = sqrt((Z + Z) - Nk); - T = (Fk - Z) * K / A; - inx = 0.0; - solution = FALSE; - b = -A + K; - d = b * b - 4 * (Z + T); - if (d >= 0) - { - d = sqrt(d); - y = (b + d) / 2; - if ((y >= 0.0) && (y < hepp)) - { - solution = TRUE; - if (y > hepm) - y = h; - t = y / h; - x = w * sqrt(1 - (t * t)); - t = K - y; - if (rs - (t * t) >= 0) - t = sqrt(rs - (t * t)); - else - t = 0; - if (flip == 2) - inx = x - t; - else - outx = x + t; - } - } - b = A + K; - d = b * b - 4 * (Z - T); - /* Because of the large magnitudes involved, we lose enough precision - * that sometimes we end up with a negative value near the axis, when - * it should be positive. This is a workaround. - */ - if (d < 0 && !solution) - d = 0.0; - if (d >= 0) { - d = sqrt(d); - y = (b + d) / 2; - if (y < hepp) - { - if (y > hepm) - y = h; - t = y / h; - x = w * sqrt(1 - (t * t)); - t = K - y; - if (rs - (t * t) >= 0) - inx = x - sqrt(rs - (t * t)); - else - inx = x; - } - y = (b - d) / 2; - if (y >= 0.0) - { - if (y > hepm) - y = h; - t = y / h; - x = w * sqrt(1 - (t * t)); - t = K - y; - if (rs - (t * t) >= 0) - t = sqrt(rs - (t * t)); - else - t = 0; - if (flip == 1) - inx = x - t; - else - outx = x + t; - } - } - span->lx = ICEIL(xorg - outx); - if (inx <= 0.0) - { - spdata->count1++; - span->lw = ICEIL(xorg + outx) - span->lx; - span->rx = ICEIL(xorg + inx); - span->rw = -ICEIL(xorg - inx); - } - else - { - spdata->count2++; - span->lw = ICEIL(xorg - inx) - span->lx; - span->rx = ICEIL(xorg + inx); - span->rw = ICEIL(xorg + outx) - span->rx; - } - span++; - } - if (spdata->bot) - { - outx = w + r; - if (r >= h && r <= w) - inx = 0.0; - else if (Nk < 0.0 && -Nk < Hs) - { - inx = w * sqrt(1 + Nk / Hs) - sqrt(rs + Nk); - if (inx > w - r) - inx = w - r; - } - else - inx = w - r; - span->lx = ICEIL(xorg - outx); - if (inx <= 0.0) - { - span->lw = ICEIL(xorg + outx) - span->lx; - span->rx = ICEIL(xorg + inx); - span->rw = -ICEIL(xorg - inx); - } - else - { - span->lw = ICEIL(xorg - inx) - span->lx; - span->rx = ICEIL(xorg + inx); - span->rw = ICEIL(xorg + outx) - span->rx; - } - } - if (spdata->hole) - { - span = &spdata->spans[spdata->count1]; - span->lw = -span->lx; - span->rx = 1; - span->rw = span->lw; - spdata->count1--; - spdata->count2++; + (int) parc->height * lw <= (int) (parc->width * parc->width) + && lw < (int) parc->height); + for (; K > 0.0; K -= 1.0) { + N = (K * K + Nk) / 6.0; + Nc = N * N * N; + Vr = Vk * K; + t = Nc + Vr * Vr; + d = Nc + t; + if (d < 0.0) { + d = Nc; + b = N; + if ((b < 0.0) == (t < 0.0)) { + b = -b; + d = -d; + } + Z = N - 2.0 * b * cos(acos(-t / d) / 3.0); + if ((Z < 0.0) == (Vr < 0.0)) + flip = 2; + else + flip = 1; + } + else { + d = Vr * sqrt(d); + Z = N + cbrt(t + d) + cbrt(t - d); + flip = 0; + } + A = sqrt((Z + Z) - Nk); + T = (Fk - Z) * K / A; + inx = 0.0; + solution = FALSE; + b = -A + K; + d = b * b - 4 * (Z + T); + if (d >= 0) { + d = sqrt(d); + y = (b + d) / 2; + if ((y >= 0.0) && (y < hepp)) { + solution = TRUE; + if (y > hepm) + y = h; + t = y / h; + x = w * sqrt(1 - (t * t)); + t = K - y; + if (rs - (t * t) >= 0) + t = sqrt(rs - (t * t)); + else + t = 0; + if (flip == 2) + inx = x - t; + else + outx = x + t; + } + } + b = A + K; + d = b * b - 4 * (Z - T); + /* Because of the large magnitudes involved, we lose enough precision + * that sometimes we end up with a negative value near the axis, when + * it should be positive. This is a workaround. + */ + if (d < 0 && !solution) + d = 0.0; + if (d >= 0) { + d = sqrt(d); + y = (b + d) / 2; + if (y < hepp) { + if (y > hepm) + y = h; + t = y / h; + x = w * sqrt(1 - (t * t)); + t = K - y; + if (rs - (t * t) >= 0) + inx = x - sqrt(rs - (t * t)); + else + inx = x; + } + y = (b - d) / 2; + if (y >= 0.0) { + if (y > hepm) + y = h; + t = y / h; + x = w * sqrt(1 - (t * t)); + t = K - y; + if (rs - (t * t) >= 0) + t = sqrt(rs - (t * t)); + else + t = 0; + if (flip == 1) + inx = x - t; + else + outx = x + t; + } + } + span->lx = ICEIL(xorg - outx); + if (inx <= 0.0) { + spdata->count1++; + span->lw = ICEIL(xorg + outx) - span->lx; + span->rx = ICEIL(xorg + inx); + span->rw = -ICEIL(xorg - inx); + } + else { + spdata->count2++; + span->lw = ICEIL(xorg - inx) - span->lx; + span->rx = ICEIL(xorg + inx); + span->rw = ICEIL(xorg + outx) - span->rx; + } + span++; + } + if (spdata->bot) { + outx = w + r; + if (r >= h && r <= w) + inx = 0.0; + else if (Nk < 0.0 && -Nk < Hs) { + inx = w * sqrt(1 + Nk / Hs) - sqrt(rs + Nk); + if (inx > w - r) + inx = w - r; + } + else + inx = w - r; + span->lx = ICEIL(xorg - outx); + if (inx <= 0.0) { + span->lw = ICEIL(xorg + outx) - span->lx; + span->rx = ICEIL(xorg + inx); + span->rw = -ICEIL(xorg - inx); + } + else { + span->lw = ICEIL(xorg - inx) - span->lx; + span->rx = ICEIL(xorg + inx); + span->rw = ICEIL(xorg + outx) - span->rx; + } + } + if (spdata->hole) { + span = &spdata->spans[spdata->count1]; + span->lw = -span->lx; + span->rx = 1; + span->rw = span->lw; + spdata->count1--; + spdata->count2++; } } static double -tailX( - double K, - struct arc_def *def, - struct arc_bound *bounds, - struct accelerators *acc) +tailX(double K, + struct arc_def *def, struct arc_bound *bounds, struct accelerators *acc) { double w, h, r; double Hs, Hf, WH, Vk, Nk, Fk, Vr, N, Nc, Z, rs; @@ -669,18 +636,18 @@ tailX( Hf = acc->h4; Nk = (Hf - Nk * Nk) / WH; if (K == 0.0) { - if (Nk < 0.0 && -Nk < Hs) { - xs[0] = w * sqrt(1 + Nk / Hs) - sqrt(rs + Nk); - xs[1] = w - r; - if (acc->left.valid && boundedLe(K, bounds->left) && - !boundedLe(K, bounds->outer) && xs[0] >= 0.0 && xs[1] >= 0.0) - return xs[1]; - if (acc->right.valid && boundedLe(K, bounds->right) && - !boundedLe(K, bounds->inner) && xs[0] <= 0.0 && xs[1] <= 0.0) - return xs[1]; - return xs[0]; - } - return w - r; + if (Nk < 0.0 && -Nk < Hs) { + xs[0] = w * sqrt(1 + Nk / Hs) - sqrt(rs + Nk); + xs[1] = w - r; + if (acc->left.valid && boundedLe(K, bounds->left) && + !boundedLe(K, bounds->outer) && xs[0] >= 0.0 && xs[1] >= 0.0) + return xs[1]; + if (acc->right.valid && boundedLe(K, bounds->right) && + !boundedLe(K, bounds->inner) && xs[0] <= 0.0 && xs[1] <= 0.0) + return xs[1]; + return xs[0]; + } + return w - r; } Fk = Hf / WH; hepp = h + EPSILON; @@ -693,48 +660,44 @@ tailX( t = Nc + Vr * Vr; d = Nc + t; if (d < 0.0) { - d = Nc; - b = N; - if ( (b < 0.0) == (t < 0.0) ) - { - b = -b; - d = -d; - } - Z = N - 2.0 * b * cos(acos(-t / d) / 3.0); - if ( (Z < 0.0) == (Vr < 0.0) ) - flip = 2; - else - flip = 1; + d = Nc; + b = N; + if ((b < 0.0) == (t < 0.0)) { + b = -b; + d = -d; + } + Z = N - 2.0 * b * cos(acos(-t / d) / 3.0); + if ((Z < 0.0) == (Vr < 0.0)) + flip = 2; + else + flip = 1; } - else - { - d = Vr * sqrt(d); - Z = N + cbrt(t + d) + cbrt(t - d); - flip = 0; + else { + d = Vr * sqrt(d); + Z = N + cbrt(t + d) + cbrt(t - d); + flip = 0; } A = sqrt((Z + Z) - Nk); T = (Fk - Z) * K / A; solution = FALSE; b = -A + K; d = b * b - 4 * (Z + T); - if (d >= 0 && flip == 2) - { - d = sqrt(d); - y = (b + d) / 2; - if ((y >= 0.0) && (y < hepp)) - { - solution = TRUE; - if (y > hepm) - y = h; - t = y / h; - x = w * sqrt(1 - (t * t)); - t = K - y; - if (rs - (t * t) >= 0) - t = sqrt(rs - (t * t)); - else - t = 0; - *xp++ = x - t; - } + if (d >= 0 && flip == 2) { + d = sqrt(d); + y = (b + d) / 2; + if ((y >= 0.0) && (y < hepp)) { + solution = TRUE; + if (y > hepm) + y = h; + t = y / h; + x = w * sqrt(1 - (t * t)); + t = K - y; + if (rs - (t * t) >= 0) + t = sqrt(rs - (t * t)); + else + t = 0; + *xp++ = x - t; + } } b = A + K; d = b * b - 4 * (Z - T); @@ -743,76 +706,71 @@ tailX( * it should be positive. This is a workaround. */ if (d < 0 && !solution) - d = 0.0; + d = 0.0; if (d >= 0) { - d = sqrt(d); - y = (b + d) / 2; - if (y < hepp) - { - if (y > hepm) - y = h; - t = y / h; - x = w * sqrt(1 - (t * t)); - t = K - y; - if (rs - (t * t) >= 0) - *xp++ = x - sqrt(rs - (t * t)); - else - *xp++ = x; - } - y = (b - d) / 2; - if (y >= 0.0 && flip == 1) - { - if (y > hepm) - y = h; - t = y / h; - x = w * sqrt(1 - (t * t)); - t = K - y; - if (rs - (t * t) >= 0) - t = sqrt(rs - (t * t)); - else - t = 0; - *xp++ = x - t; - } + d = sqrt(d); + y = (b + d) / 2; + if (y < hepp) { + if (y > hepm) + y = h; + t = y / h; + x = w * sqrt(1 - (t * t)); + t = K - y; + if (rs - (t * t) >= 0) + *xp++ = x - sqrt(rs - (t * t)); + else + *xp++ = x; + } + y = (b - d) / 2; + if (y >= 0.0 && flip == 1) { + if (y > hepm) + y = h; + t = y / h; + x = w * sqrt(1 - (t * t)); + t = K - y; + if (rs - (t * t) >= 0) + t = sqrt(rs - (t * t)); + else + t = 0; + *xp++ = x - t; + } } if (xp > &xs[1]) { - if (acc->left.valid && boundedLe(K, bounds->left) && - !boundedLe(K, bounds->outer) && xs[0] >= 0.0 && xs[1] >= 0.0) - return xs[1]; - if (acc->right.valid && boundedLe(K, bounds->right) && - !boundedLe(K, bounds->inner) && xs[0] <= 0.0 && xs[1] <= 0.0) - return xs[1]; + if (acc->left.valid && boundedLe(K, bounds->left) && + !boundedLe(K, bounds->outer) && xs[0] >= 0.0 && xs[1] >= 0.0) + return xs[1]; + if (acc->right.valid && boundedLe(K, bounds->right) && + !boundedLe(K, bounds->inner) && xs[0] <= 0.0 && xs[1] <= 0.0) + return xs[1]; } return xs[0]; } static miArcSpanData * -miComputeWideEllipse(int lw, xArc *parc) +miComputeWideEllipse(int lw, xArc * parc) { miArcSpanData *spdata = NULL; int k; if (!lw) - lw = 1; + lw = 1; k = (parc->height >> 1) + ((lw - 1) >> 1); spdata = malloc(sizeof(miArcSpanData) + sizeof(miArcSpan) * (k + 2)); if (!spdata) - return NULL; - spdata->spans = (miArcSpan *)(spdata + 1); + return NULL; + spdata->spans = (miArcSpan *) (spdata + 1); spdata->k = k; spdata->top = !(lw & 1) && !(parc->width & 1); spdata->bot = !(parc->height & 1); if (parc->width == parc->height) - miComputeCircleSpans(lw, parc, spdata); + miComputeCircleSpans(lw, parc, spdata); else - miComputeEllipseSpans(lw, parc, spdata); + miComputeEllipseSpans(lw, parc, spdata); return spdata; } static void -miFillWideEllipse( - DrawablePtr pDraw, - GCPtr pGC, - xArc *parc) +miFillWideEllipse(DrawablePtr pDraw, GCPtr pGC, xArc * parc) { DDXPointPtr points; DDXPointPtr pts; @@ -827,13 +785,12 @@ miFillWideEllipse( n = (sizeof(int) * 2) * yorgu; widths = malloc(n + (sizeof(DDXPointRec) * 2) * yorgu); if (!widths) - return; - points = (DDXPointPtr)((char *)widths + n); - spdata = miComputeWideEllipse((int)pGC->lineWidth, parc); - if (!spdata) - { - free(widths); - return; + return; + points = (DDXPointPtr) ((char *) widths + n); + spdata = miComputeWideEllipse((int) pGC->lineWidth, parc); + if (!spdata) { + free(widths); + return; } pts = points; wids = widths; @@ -841,88 +798,80 @@ miFillWideEllipse( xorg = parc->x + (parc->width >> 1); yorgu = parc->y + (parc->height >> 1); yorgl = yorgu + (parc->height & 1); - if (pGC->miTranslate) - { - xorg += pDraw->x; - yorgu += pDraw->y; - yorgl += pDraw->y; + if (pGC->miTranslate) { + xorg += pDraw->x; + yorgu += pDraw->y; + yorgl += pDraw->y; } yorgu -= spdata->k; yorgl += spdata->k; - if (spdata->top) - { - pts->x = xorg; - pts->y = yorgu - 1; - pts++; - *wids++ = 1; - span++; - } - for (n = spdata->count1; --n >= 0; ) - { - pts[0].x = xorg + span->lx; - pts[0].y = yorgu; - wids[0] = span->lw; - pts[1].x = pts[0].x; - pts[1].y = yorgl; - wids[1] = wids[0]; - yorgu++; - yorgl--; - pts += 2; - wids += 2; - span++; - } - if (spdata->hole) - { - pts[0].x = xorg; - pts[0].y = yorgl; - wids[0] = 1; - pts++; - wids++; - } - for (n = spdata->count2; --n >= 0; ) - { - pts[0].x = xorg + span->lx; - pts[0].y = yorgu; - wids[0] = span->lw; - pts[1].x = xorg + span->rx; - pts[1].y = pts[0].y; - wids[1] = span->rw; - pts[2].x = pts[0].x; - pts[2].y = yorgl; - wids[2] = wids[0]; - pts[3].x = pts[1].x; - pts[3].y = pts[2].y; - wids[3] = wids[1]; - yorgu++; - yorgl--; - pts += 4; - wids += 4; - span++; - } - if (spdata->bot) - { - if (span->rw <= 0) - { - pts[0].x = xorg + span->lx; - pts[0].y = yorgu; - wids[0] = span->lw; - pts++; - wids++; - } - else - { - pts[0].x = xorg + span->lx; - pts[0].y = yorgu; - wids[0] = span->lw; - pts[1].x = xorg + span->rx; - pts[1].y = pts[0].y; - wids[1] = span->rw; - pts += 2; - wids += 2; - } + if (spdata->top) { + pts->x = xorg; + pts->y = yorgu - 1; + pts++; + *wids++ = 1; + span++; + } + for (n = spdata->count1; --n >= 0;) { + pts[0].x = xorg + span->lx; + pts[0].y = yorgu; + wids[0] = span->lw; + pts[1].x = pts[0].x; + pts[1].y = yorgl; + wids[1] = wids[0]; + yorgu++; + yorgl--; + pts += 2; + wids += 2; + span++; + } + if (spdata->hole) { + pts[0].x = xorg; + pts[0].y = yorgl; + wids[0] = 1; + pts++; + wids++; + } + for (n = spdata->count2; --n >= 0;) { + pts[0].x = xorg + span->lx; + pts[0].y = yorgu; + wids[0] = span->lw; + pts[1].x = xorg + span->rx; + pts[1].y = pts[0].y; + wids[1] = span->rw; + pts[2].x = pts[0].x; + pts[2].y = yorgl; + wids[2] = wids[0]; + pts[3].x = pts[1].x; + pts[3].y = pts[2].y; + wids[3] = wids[1]; + yorgu++; + yorgl--; + pts += 4; + wids += 4; + span++; + } + if (spdata->bot) { + if (span->rw <= 0) { + pts[0].x = xorg + span->lx; + pts[0].y = yorgu; + wids[0] = span->lw; + pts++; + wids++; + } + else { + pts[0].x = xorg + span->lx; + pts[0].y = yorgu; + wids[0] = span->lw; + pts[1].x = xorg + span->rx; + pts[1].y = pts[0].y; + wids[1] = span->rw; + pts += 2; + wids += 2; + } } free(spdata); - (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE); + (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE); free(widths); } @@ -941,430 +890,406 @@ miFillWideEllipse( */ void -miPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs) +miPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs) { - int i; - xArc *parc; - int xMin, xMax, yMin, yMax; - int pixmapWidth = 0, pixmapHeight = 0; - int xOrg = 0, yOrg = 0; - int width; - Bool fTricky; - DrawablePtr pDrawTo; - CARD32 fg, bg; - GCPtr pGCTo; + int i; + xArc *parc; + int xMin, xMax, yMin, yMax; + int pixmapWidth = 0, pixmapHeight = 0; + int xOrg = 0, yOrg = 0; + int width; + Bool fTricky; + DrawablePtr pDrawTo; + CARD32 fg, bg; + GCPtr pGCTo; miPolyArcPtr polyArcs; - int cap[2], join[2]; - int iphase; - int halfWidth; + int cap[2], join[2]; + int iphase; + int halfWidth; width = pGC->lineWidth; - if(width == 0 && pGC->lineStyle == LineSolid) - { - for(i = narcs, parc = parcs; --i >= 0; parc++) - miArcSegment( pDraw, pGC, *parc, - (miArcFacePtr) 0, (miArcFacePtr) 0 ); - fillSpans (pDraw, pGC); - } - else - { - if ((pGC->lineStyle == LineSolid) && narcs) - { - while (parcs->width && parcs->height && - (parcs->angle2 >= FULLCIRCLE || - parcs->angle2 <= -FULLCIRCLE)) - { - miFillWideEllipse(pDraw, pGC, parcs); - if (!--narcs) - return; - parcs++; - } - } - - /* Set up pDrawTo and pGCTo based on the rasterop */ - switch(pGC->alu) - { - case GXclear: /* 0 */ - case GXcopy: /* src */ - case GXcopyInverted: /* NOT src */ - case GXset: /* 1 */ - fTricky = FALSE; - pDrawTo = pDraw; - pGCTo = pGC; - break; - default: - fTricky = TRUE; - - /* find bounding box around arcs */ - xMin = yMin = MAXSHORT; - xMax = yMax = MINSHORT; - - for(i = narcs, parc = parcs; --i >= 0; parc++) - { - xMin = min (xMin, parc->x); - yMin = min (yMin, parc->y); - xMax = max (xMax, (parc->x + (int) parc->width)); - yMax = max (yMax, (parc->y + (int) parc->height)); - } - - /* expand box to deal with line widths */ - halfWidth = (width + 1)/2; - xMin -= halfWidth; - yMin -= halfWidth; - xMax += halfWidth; - yMax += halfWidth; - - /* compute pixmap size; limit it to size of drawable */ - xOrg = max(xMin, 0); - yOrg = max(yMin, 0); - pixmapWidth = min(xMax, pDraw->width) - xOrg; - pixmapHeight = min(yMax, pDraw->height) - yOrg; - - /* if nothing left, return */ - if ( (pixmapWidth <= 0) || (pixmapHeight <= 0) ) return; - - for(i = narcs, parc = parcs; --i >= 0; parc++) - { - parc->x -= xOrg; - parc->y -= yOrg; - } - if (pGC->miTranslate) - { - xOrg += pDraw->x; - yOrg += pDraw->y; - } - - /* set up scratch GC */ - - pGCTo = GetScratchGC(1, pDraw->pScreen); - if (!pGCTo) - return; - { - ChangeGCVal gcvals[6]; - gcvals[0].val = GXcopy; - gcvals[1].val = 1; - gcvals[2].val = 0; - gcvals[3].val = pGC->lineWidth; - gcvals[4].val = pGC->capStyle; - gcvals[5].val = pGC->joinStyle; - ChangeGC(NullClient, pGCTo, GCFunction | - GCForeground | GCBackground | GCLineWidth | - GCCapStyle | GCJoinStyle, gcvals); - } - - /* allocate a 1 bit deep pixmap of the appropriate size, and - * validate it */ - pDrawTo = (DrawablePtr)(*pDraw->pScreen->CreatePixmap) - (pDraw->pScreen, pixmapWidth, pixmapHeight, 1, - CREATE_PIXMAP_USAGE_SCRATCH); - if (!pDrawTo) - { - FreeScratchGC(pGCTo); - return; - } - ValidateGC(pDrawTo, pGCTo); - miClearDrawable(pDrawTo, pGCTo); - } - - fg = pGC->fgPixel; - bg = pGC->bgPixel; - if ((pGC->fillStyle == FillTiled) || - (pGC->fillStyle == FillOpaqueStippled)) - bg = fg; /* the protocol sez these don't cause color changes */ - - polyArcs = miComputeArcs (parcs, narcs, pGC); - - if (!polyArcs) - { - if (fTricky) { - (*pDraw->pScreen->DestroyPixmap) ((PixmapPtr)pDrawTo); - FreeScratchGC (pGCTo); - } - return; - } - - cap[0] = cap[1] = 0; - join[0] = join[1] = 0; - for (iphase = ((pGC->lineStyle == LineDoubleDash) ? 1 : 0); - iphase >= 0; - iphase--) - { - ChangeGCVal gcval; - if (iphase == 1) { - gcval.val = bg; - ChangeGC (NullClient, pGC, GCForeground, &gcval); - ValidateGC (pDraw, pGC); - } else if (pGC->lineStyle == LineDoubleDash) { - gcval.val = fg; - ChangeGC (NullClient, pGC, GCForeground, &gcval); - ValidateGC (pDraw, pGC); - } - for (i = 0; i < polyArcs[iphase].narcs; i++) { - miArcDataPtr arcData; - - arcData = &polyArcs[iphase].arcs[i]; - miArcSegment(pDrawTo, pGCTo, arcData->arc, - &arcData->bounds[RIGHT_END], - &arcData->bounds[LEFT_END]); - if (polyArcs[iphase].arcs[i].render) { - fillSpans (pDrawTo, pGCTo); - /* - * don't cap self-joining arcs - */ - if (polyArcs[iphase].arcs[i].selfJoin && - cap[iphase] < polyArcs[iphase].arcs[i].cap) - cap[iphase]++; - while (cap[iphase] < polyArcs[iphase].arcs[i].cap) { - int arcIndex, end; - miArcDataPtr arcData0; - - arcIndex = polyArcs[iphase].caps[cap[iphase]].arcIndex; - end = polyArcs[iphase].caps[cap[iphase]].end; - arcData0 = &polyArcs[iphase].arcs[arcIndex]; - miArcCap (pDrawTo, pGCTo, - &arcData0->bounds[end], end, - arcData0->arc.x, arcData0->arc.y, - (double) arcData0->arc.width / 2.0, - (double) arcData0->arc.height / 2.0); - ++cap[iphase]; - } - while (join[iphase] < polyArcs[iphase].arcs[i].join) { - int arcIndex0, arcIndex1, end0, end1; - int phase0, phase1; - miArcDataPtr arcData0, arcData1; - miArcJoinPtr joinp; - - joinp = &polyArcs[iphase].joins[join[iphase]]; - arcIndex0 = joinp->arcIndex0; - end0 = joinp->end0; - arcIndex1 = joinp->arcIndex1; - end1 = joinp->end1; - phase0 = joinp->phase0; - phase1 = joinp->phase1; - arcData0 = &polyArcs[phase0].arcs[arcIndex0]; - arcData1 = &polyArcs[phase1].arcs[arcIndex1]; - miArcJoin (pDrawTo, pGCTo, - &arcData0->bounds[end0], - &arcData1->bounds[end1], - arcData0->arc.x, arcData0->arc.y, - (double) arcData0->arc.width / 2.0, - (double) arcData0->arc.height / 2.0, - arcData1->arc.x, arcData1->arc.y, - (double) arcData1->arc.width / 2.0, - (double) arcData1->arc.height / 2.0); - ++join[iphase]; - } - if (fTricky) { - if (pGC->serialNumber != pDraw->serialNumber) - ValidateGC (pDraw, pGC); - (*pGC->ops->PushPixels) (pGC, (PixmapPtr)pDrawTo, - pDraw, pixmapWidth, pixmapHeight, xOrg, yOrg); - miClearDrawable ((DrawablePtr) pDrawTo, pGCTo); - } - } - } - } - miFreeArcs(polyArcs, pGC); - - if(fTricky) - { - (*pGCTo->pScreen->DestroyPixmap)((PixmapPtr)pDrawTo); - FreeScratchGC(pGCTo); - } + if (width == 0 && pGC->lineStyle == LineSolid) { + for (i = narcs, parc = parcs; --i >= 0; parc++) + miArcSegment(pDraw, pGC, *parc, (miArcFacePtr) 0, (miArcFacePtr) 0); + fillSpans(pDraw, pGC); + } + else { + if ((pGC->lineStyle == LineSolid) && narcs) { + while (parcs->width && parcs->height && + (parcs->angle2 >= FULLCIRCLE || + parcs->angle2 <= -FULLCIRCLE)) { + miFillWideEllipse(pDraw, pGC, parcs); + if (!--narcs) + return; + parcs++; + } + } + + /* Set up pDrawTo and pGCTo based on the rasterop */ + switch (pGC->alu) { + case GXclear: /* 0 */ + case GXcopy: /* src */ + case GXcopyInverted: /* NOT src */ + case GXset: /* 1 */ + fTricky = FALSE; + pDrawTo = pDraw; + pGCTo = pGC; + break; + default: + fTricky = TRUE; + + /* find bounding box around arcs */ + xMin = yMin = MAXSHORT; + xMax = yMax = MINSHORT; + + for (i = narcs, parc = parcs; --i >= 0; parc++) { + xMin = min(xMin, parc->x); + yMin = min(yMin, parc->y); + xMax = max(xMax, (parc->x + (int) parc->width)); + yMax = max(yMax, (parc->y + (int) parc->height)); + } + + /* expand box to deal with line widths */ + halfWidth = (width + 1) / 2; + xMin -= halfWidth; + yMin -= halfWidth; + xMax += halfWidth; + yMax += halfWidth; + + /* compute pixmap size; limit it to size of drawable */ + xOrg = max(xMin, 0); + yOrg = max(yMin, 0); + pixmapWidth = min(xMax, pDraw->width) - xOrg; + pixmapHeight = min(yMax, pDraw->height) - yOrg; + + /* if nothing left, return */ + if ((pixmapWidth <= 0) || (pixmapHeight <= 0)) + return; + + for (i = narcs, parc = parcs; --i >= 0; parc++) { + parc->x -= xOrg; + parc->y -= yOrg; + } + if (pGC->miTranslate) { + xOrg += pDraw->x; + yOrg += pDraw->y; + } + + /* set up scratch GC */ + + pGCTo = GetScratchGC(1, pDraw->pScreen); + if (!pGCTo) + return; + { + ChangeGCVal gcvals[6]; + + gcvals[0].val = GXcopy; + gcvals[1].val = 1; + gcvals[2].val = 0; + gcvals[3].val = pGC->lineWidth; + gcvals[4].val = pGC->capStyle; + gcvals[5].val = pGC->joinStyle; + ChangeGC(NullClient, pGCTo, GCFunction | + GCForeground | GCBackground | GCLineWidth | + GCCapStyle | GCJoinStyle, gcvals); + } + + /* allocate a 1 bit deep pixmap of the appropriate size, and + * validate it */ + pDrawTo = (DrawablePtr) (*pDraw->pScreen->CreatePixmap) + (pDraw->pScreen, pixmapWidth, pixmapHeight, 1, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!pDrawTo) { + FreeScratchGC(pGCTo); + return; + } + ValidateGC(pDrawTo, pGCTo); + miClearDrawable(pDrawTo, pGCTo); + } + + fg = pGC->fgPixel; + bg = pGC->bgPixel; + if ((pGC->fillStyle == FillTiled) || + (pGC->fillStyle == FillOpaqueStippled)) + bg = fg; /* the protocol sez these don't cause color changes */ + + polyArcs = miComputeArcs(parcs, narcs, pGC); + + if (!polyArcs) { + if (fTricky) { + (*pDraw->pScreen->DestroyPixmap) ((PixmapPtr) pDrawTo); + FreeScratchGC(pGCTo); + } + return; + } + + cap[0] = cap[1] = 0; + join[0] = join[1] = 0; + for (iphase = ((pGC->lineStyle == LineDoubleDash) ? 1 : 0); + iphase >= 0; iphase--) { + ChangeGCVal gcval; + + if (iphase == 1) { + gcval.val = bg; + ChangeGC(NullClient, pGC, GCForeground, &gcval); + ValidateGC(pDraw, pGC); + } + else if (pGC->lineStyle == LineDoubleDash) { + gcval.val = fg; + ChangeGC(NullClient, pGC, GCForeground, &gcval); + ValidateGC(pDraw, pGC); + } + for (i = 0; i < polyArcs[iphase].narcs; i++) { + miArcDataPtr arcData; + + arcData = &polyArcs[iphase].arcs[i]; + miArcSegment(pDrawTo, pGCTo, arcData->arc, + &arcData->bounds[RIGHT_END], + &arcData->bounds[LEFT_END]); + if (polyArcs[iphase].arcs[i].render) { + fillSpans(pDrawTo, pGCTo); + /* + * don't cap self-joining arcs + */ + if (polyArcs[iphase].arcs[i].selfJoin && + cap[iphase] < polyArcs[iphase].arcs[i].cap) + cap[iphase]++; + while (cap[iphase] < polyArcs[iphase].arcs[i].cap) { + int arcIndex, end; + miArcDataPtr arcData0; + + arcIndex = polyArcs[iphase].caps[cap[iphase]].arcIndex; + end = polyArcs[iphase].caps[cap[iphase]].end; + arcData0 = &polyArcs[iphase].arcs[arcIndex]; + miArcCap(pDrawTo, pGCTo, + &arcData0->bounds[end], end, + arcData0->arc.x, arcData0->arc.y, + (double) arcData0->arc.width / 2.0, + (double) arcData0->arc.height / 2.0); + ++cap[iphase]; + } + while (join[iphase] < polyArcs[iphase].arcs[i].join) { + int arcIndex0, arcIndex1, end0, end1; + int phase0, phase1; + miArcDataPtr arcData0, arcData1; + miArcJoinPtr joinp; + + joinp = &polyArcs[iphase].joins[join[iphase]]; + arcIndex0 = joinp->arcIndex0; + end0 = joinp->end0; + arcIndex1 = joinp->arcIndex1; + end1 = joinp->end1; + phase0 = joinp->phase0; + phase1 = joinp->phase1; + arcData0 = &polyArcs[phase0].arcs[arcIndex0]; + arcData1 = &polyArcs[phase1].arcs[arcIndex1]; + miArcJoin(pDrawTo, pGCTo, + &arcData0->bounds[end0], + &arcData1->bounds[end1], + arcData0->arc.x, arcData0->arc.y, + (double) arcData0->arc.width / 2.0, + (double) arcData0->arc.height / 2.0, + arcData1->arc.x, arcData1->arc.y, + (double) arcData1->arc.width / 2.0, + (double) arcData1->arc.height / 2.0); + ++join[iphase]; + } + if (fTricky) { + if (pGC->serialNumber != pDraw->serialNumber) + ValidateGC(pDraw, pGC); + (*pGC->ops->PushPixels) (pGC, (PixmapPtr) pDrawTo, + pDraw, pixmapWidth, + pixmapHeight, xOrg, yOrg); + miClearDrawable((DrawablePtr) pDrawTo, pGCTo); + } + } + } + } + miFreeArcs(polyArcs, pGC); + + if (fTricky) { + (*pGCTo->pScreen->DestroyPixmap) ((PixmapPtr) pDrawTo); + FreeScratchGC(pGCTo); + } } } static double -angleBetween (SppPointRec center, SppPointRec point1, SppPointRec point2) +angleBetween(SppPointRec center, SppPointRec point1, SppPointRec point2) { - double a1, a2, a; - - /* - * reflect from X coordinates back to ellipse - * coordinates -- y increasing upwards - */ - a1 = miDatan2 (- (point1.y - center.y), point1.x - center.x); - a2 = miDatan2 (- (point2.y - center.y), point2.x - center.x); - a = a2 - a1; - if (a <= -180.0) - a += 360.0; - else if (a > 180.0) - a -= 360.0; - return a; + double a1, a2, a; + + /* + * reflect from X coordinates back to ellipse + * coordinates -- y increasing upwards + */ + a1 = miDatan2(-(point1.y - center.y), point1.x - center.x); + a2 = miDatan2(-(point2.y - center.y), point2.x - center.x); + a = a2 - a1; + if (a <= -180.0) + a += 360.0; + else if (a > 180.0) + a -= 360.0; + return a; } static void -translateBounds ( - miArcFacePtr b, - int x, - int y, - double fx, - double fy) +translateBounds(miArcFacePtr b, int x, int y, double fx, double fy) { - fx += x; - fy += y; - b->clock.x -= fx; - b->clock.y -= fy; - b->center.x -= fx; - b->center.y -= fy; - b->counterClock.x -= fx; - b->counterClock.y -= fy; + fx += x; + fy += y; + b->clock.x -= fx; + b->clock.y -= fy; + b->center.x -= fx; + b->center.y -= fy; + b->counterClock.x -= fx; + b->counterClock.y -= fy; } static void miArcJoin(DrawablePtr pDraw, GCPtr pGC, miArcFacePtr pLeft, - miArcFacePtr pRight, int xOrgLeft, int yOrgLeft, - double xFtransLeft, double yFtransLeft, - int xOrgRight, int yOrgRight, - double xFtransRight, double yFtransRight) + miArcFacePtr pRight, int xOrgLeft, int yOrgLeft, + double xFtransLeft, double yFtransLeft, + int xOrgRight, int yOrgRight, + double xFtransRight, double yFtransRight) { - SppPointRec center, corner, otherCorner; - SppPointRec poly[5], e; - SppPointPtr pArcPts; - int cpt; - SppArcRec arc; - miArcFaceRec Right, Left; - int polyLen = 0; - int xOrg, yOrg; - double xFtrans, yFtrans; - double a; - double ae, ac2, ec2, bc2, de; - double width; - - xOrg = (xOrgRight + xOrgLeft) / 2; - yOrg = (yOrgRight + yOrgLeft) / 2; - xFtrans = (xFtransLeft + xFtransRight) / 2; - yFtrans = (yFtransLeft + yFtransRight) / 2; - Right = *pRight; - translateBounds (&Right, xOrg - xOrgRight, yOrg - yOrgRight, - xFtrans - xFtransRight, yFtrans - yFtransRight); - Left = *pLeft; - translateBounds (&Left, xOrg - xOrgLeft, yOrg - yOrgLeft, - xFtrans - xFtransLeft, yFtrans - yFtransLeft); - pRight = &Right; - pLeft = &Left; - - if (pRight->clock.x == pLeft->counterClock.x && - pRight->clock.y == pLeft->counterClock.y) - return; - center = pRight->center; - if (0 <= (a = angleBetween (center, pRight->clock, pLeft->counterClock)) - && a <= 180.0) - { - corner = pRight->clock; - otherCorner = pLeft->counterClock; - } else { - a = angleBetween (center, pLeft->clock, pRight->counterClock); - corner = pLeft->clock; - otherCorner = pRight->counterClock; - } - switch (pGC->joinStyle) { - case JoinRound: - width = (pGC->lineWidth ? (double)pGC->lineWidth : (double)1); - - arc.x = center.x - width/2; - arc.y = center.y - width/2; - arc.width = width; - arc.height = width; - arc.angle1 = -miDatan2 (corner.y - center.y, corner.x - center.x); - arc.angle2 = a; - pArcPts = malloc(3 * sizeof (SppPointRec)); - if (!pArcPts) - return; - pArcPts[0].x = otherCorner.x; - pArcPts[0].y = otherCorner.y; - pArcPts[1].x = center.x; - pArcPts[1].y = center.y; - pArcPts[2].x = corner.x; - pArcPts[2].y = corner.y; - if( (cpt = miGetArcPts(&arc, 3, &pArcPts)) ) - { - /* by drawing with miFillSppPoly and setting the endpoints of the arc - * to be the corners, we assure that the cap will meet up with the - * rest of the line */ - miFillSppPoly(pDraw, pGC, cpt, pArcPts, xOrg, yOrg, xFtrans, yFtrans); - } - free(pArcPts); - return; - case JoinMiter: - /* - * don't miter arcs with less than 11 degrees between them - */ - if (a < 169.0) { - poly[0] = corner; - poly[1] = center; - poly[2] = otherCorner; - bc2 = (corner.x - otherCorner.x) * (corner.x - otherCorner.x) + - (corner.y - otherCorner.y) * (corner.y - otherCorner.y); - ec2 = bc2 / 4; - ac2 = (corner.x - center.x) * (corner.x - center.x) + - (corner.y - center.y) * (corner.y - center.y); - ae = sqrt (ac2 - ec2); - de = ec2 / ae; - e.x = (corner.x + otherCorner.x) / 2; - e.y = (corner.y + otherCorner.y) / 2; - poly[3].x = e.x + de * (e.x - center.x) / ae; - poly[3].y = e.y + de * (e.y - center.y) / ae; - poly[4] = corner; - polyLen = 5; - break; - } - case JoinBevel: - poly[0] = corner; - poly[1] = center; - poly[2] = otherCorner; - poly[3] = corner; - polyLen = 4; - break; - } - miFillSppPoly (pDraw, pGC, polyLen, poly, xOrg, yOrg, xFtrans, yFtrans); + SppPointRec center, corner, otherCorner; + SppPointRec poly[5], e; + SppPointPtr pArcPts; + int cpt; + SppArcRec arc; + miArcFaceRec Right, Left; + int polyLen = 0; + int xOrg, yOrg; + double xFtrans, yFtrans; + double a; + double ae, ac2, ec2, bc2, de; + double width; + + xOrg = (xOrgRight + xOrgLeft) / 2; + yOrg = (yOrgRight + yOrgLeft) / 2; + xFtrans = (xFtransLeft + xFtransRight) / 2; + yFtrans = (yFtransLeft + yFtransRight) / 2; + Right = *pRight; + translateBounds(&Right, xOrg - xOrgRight, yOrg - yOrgRight, + xFtrans - xFtransRight, yFtrans - yFtransRight); + Left = *pLeft; + translateBounds(&Left, xOrg - xOrgLeft, yOrg - yOrgLeft, + xFtrans - xFtransLeft, yFtrans - yFtransLeft); + pRight = &Right; + pLeft = &Left; + + if (pRight->clock.x == pLeft->counterClock.x && + pRight->clock.y == pLeft->counterClock.y) + return; + center = pRight->center; + if (0 <= (a = angleBetween(center, pRight->clock, pLeft->counterClock)) + && a <= 180.0) { + corner = pRight->clock; + otherCorner = pLeft->counterClock; + } + else { + a = angleBetween(center, pLeft->clock, pRight->counterClock); + corner = pLeft->clock; + otherCorner = pRight->counterClock; + } + switch (pGC->joinStyle) { + case JoinRound: + width = (pGC->lineWidth ? (double) pGC->lineWidth : (double) 1); + + arc.x = center.x - width / 2; + arc.y = center.y - width / 2; + arc.width = width; + arc.height = width; + arc.angle1 = -miDatan2(corner.y - center.y, corner.x - center.x); + arc.angle2 = a; + pArcPts = malloc(3 * sizeof(SppPointRec)); + if (!pArcPts) + return; + pArcPts[0].x = otherCorner.x; + pArcPts[0].y = otherCorner.y; + pArcPts[1].x = center.x; + pArcPts[1].y = center.y; + pArcPts[2].x = corner.x; + pArcPts[2].y = corner.y; + if ((cpt = miGetArcPts(&arc, 3, &pArcPts))) { + /* by drawing with miFillSppPoly and setting the endpoints of the arc + * to be the corners, we assure that the cap will meet up with the + * rest of the line */ + miFillSppPoly(pDraw, pGC, cpt, pArcPts, xOrg, yOrg, xFtrans, + yFtrans); + } + free(pArcPts); + return; + case JoinMiter: + /* + * don't miter arcs with less than 11 degrees between them + */ + if (a < 169.0) { + poly[0] = corner; + poly[1] = center; + poly[2] = otherCorner; + bc2 = (corner.x - otherCorner.x) * (corner.x - otherCorner.x) + + (corner.y - otherCorner.y) * (corner.y - otherCorner.y); + ec2 = bc2 / 4; + ac2 = (corner.x - center.x) * (corner.x - center.x) + + (corner.y - center.y) * (corner.y - center.y); + ae = sqrt(ac2 - ec2); + de = ec2 / ae; + e.x = (corner.x + otherCorner.x) / 2; + e.y = (corner.y + otherCorner.y) / 2; + poly[3].x = e.x + de * (e.x - center.x) / ae; + poly[3].y = e.y + de * (e.y - center.y) / ae; + poly[4] = corner; + polyLen = 5; + break; + } + case JoinBevel: + poly[0] = corner; + poly[1] = center; + poly[2] = otherCorner; + poly[3] = corner; + polyLen = 4; + break; + } + miFillSppPoly(pDraw, pGC, polyLen, poly, xOrg, yOrg, xFtrans, yFtrans); } -/*ARGSUSED*/ -static void -miArcCap ( - DrawablePtr pDraw, - GCPtr pGC, - miArcFacePtr pFace, - int end, - int xOrg, - int yOrg, - double xFtrans, - double yFtrans) + /*ARGSUSED*/ static void +miArcCap(DrawablePtr pDraw, + GCPtr pGC, + miArcFacePtr pFace, + int end, int xOrg, int yOrg, double xFtrans, double yFtrans) { - SppPointRec corner, otherCorner, center, endPoint, poly[5]; - - corner = pFace->clock; - otherCorner = pFace->counterClock; - center = pFace->center; - switch (pGC->capStyle) { - case CapProjecting: - poly[0].x = otherCorner.x; - poly[0].y = otherCorner.y; - poly[1].x = corner.x; - poly[1].y = corner.y; - poly[2].x = corner.x - - (center.y - corner.y); - poly[2].y = corner.y + - (center.x - corner.x); - poly[3].x = otherCorner.x - - (otherCorner.y - center.y); - poly[3].y = otherCorner.y + - (otherCorner.x - center.x); - poly[4].x = otherCorner.x; - poly[4].y = otherCorner.y; - miFillSppPoly (pDraw, pGC, 5, poly, xOrg, yOrg, xFtrans, yFtrans); - break; - case CapRound: - /* - * miRoundCap just needs these to be unequal. - */ - endPoint = center; - endPoint.x = endPoint.x + 100; - miRoundCap (pDraw, pGC, center, endPoint, corner, otherCorner, 0, - -xOrg, -yOrg, xFtrans, yFtrans); - break; - } + SppPointRec corner, otherCorner, center, endPoint, poly[5]; + + corner = pFace->clock; + otherCorner = pFace->counterClock; + center = pFace->center; + switch (pGC->capStyle) { + case CapProjecting: + poly[0].x = otherCorner.x; + poly[0].y = otherCorner.y; + poly[1].x = corner.x; + poly[1].y = corner.y; + poly[2].x = corner.x - (center.y - corner.y); + poly[2].y = corner.y + (center.x - corner.x); + poly[3].x = otherCorner.x - (otherCorner.y - center.y); + poly[3].y = otherCorner.y + (otherCorner.x - center.x); + poly[4].x = otherCorner.x; + poly[4].y = otherCorner.y; + miFillSppPoly(pDraw, pGC, 5, poly, xOrg, yOrg, xFtrans, yFtrans); + break; + case CapRound: + /* + * miRoundCap just needs these to be unequal. + */ + endPoint = center; + endPoint.x = endPoint.x + 100; + miRoundCap(pDraw, pGC, center, endPoint, corner, otherCorner, 0, + -xOrg, -yOrg, xFtrans, yFtrans); + break; + } } /* MIROUNDCAP -- a private helper function @@ -1373,47 +1298,42 @@ miArcCap ( * two corners at this end of the line. * NOTE: pOtherCorner must be counter-clockwise from pCorner. */ -/*ARGSUSED*/ -static void -miRoundCap( - DrawablePtr pDraw, - GCPtr pGC, - SppPointRec pCenter, - SppPointRec pEnd, - SppPointRec pCorner, - SppPointRec pOtherCorner, - int fLineEnd, - int xOrg, - int yOrg, - double xFtrans, - double yFtrans) + /*ARGSUSED*/ static void +miRoundCap(DrawablePtr pDraw, + GCPtr pGC, + SppPointRec pCenter, + SppPointRec pEnd, + SppPointRec pCorner, + SppPointRec pOtherCorner, + int fLineEnd, int xOrg, int yOrg, double xFtrans, double yFtrans) { - int cpt; - double width; - SppArcRec arc; - SppPointPtr pArcPts; + int cpt; + double width; + SppArcRec arc; + SppPointPtr pArcPts; - width = (pGC->lineWidth ? (double)pGC->lineWidth : (double)1); + width = (pGC->lineWidth ? (double) pGC->lineWidth : (double) 1); - arc.x = pCenter.x - width/2; - arc.y = pCenter.y - width/2; + arc.x = pCenter.x - width / 2; + arc.y = pCenter.y - width / 2; arc.width = width; arc.height = width; - arc.angle1 = -miDatan2 (pCorner.y - pCenter.y, pCorner.x - pCenter.x); - if(PTISEQUAL(pCenter, pEnd)) - arc.angle2 = - 180.0; + arc.angle1 = -miDatan2(pCorner.y - pCenter.y, pCorner.x - pCenter.x); + if (PTISEQUAL(pCenter, pEnd)) + arc.angle2 = -180.0; else { - arc.angle2 = -miDatan2 (pOtherCorner.y - pCenter.y, pOtherCorner.x - pCenter.x) - arc.angle1; - if (arc.angle2 < 0) - arc.angle2 += 360.0; + arc.angle2 = + -miDatan2(pOtherCorner.y - pCenter.y, + pOtherCorner.x - pCenter.x) - arc.angle1; + if (arc.angle2 < 0) + arc.angle2 += 360.0; } pArcPts = (SppPointPtr) NULL; - if( (cpt = miGetArcPts(&arc, 0, &pArcPts)) ) - { - /* by drawing with miFillSppPoly and setting the endpoints of the arc - * to be the corners, we assure that the cap will meet up with the - * rest of the line */ - miFillSppPoly(pDraw, pGC, cpt, pArcPts, -xOrg, -yOrg, xFtrans, yFtrans); + if ((cpt = miGetArcPts(&arc, 0, &pArcPts))) { + /* by drawing with miFillSppPoly and setting the endpoints of the arc + * to be the corners, we assure that the cap will meet up with the + * rest of the line */ + miFillSppPoly(pDraw, pGC, cpt, pArcPts, -xOrg, -yOrg, xFtrans, yFtrans); } free(pArcPts); } @@ -1430,79 +1350,91 @@ miRoundCap( #define M_PI_2 1.57079632679489661923 #endif -# define Dsin(d) ((d) == 0.0 ? 0.0 : ((d) == 90.0 ? 1.0 : sin(d*M_PI/180.0))) -# define Dcos(d) ((d) == 0.0 ? 1.0 : ((d) == 90.0 ? 0.0 : cos(d*M_PI/180.0))) -# define mod(a,b) ((a) >= 0 ? (a) % (b) : (b) - (-(a)) % (b)) +#define Dsin(d) ((d) == 0.0 ? 0.0 : ((d) == 90.0 ? 1.0 : sin(d*M_PI/180.0))) +#define Dcos(d) ((d) == 0.0 ? 1.0 : ((d) == 90.0 ? 0.0 : cos(d*M_PI/180.0))) +#define mod(a,b) ((a) >= 0 ? (a) % (b) : (b) - (-(a)) % (b)) static double -miDcos (double a) +miDcos(double a) { - int i; - - if (floor (a/90) == a/90) { - i = (int) (a/90.0); - switch (mod (i, 4)) { - case 0: return 1; - case 1: return 0; - case 2: return -1; - case 3: return 0; - } - } - return cos (a * M_PI / 180.0); + int i; + + if (floor(a / 90) == a / 90) { + i = (int) (a / 90.0); + switch (mod(i, 4)) { + case 0: + return 1; + case 1: + return 0; + case 2: + return -1; + case 3: + return 0; + } + } + return cos(a * M_PI / 180.0); } static double -miDsin (double a) +miDsin(double a) { - int i; - - if (floor (a/90) == a/90) { - i = (int) (a/90.0); - switch (mod (i, 4)) { - case 0: return 0; - case 1: return 1; - case 2: return 0; - case 3: return -1; - } - } - return sin (a * M_PI / 180.0); + int i; + + if (floor(a / 90) == a / 90) { + i = (int) (a / 90.0); + switch (mod(i, 4)) { + case 0: + return 0; + case 1: + return 1; + case 2: + return 0; + case 3: + return -1; + } + } + return sin(a * M_PI / 180.0); } static double -miDasin (double v) +miDasin(double v) { if (v == 0) - return 0.0; + return 0.0; if (v == 1.0) - return 90.0; + return 90.0; if (v == -1.0) - return -90.0; + return -90.0; return asin(v) * (180.0 / M_PI); } static double -miDatan2 (double dy, double dx) +miDatan2(double dy, double dx) { if (dy == 0) { - if (dx >= 0) - return 0.0; - return 180.0; - } else if (dx == 0) { - if (dy > 0) - return 90.0; - return -90.0; - } else if (fabs (dy) == fabs (dx)) { - if (dy > 0) { - if (dx > 0) - return 45.0; - return 135.0; - } else { - if (dx > 0) - return 315.0; - return 225.0; - } - } else { - return atan2 (dy, dx) * (180.0 / M_PI); + if (dx >= 0) + return 0.0; + return 180.0; + } + else if (dx == 0) { + if (dy > 0) + return 90.0; + return -90.0; + } + else if (fabs(dy) == fabs(dx)) { + if (dy > 0) { + if (dx > 0) + return 45.0; + return 135.0; + } + else { + if (dx > 0) + return 315.0; + return 225.0; + } + } + else { + return atan2(dy, dx) * (180.0 / M_PI); } } @@ -1519,30 +1451,28 @@ miDatan2 (double dy, double dx) * count on realloc() to handle the null pointer correctly. */ static int -miGetArcPts( - SppArcPtr parc, /* points to an arc */ - int cpt, /* number of points already in arc list */ - SppPointPtr *ppPts) /* pointer to pointer to arc-list -- modified */ -{ - double st, /* Start Theta, start angle */ - et, /* End Theta, offset from start theta */ - dt, /* Delta Theta, angle to sweep ellipse */ - cdt, /* Cos Delta Theta, actually 2 cos(dt) */ - x0, y0, /* the recurrence formula needs two points to start */ - x1, y1, - x2, y2, /* this will be the new point generated */ - xc, yc; /* the center point */ - int count, i; - SppPointPtr poly; +miGetArcPts(SppArcPtr parc, /* points to an arc */ + int cpt, /* number of points already in arc list */ + SppPointPtr * ppPts) +{ /* pointer to pointer to arc-list -- modified */ + double st, /* Start Theta, start angle */ + et, /* End Theta, offset from start theta */ + dt, /* Delta Theta, angle to sweep ellipse */ + cdt, /* Cos Delta Theta, actually 2 cos(dt) */ + x0, y0, /* the recurrence formula needs two points to start */ + x1, y1, x2, y2, /* this will be the new point generated */ + xc, yc; /* the center point */ + int count, i; + SppPointPtr poly; /* The spec says that positive angles indicate counterclockwise motion. * Given our coordinate system (with 0,0 in the upper left corner), * the screen appears flipped in Y. The easiest fix is to negate the * angles given */ - - st = - parc->angle1; - et = - parc->angle2; + st = -parc->angle1; + + et = -parc->angle2; /* Try to get a delta theta that is within 1/2 pixel. Then adjust it * so that it divides evenly into the total. @@ -1550,175 +1480,151 @@ miGetArcPts( */ cdt = parc->width; if (parc->height > cdt) - cdt = parc->height; + cdt = parc->height; cdt /= 2.0; - if(cdt <= 0) - return 0; + if (cdt <= 0) + return 0; if (cdt < 1.0) - cdt = 1.0; - dt = miDasin ( 1.0 / cdt ); /* minimum step necessary */ - count = et/dt; + cdt = 1.0; + dt = miDasin(1.0 / cdt); /* minimum step necessary */ + count = et / dt; count = abs(count) + 1; - dt = et/count; + dt = et / count; count++; cdt = 2 * miDcos(dt); - if (!(poly = (SppPointPtr) realloc((pointer)*ppPts, - (cpt + count) * sizeof(SppPointRec)))) - return 0; + if (!(poly = (SppPointPtr) realloc((pointer) *ppPts, + (cpt + count) * sizeof(SppPointRec)))) + return 0; *ppPts = poly; - xc = parc->width/2.0; /* store half width and half height */ - yc = parc->height/2.0; - + xc = parc->width / 2.0; /* store half width and half height */ + yc = parc->height / 2.0; + x0 = xc * miDcos(st); y0 = yc * miDsin(st); x1 = xc * miDcos(st + dt); y1 = yc * miDsin(st + dt); - xc += parc->x; /* by adding initial point, these become */ - yc += parc->y; /* the center point */ + xc += parc->x; /* by adding initial point, these become */ + yc += parc->y; /* the center point */ poly[cpt].x = (xc + x0); poly[cpt].y = (yc + y0); poly[cpt + 1].x = (xc + x1); poly[cpt + 1].y = (yc + y1); - for(i = 2; i < count; i++) - { - x2 = cdt * x1 - x0; - y2 = cdt * y1 - y0; + for (i = 2; i < count; i++) { + x2 = cdt * x1 - x0; + y2 = cdt * y1 - y0; - poly[cpt + i].x = (xc + x2); - poly[cpt + i].y = (yc + y2); + poly[cpt + i].x = (xc + x2); + poly[cpt + i].y = (yc + y2); - x0 = x1; y0 = y1; - x1 = x2; y1 = y2; + x0 = x1; + y0 = y1; + x1 = x2; + y1 = y2; } /* adjust the last point */ if (abs(parc->angle2) >= 360.0) - poly[cpt +i -1] = poly[0]; + poly[cpt + i - 1] = poly[0]; else { - poly[cpt +i -1].x = (miDcos(st + et) * parc->width/2.0 + xc); - poly[cpt +i -1].y = (miDsin(st + et) * parc->height/2.0 + yc); + poly[cpt + i - 1].x = (miDcos(st + et) * parc->width / 2.0 + xc); + poly[cpt + i - 1].y = (miDsin(st + et) * parc->height / 2.0 + yc); } return count; } struct arcData { - double x0, y0, x1, y1; - int selfJoin; + double x0, y0, x1, y1; + int selfJoin; }; -# define ADD_REALLOC_STEP 20 +#define ADD_REALLOC_STEP 20 static void -addCap ( - miArcCapPtr *capsp, - int *ncapsp, - int *sizep, - int end, - int arcIndex) +addCap(miArcCapPtr * capsp, int *ncapsp, int *sizep, int end, int arcIndex) { - int newsize; - miArcCapPtr cap; - - if (*ncapsp == *sizep) - { - newsize = *sizep + ADD_REALLOC_STEP; - cap = (miArcCapPtr) realloc(*capsp, - newsize * sizeof (**capsp)); - if (!cap) - return; - *sizep = newsize; - *capsp = cap; - } - cap = &(*capsp)[*ncapsp]; - cap->end = end; - cap->arcIndex = arcIndex; - ++*ncapsp; + int newsize; + miArcCapPtr cap; + + if (*ncapsp == *sizep) { + newsize = *sizep + ADD_REALLOC_STEP; + cap = (miArcCapPtr) realloc(*capsp, newsize * sizeof(**capsp)); + if (!cap) + return; + *sizep = newsize; + *capsp = cap; + } + cap = &(*capsp)[*ncapsp]; + cap->end = end; + cap->arcIndex = arcIndex; + ++*ncapsp; } static void -addJoin ( - miArcJoinPtr *joinsp, - int *njoinsp, - int *sizep, - int end0, - int index0, - int phase0, - int end1, - int index1, - int phase1) +addJoin(miArcJoinPtr * joinsp, + int *njoinsp, + int *sizep, + int end0, int index0, int phase0, int end1, int index1, int phase1) { - int newsize; - miArcJoinPtr join; - - if (*njoinsp == *sizep) - { - newsize = *sizep + ADD_REALLOC_STEP; - join = (miArcJoinPtr) realloc(*joinsp, - newsize * sizeof (**joinsp)); - if (!join) - return; - *sizep = newsize; - *joinsp = join; - } - join = &(*joinsp)[*njoinsp]; - join->end0 = end0; - join->arcIndex0 = index0; - join->phase0 = phase0; - join->end1 = end1; - join->arcIndex1 = index1; - join->phase1 = phase1; - ++*njoinsp; + int newsize; + miArcJoinPtr join; + + if (*njoinsp == *sizep) { + newsize = *sizep + ADD_REALLOC_STEP; + join = (miArcJoinPtr) realloc(*joinsp, newsize * sizeof(**joinsp)); + if (!join) + return; + *sizep = newsize; + *joinsp = join; + } + join = &(*joinsp)[*njoinsp]; + join->end0 = end0; + join->arcIndex0 = index0; + join->phase0 = phase0; + join->end1 = end1; + join->arcIndex1 = index1; + join->phase1 = phase1; + ++*njoinsp; } static miArcDataPtr -addArc ( - miArcDataPtr *arcsp, - int *narcsp, - int *sizep, - xArc *xarc) +addArc(miArcDataPtr * arcsp, int *narcsp, int *sizep, xArc * xarc) { - int newsize; - miArcDataPtr arc; - - if (*narcsp == *sizep) - { - newsize = *sizep + ADD_REALLOC_STEP; - arc = (miArcDataPtr) realloc(*arcsp, - newsize * sizeof (**arcsp)); - if (!arc) - return NULL; - *sizep = newsize; - *arcsp = arc; - } - arc = &(*arcsp)[*narcsp]; - arc->arc = *xarc; - ++*narcsp; - return arc; + int newsize; + miArcDataPtr arc; + + if (*narcsp == *sizep) { + newsize = *sizep + ADD_REALLOC_STEP; + arc = (miArcDataPtr) realloc(*arcsp, newsize * sizeof(**arcsp)); + if (!arc) + return NULL; + *sizep = newsize; + *arcsp = arc; + } + arc = &(*arcsp)[*narcsp]; + arc->arc = *xarc; + ++*narcsp; + return arc; } static void -miFreeArcs( - miPolyArcPtr arcs, - GCPtr pGC) +miFreeArcs(miPolyArcPtr arcs, GCPtr pGC) { - int iphase; - - for (iphase = ((pGC->lineStyle == LineDoubleDash) ? 1 : 0); - iphase >= 0; - iphase--) - { - if (arcs[iphase].narcs > 0) - free(arcs[iphase].arcs); - if (arcs[iphase].njoins > 0) - free(arcs[iphase].joins); - if (arcs[iphase].ncaps > 0) - free(arcs[iphase].caps); - } - free(arcs); + int iphase; + + for (iphase = ((pGC->lineStyle == LineDoubleDash) ? 1 : 0); + iphase >= 0; iphase--) { + if (arcs[iphase].narcs > 0) + free(arcs[iphase].arcs); + if (arcs[iphase].njoins > 0) + free(arcs[iphase].joins); + if (arcs[iphase].ncaps > 0) + free(arcs[iphase].caps); + } + free(arcs); } /* @@ -1729,486 +1635,484 @@ miFreeArcs( * a polygonal approximation to the arc for computing arc lengths */ -# define DASH_MAP_SIZE 91 +#define DASH_MAP_SIZE 91 -# define dashIndexToAngle(di) ((((double) (di)) * 90.0) / ((double) DASH_MAP_SIZE - 1)) -# define xAngleToDashIndex(xa) ((((long) (xa)) * (DASH_MAP_SIZE - 1)) / (90 * 64)) -# define dashIndexToXAngle(di) ((((long) (di)) * (90 * 64)) / (DASH_MAP_SIZE - 1)) -# define dashXAngleStep (((double) (90 * 64)) / ((double) (DASH_MAP_SIZE - 1))) +#define dashIndexToAngle(di) ((((double) (di)) * 90.0) / ((double) DASH_MAP_SIZE - 1)) +#define xAngleToDashIndex(xa) ((((long) (xa)) * (DASH_MAP_SIZE - 1)) / (90 * 64)) +#define dashIndexToXAngle(di) ((((long) (di)) * (90 * 64)) / (DASH_MAP_SIZE - 1)) +#define dashXAngleStep (((double) (90 * 64)) / ((double) (DASH_MAP_SIZE - 1))) typedef struct { - double map[DASH_MAP_SIZE]; + double map[DASH_MAP_SIZE]; } dashMap; -static int computeAngleFromPath(int startAngle, int endAngle, dashMap *map, - int *lenp, int backwards); +static int computeAngleFromPath(int startAngle, int endAngle, dashMap * map, + int *lenp, int backwards); static void -computeDashMap ( - xArc *arcp, - dashMap *map) +computeDashMap(xArc * arcp, dashMap * map) { - int di; - double a, x, y, prevx = 0.0, prevy = 0.0, dist; - - for (di = 0; di < DASH_MAP_SIZE; di++) { - a = dashIndexToAngle (di); - x = ((double) arcp->width / 2.0) * miDcos (a); - y = ((double) arcp->height / 2.0) * miDsin (a); - if (di == 0) { - map->map[di] = 0.0; - } else { - dist = hypot (x - prevx, y - prevy); - map->map[di] = map->map[di - 1] + dist; - } - prevx = x; - prevy = y; - } + int di; + double a, x, y, prevx = 0.0, prevy = 0.0, dist; + + for (di = 0; di < DASH_MAP_SIZE; di++) { + a = dashIndexToAngle(di); + x = ((double) arcp->width / 2.0) * miDcos(a); + y = ((double) arcp->height / 2.0) * miDsin(a); + if (di == 0) { + map->map[di] = 0.0; + } + else { + dist = hypot(x - prevx, y - prevy); + map->map[di] = map->map[di - 1] + dist; + } + prevx = x; + prevy = y; + } } -typedef enum {HORIZONTAL, VERTICAL, OTHER} arcTypes; +typedef enum { HORIZONTAL, VERTICAL, OTHER } arcTypes; /* this routine is a bit gory */ static miPolyArcPtr -miComputeArcs ( - xArc *parcs, - int narcs, - GCPtr pGC) +miComputeArcs(xArc * parcs, int narcs, GCPtr pGC) { - int isDashed, isDoubleDash; - int dashOffset; - miPolyArcPtr arcs; - int start, i, j, k = 0, nexti, nextk = 0; - int joinSize[2]; - int capSize[2]; - int arcSize[2]; - int angle2; - double a0, a1; - struct arcData *data; - miArcDataPtr arc; - xArc xarc; - int iphase, prevphase = 0, joinphase; - int arcsJoin; - int selfJoin; - - int iDash = 0, dashRemaining = 0; - int iDashStart = 0, dashRemainingStart = 0, iphaseStart; - int startAngle, spanAngle, endAngle, backwards = 0; - int prevDashAngle, dashAngle; - dashMap map; - - isDashed = !(pGC->lineStyle == LineSolid); - isDoubleDash = (pGC->lineStyle == LineDoubleDash); - dashOffset = pGC->dashOffset; - - data = malloc(narcs * sizeof (struct arcData)); - if (!data) - return NULL; - arcs = malloc(sizeof (*arcs) * (isDoubleDash ? 2 : 1)); - if (!arcs) - { - free(data); - return NULL; - } - for (i = 0; i < narcs; i++) { - a0 = todeg (parcs[i].angle1); - angle2 = parcs[i].angle2; - if (angle2 > FULLCIRCLE) - angle2 = FULLCIRCLE; - else if (angle2 < -FULLCIRCLE) - angle2 = -FULLCIRCLE; - data[i].selfJoin = angle2 == FULLCIRCLE || angle2 == -FULLCIRCLE; - a1 = todeg (parcs[i].angle1 + angle2); - data[i].x0 = parcs[i].x + (double) parcs[i].width / 2 * (1 + miDcos (a0)); - data[i].y0 = parcs[i].y + (double) parcs[i].height / 2 * (1 - miDsin (a0)); - data[i].x1 = parcs[i].x + (double) parcs[i].width / 2 * (1 + miDcos (a1)); - data[i].y1 = parcs[i].y + (double) parcs[i].height / 2 * (1 - miDsin (a1)); - } - - for (iphase = 0; iphase < (isDoubleDash ? 2 : 1); iphase++) { - arcs[iphase].njoins = 0; - arcs[iphase].joins = 0; - joinSize[iphase] = 0; - - arcs[iphase].ncaps = 0; - arcs[iphase].caps = 0; - capSize[iphase] = 0; - - arcs[iphase].narcs = 0; - arcs[iphase].arcs = 0; - arcSize[iphase] = 0; - } - - iphase = 0; - if (isDashed) { - iDash = 0; - dashRemaining = pGC->dash[0]; - while (dashOffset > 0) { - if (dashOffset >= dashRemaining) { - dashOffset -= dashRemaining; - iphase = iphase ? 0 : 1; - iDash++; - if (iDash == pGC->numInDashList) - iDash = 0; - dashRemaining = pGC->dash[iDash]; - } else { - dashRemaining -= dashOffset; - dashOffset = 0; - } - } - iDashStart = iDash; - dashRemainingStart = dashRemaining; - } - iphaseStart = iphase; - - for (i = narcs - 1; i >= 0; i--) { - j = i + 1; - if (j == narcs) - j = 0; - if (data[i].selfJoin || i == j || - (UNEQUAL (data[i].x1, data[j].x0) || - UNEQUAL (data[i].y1, data[j].y0))) - { - if (iphase == 0 || isDoubleDash) - addCap (&arcs[iphase].caps, &arcs[iphase].ncaps, - &capSize[iphase], RIGHT_END, 0); - break; - } - } - start = i + 1; - if (start == narcs) - start = 0; - i = start; - for (;;) { - j = i + 1; - if (j == narcs) - j = 0; - nexti = i+1; - if (nexti == narcs) - nexti = 0; - if (isDashed) { - /* - ** deal with dashed arcs. Use special rules for certain 0 area arcs. - ** Presumably, the other 0 area arcs still aren't done right. - */ - arcTypes arcType = OTHER; - CARD16 thisLength; - - if (parcs[i].height == 0 - && (parcs[i].angle1 % FULLCIRCLE) == 0x2d00 - && parcs[i].angle2 == 0x2d00) - arcType = HORIZONTAL; - else if (parcs[i].width == 0 - && (parcs[i].angle1 % FULLCIRCLE) == 0x1680 - && parcs[i].angle2 == 0x2d00) - arcType = VERTICAL; - if (arcType == OTHER) { - /* - * precompute an approximation map - */ - computeDashMap (&parcs[i], &map); - /* - * compute each individual dash segment using the path - * length function - */ - startAngle = parcs[i].angle1; - spanAngle = parcs[i].angle2; - if (spanAngle > FULLCIRCLE) - spanAngle = FULLCIRCLE; - else if (spanAngle < -FULLCIRCLE) - spanAngle = -FULLCIRCLE; - if (startAngle < 0) - startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE; - if (startAngle >= FULLCIRCLE) - startAngle = startAngle % FULLCIRCLE; - endAngle = startAngle + spanAngle; - backwards = spanAngle < 0; - } else { - xarc = parcs[i]; - if (arcType == VERTICAL) { - xarc.angle1 = 0x1680; - startAngle = parcs[i].y; - endAngle = startAngle + parcs[i].height; - } else { - xarc.angle1 = 0x2d00; - startAngle = parcs[i].x; - endAngle = startAngle + parcs[i].width; - } - } - dashAngle = startAngle; - selfJoin = data[i].selfJoin && - (iphase == 0 || isDoubleDash); - /* - * add dashed arcs to each bucket - */ - arc = 0; - while (dashAngle != endAngle) { - prevDashAngle = dashAngle; - if (arcType == OTHER) { - dashAngle = computeAngleFromPath (prevDashAngle, endAngle, - &map, &dashRemaining, backwards); - /* avoid troubles with huge arcs and small dashes */ - if (dashAngle == prevDashAngle) { - if (backwards) - dashAngle--; - else - dashAngle++; - } - } else { - thisLength = (dashAngle + dashRemaining <= endAngle) ? - dashRemaining : endAngle - dashAngle; - if (arcType == VERTICAL) { - xarc.y = dashAngle; - xarc.height = thisLength; - } else { - xarc.x = dashAngle; - xarc.width = thisLength; - } - dashAngle += thisLength; - dashRemaining -= thisLength; - } - if (iphase == 0 || isDoubleDash) { - if (arcType == OTHER) { - xarc = parcs[i]; - spanAngle = prevDashAngle; - if (spanAngle < 0) - spanAngle = FULLCIRCLE - (-spanAngle) % FULLCIRCLE; - if (spanAngle >= FULLCIRCLE) - spanAngle = spanAngle % FULLCIRCLE; - xarc.angle1 = spanAngle; - spanAngle = dashAngle - prevDashAngle; - if (backwards) { - if (dashAngle > prevDashAngle) - spanAngle = - FULLCIRCLE + spanAngle; - } else { - if (dashAngle < prevDashAngle) - spanAngle = FULLCIRCLE + spanAngle; - } - if (spanAngle > FULLCIRCLE) - spanAngle = FULLCIRCLE; - if (spanAngle < -FULLCIRCLE) - spanAngle = -FULLCIRCLE; - xarc.angle2 = spanAngle; - } - arc = addArc (&arcs[iphase].arcs, &arcs[iphase].narcs, - &arcSize[iphase], &xarc); - if (!arc) - goto arcfail; - /* - * cap each end of an on/off dash - */ - if (!isDoubleDash) { - if (prevDashAngle != startAngle) { - addCap (&arcs[iphase].caps, - &arcs[iphase].ncaps, - &capSize[iphase], RIGHT_END, - arc - arcs[iphase].arcs); - - } - if (dashAngle != endAngle) { - addCap (&arcs[iphase].caps, - &arcs[iphase].ncaps, - &capSize[iphase], LEFT_END, - arc - arcs[iphase].arcs); - } - } - arc->cap = arcs[iphase].ncaps; - arc->join = arcs[iphase].njoins; - arc->render = 0; - arc->selfJoin = 0; - if (dashAngle == endAngle) - arc->selfJoin = selfJoin; - } - prevphase = iphase; - if (dashRemaining <= 0) { - ++iDash; - if (iDash == pGC->numInDashList) - iDash = 0; - iphase = iphase ? 0:1; - dashRemaining = pGC->dash[iDash]; - } - } - /* - * make sure a place exists for the position data when - * drawing a zero-length arc - */ - if (startAngle == endAngle) { - prevphase = iphase; - if (!isDoubleDash && iphase == 1) - prevphase = 0; - arc = addArc (&arcs[prevphase].arcs, &arcs[prevphase].narcs, - &arcSize[prevphase], &parcs[i]); - if (!arc) - goto arcfail; - arc->join = arcs[prevphase].njoins; - arc->cap = arcs[prevphase].ncaps; - arc->selfJoin = data[i].selfJoin; - } - } else { - arc = addArc (&arcs[iphase].arcs, &arcs[iphase].narcs, - &arcSize[iphase], &parcs[i]); - if (!arc) - goto arcfail; - arc->join = arcs[iphase].njoins; - arc->cap = arcs[iphase].ncaps; - arc->selfJoin = data[i].selfJoin; - prevphase = iphase; - } - if (prevphase == 0 || isDoubleDash) - k = arcs[prevphase].narcs - 1; - if (iphase == 0 || isDoubleDash) - nextk = arcs[iphase].narcs; - if (nexti == start) { - nextk = 0; - if (isDashed) { - iDash = iDashStart; - iphase = iphaseStart; - dashRemaining = dashRemainingStart; - } - } - arcsJoin = narcs > 1 && i != j && - ISEQUAL (data[i].x1, data[j].x0) && - ISEQUAL (data[i].y1, data[j].y0) && - !data[i].selfJoin && !data[j].selfJoin; - if (arc) - { - if (arcsJoin) - arc->render = 0; - else - arc->render = 1; - } - if (arcsJoin && - (prevphase == 0 || isDoubleDash) && - (iphase == 0 || isDoubleDash)) - { - joinphase = iphase; - if (isDoubleDash) { - if (nexti == start) - joinphase = iphaseStart; - /* - * if the join is right at the dash, - * draw the join in foreground - * This is because the foreground - * arcs are computed second, the results - * of which are needed to draw the join - */ - if (joinphase != prevphase) - joinphase = 0; - } - if (joinphase == 0 || isDoubleDash) { - addJoin (&arcs[joinphase].joins, - &arcs[joinphase].njoins, - &joinSize[joinphase], - LEFT_END, k, prevphase, - RIGHT_END, nextk, iphase); - arc->join = arcs[prevphase].njoins; - } - } else { - /* - * cap the left end of this arc - * unless it joins itself - */ - if ((prevphase == 0 || isDoubleDash) && - !arc->selfJoin) - { - addCap (&arcs[prevphase].caps, &arcs[prevphase].ncaps, - &capSize[prevphase], LEFT_END, k); - arc->cap = arcs[prevphase].ncaps; - } - if (isDashed && !arcsJoin) { - iDash = iDashStart; - iphase = iphaseStart; - dashRemaining = dashRemainingStart; - } - nextk = arcs[iphase].narcs; - if (nexti == start) { - nextk = 0; - iDash = iDashStart; - iphase = iphaseStart; - dashRemaining = dashRemainingStart; - } - /* - * cap the right end of the next arc. If the - * next arc is actually the first arc, only - * cap it if it joins with this arc. This - * case will occur when the final dash segment - * of an on/off dash is off. Of course, this - * cap will be drawn at a strange time, but that - * hardly matters... - */ - if ((iphase == 0 || isDoubleDash) && - (nexti != start || (arcsJoin && isDashed))) - addCap (&arcs[iphase].caps, &arcs[iphase].ncaps, - &capSize[iphase], RIGHT_END, nextk); - } - i = nexti; - if (i == start) - break; - } - /* - * make sure the last section is rendered - */ - for (iphase = 0; iphase < (isDoubleDash ? 2 : 1); iphase++) - if (arcs[iphase].narcs > 0) { - arcs[iphase].arcs[arcs[iphase].narcs-1].render = 1; - arcs[iphase].arcs[arcs[iphase].narcs-1].join = - arcs[iphase].njoins; - arcs[iphase].arcs[arcs[iphase].narcs-1].cap = - arcs[iphase].ncaps; - } - free(data); - return arcs; -arcfail: - miFreeArcs(arcs, pGC); - free(data); - return NULL; + int isDashed, isDoubleDash; + int dashOffset; + miPolyArcPtr arcs; + int start, i, j, k = 0, nexti, nextk = 0; + int joinSize[2]; + int capSize[2]; + int arcSize[2]; + int angle2; + double a0, a1; + struct arcData *data; + miArcDataPtr arc; + xArc xarc; + int iphase, prevphase = 0, joinphase; + int arcsJoin; + int selfJoin; + + int iDash = 0, dashRemaining = 0; + int iDashStart = 0, dashRemainingStart = 0, iphaseStart; + int startAngle, spanAngle, endAngle, backwards = 0; + int prevDashAngle, dashAngle; + dashMap map; + + isDashed = !(pGC->lineStyle == LineSolid); + isDoubleDash = (pGC->lineStyle == LineDoubleDash); + dashOffset = pGC->dashOffset; + + data = malloc(narcs * sizeof(struct arcData)); + if (!data) + return NULL; + arcs = malloc(sizeof(*arcs) * (isDoubleDash ? 2 : 1)); + if (!arcs) { + free(data); + return NULL; + } + for (i = 0; i < narcs; i++) { + a0 = todeg(parcs[i].angle1); + angle2 = parcs[i].angle2; + if (angle2 > FULLCIRCLE) + angle2 = FULLCIRCLE; + else if (angle2 < -FULLCIRCLE) + angle2 = -FULLCIRCLE; + data[i].selfJoin = angle2 == FULLCIRCLE || angle2 == -FULLCIRCLE; + a1 = todeg(parcs[i].angle1 + angle2); + data[i].x0 = + parcs[i].x + (double) parcs[i].width / 2 * (1 + miDcos(a0)); + data[i].y0 = + parcs[i].y + (double) parcs[i].height / 2 * (1 - miDsin(a0)); + data[i].x1 = + parcs[i].x + (double) parcs[i].width / 2 * (1 + miDcos(a1)); + data[i].y1 = + parcs[i].y + (double) parcs[i].height / 2 * (1 - miDsin(a1)); + } + + for (iphase = 0; iphase < (isDoubleDash ? 2 : 1); iphase++) { + arcs[iphase].njoins = 0; + arcs[iphase].joins = 0; + joinSize[iphase] = 0; + + arcs[iphase].ncaps = 0; + arcs[iphase].caps = 0; + capSize[iphase] = 0; + + arcs[iphase].narcs = 0; + arcs[iphase].arcs = 0; + arcSize[iphase] = 0; + } + + iphase = 0; + if (isDashed) { + iDash = 0; + dashRemaining = pGC->dash[0]; + while (dashOffset > 0) { + if (dashOffset >= dashRemaining) { + dashOffset -= dashRemaining; + iphase = iphase ? 0 : 1; + iDash++; + if (iDash == pGC->numInDashList) + iDash = 0; + dashRemaining = pGC->dash[iDash]; + } + else { + dashRemaining -= dashOffset; + dashOffset = 0; + } + } + iDashStart = iDash; + dashRemainingStart = dashRemaining; + } + iphaseStart = iphase; + + for (i = narcs - 1; i >= 0; i--) { + j = i + 1; + if (j == narcs) + j = 0; + if (data[i].selfJoin || i == j || + (UNEQUAL(data[i].x1, data[j].x0) || + UNEQUAL(data[i].y1, data[j].y0))) { + if (iphase == 0 || isDoubleDash) + addCap(&arcs[iphase].caps, &arcs[iphase].ncaps, + &capSize[iphase], RIGHT_END, 0); + break; + } + } + start = i + 1; + if (start == narcs) + start = 0; + i = start; + for (;;) { + j = i + 1; + if (j == narcs) + j = 0; + nexti = i + 1; + if (nexti == narcs) + nexti = 0; + if (isDashed) { + /* + ** deal with dashed arcs. Use special rules for certain 0 area arcs. + ** Presumably, the other 0 area arcs still aren't done right. + */ + arcTypes arcType = OTHER; + CARD16 thisLength; + + if (parcs[i].height == 0 + && (parcs[i].angle1 % FULLCIRCLE) == 0x2d00 + && parcs[i].angle2 == 0x2d00) + arcType = HORIZONTAL; + else if (parcs[i].width == 0 + && (parcs[i].angle1 % FULLCIRCLE) == 0x1680 + && parcs[i].angle2 == 0x2d00) + arcType = VERTICAL; + if (arcType == OTHER) { + /* + * precompute an approximation map + */ + computeDashMap(&parcs[i], &map); + /* + * compute each individual dash segment using the path + * length function + */ + startAngle = parcs[i].angle1; + spanAngle = parcs[i].angle2; + if (spanAngle > FULLCIRCLE) + spanAngle = FULLCIRCLE; + else if (spanAngle < -FULLCIRCLE) + spanAngle = -FULLCIRCLE; + if (startAngle < 0) + startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE; + if (startAngle >= FULLCIRCLE) + startAngle = startAngle % FULLCIRCLE; + endAngle = startAngle + spanAngle; + backwards = spanAngle < 0; + } + else { + xarc = parcs[i]; + if (arcType == VERTICAL) { + xarc.angle1 = 0x1680; + startAngle = parcs[i].y; + endAngle = startAngle + parcs[i].height; + } + else { + xarc.angle1 = 0x2d00; + startAngle = parcs[i].x; + endAngle = startAngle + parcs[i].width; + } + } + dashAngle = startAngle; + selfJoin = data[i].selfJoin && (iphase == 0 || isDoubleDash); + /* + * add dashed arcs to each bucket + */ + arc = 0; + while (dashAngle != endAngle) { + prevDashAngle = dashAngle; + if (arcType == OTHER) { + dashAngle = computeAngleFromPath(prevDashAngle, endAngle, + &map, &dashRemaining, + backwards); + /* avoid troubles with huge arcs and small dashes */ + if (dashAngle == prevDashAngle) { + if (backwards) + dashAngle--; + else + dashAngle++; + } + } + else { + thisLength = (dashAngle + dashRemaining <= endAngle) ? + dashRemaining : endAngle - dashAngle; + if (arcType == VERTICAL) { + xarc.y = dashAngle; + xarc.height = thisLength; + } + else { + xarc.x = dashAngle; + xarc.width = thisLength; + } + dashAngle += thisLength; + dashRemaining -= thisLength; + } + if (iphase == 0 || isDoubleDash) { + if (arcType == OTHER) { + xarc = parcs[i]; + spanAngle = prevDashAngle; + if (spanAngle < 0) + spanAngle = FULLCIRCLE - (-spanAngle) % FULLCIRCLE; + if (spanAngle >= FULLCIRCLE) + spanAngle = spanAngle % FULLCIRCLE; + xarc.angle1 = spanAngle; + spanAngle = dashAngle - prevDashAngle; + if (backwards) { + if (dashAngle > prevDashAngle) + spanAngle = -FULLCIRCLE + spanAngle; + } + else { + if (dashAngle < prevDashAngle) + spanAngle = FULLCIRCLE + spanAngle; + } + if (spanAngle > FULLCIRCLE) + spanAngle = FULLCIRCLE; + if (spanAngle < -FULLCIRCLE) + spanAngle = -FULLCIRCLE; + xarc.angle2 = spanAngle; + } + arc = addArc(&arcs[iphase].arcs, &arcs[iphase].narcs, + &arcSize[iphase], &xarc); + if (!arc) + goto arcfail; + /* + * cap each end of an on/off dash + */ + if (!isDoubleDash) { + if (prevDashAngle != startAngle) { + addCap(&arcs[iphase].caps, + &arcs[iphase].ncaps, + &capSize[iphase], RIGHT_END, + arc - arcs[iphase].arcs); + + } + if (dashAngle != endAngle) { + addCap(&arcs[iphase].caps, + &arcs[iphase].ncaps, + &capSize[iphase], LEFT_END, + arc - arcs[iphase].arcs); + } + } + arc->cap = arcs[iphase].ncaps; + arc->join = arcs[iphase].njoins; + arc->render = 0; + arc->selfJoin = 0; + if (dashAngle == endAngle) + arc->selfJoin = selfJoin; + } + prevphase = iphase; + if (dashRemaining <= 0) { + ++iDash; + if (iDash == pGC->numInDashList) + iDash = 0; + iphase = iphase ? 0 : 1; + dashRemaining = pGC->dash[iDash]; + } + } + /* + * make sure a place exists for the position data when + * drawing a zero-length arc + */ + if (startAngle == endAngle) { + prevphase = iphase; + if (!isDoubleDash && iphase == 1) + prevphase = 0; + arc = addArc(&arcs[prevphase].arcs, &arcs[prevphase].narcs, + &arcSize[prevphase], &parcs[i]); + if (!arc) + goto arcfail; + arc->join = arcs[prevphase].njoins; + arc->cap = arcs[prevphase].ncaps; + arc->selfJoin = data[i].selfJoin; + } + } + else { + arc = addArc(&arcs[iphase].arcs, &arcs[iphase].narcs, + &arcSize[iphase], &parcs[i]); + if (!arc) + goto arcfail; + arc->join = arcs[iphase].njoins; + arc->cap = arcs[iphase].ncaps; + arc->selfJoin = data[i].selfJoin; + prevphase = iphase; + } + if (prevphase == 0 || isDoubleDash) + k = arcs[prevphase].narcs - 1; + if (iphase == 0 || isDoubleDash) + nextk = arcs[iphase].narcs; + if (nexti == start) { + nextk = 0; + if (isDashed) { + iDash = iDashStart; + iphase = iphaseStart; + dashRemaining = dashRemainingStart; + } + } + arcsJoin = narcs > 1 && i != j && + ISEQUAL(data[i].x1, data[j].x0) && + ISEQUAL(data[i].y1, data[j].y0) && + !data[i].selfJoin && !data[j].selfJoin; + if (arc) { + if (arcsJoin) + arc->render = 0; + else + arc->render = 1; + } + if (arcsJoin && + (prevphase == 0 || isDoubleDash) && (iphase == 0 || isDoubleDash)) { + joinphase = iphase; + if (isDoubleDash) { + if (nexti == start) + joinphase = iphaseStart; + /* + * if the join is right at the dash, + * draw the join in foreground + * This is because the foreground + * arcs are computed second, the results + * of which are needed to draw the join + */ + if (joinphase != prevphase) + joinphase = 0; + } + if (joinphase == 0 || isDoubleDash) { + addJoin(&arcs[joinphase].joins, + &arcs[joinphase].njoins, + &joinSize[joinphase], + LEFT_END, k, prevphase, RIGHT_END, nextk, iphase); + arc->join = arcs[prevphase].njoins; + } + } + else { + /* + * cap the left end of this arc + * unless it joins itself + */ + if ((prevphase == 0 || isDoubleDash) && !arc->selfJoin) { + addCap(&arcs[prevphase].caps, &arcs[prevphase].ncaps, + &capSize[prevphase], LEFT_END, k); + arc->cap = arcs[prevphase].ncaps; + } + if (isDashed && !arcsJoin) { + iDash = iDashStart; + iphase = iphaseStart; + dashRemaining = dashRemainingStart; + } + nextk = arcs[iphase].narcs; + if (nexti == start) { + nextk = 0; + iDash = iDashStart; + iphase = iphaseStart; + dashRemaining = dashRemainingStart; + } + /* + * cap the right end of the next arc. If the + * next arc is actually the first arc, only + * cap it if it joins with this arc. This + * case will occur when the final dash segment + * of an on/off dash is off. Of course, this + * cap will be drawn at a strange time, but that + * hardly matters... + */ + if ((iphase == 0 || isDoubleDash) && + (nexti != start || (arcsJoin && isDashed))) + addCap(&arcs[iphase].caps, &arcs[iphase].ncaps, + &capSize[iphase], RIGHT_END, nextk); + } + i = nexti; + if (i == start) + break; + } + /* + * make sure the last section is rendered + */ + for (iphase = 0; iphase < (isDoubleDash ? 2 : 1); iphase++) + if (arcs[iphase].narcs > 0) { + arcs[iphase].arcs[arcs[iphase].narcs - 1].render = 1; + arcs[iphase].arcs[arcs[iphase].narcs - 1].join = + arcs[iphase].njoins; + arcs[iphase].arcs[arcs[iphase].narcs - 1].cap = arcs[iphase].ncaps; + } + free(data); + return arcs; + arcfail: + miFreeArcs(arcs, pGC); + free(data); + return NULL; } static double -angleToLength ( - int angle, - dashMap *map) +angleToLength(int angle, dashMap * map) { - double len, excesslen, sidelen = map->map[DASH_MAP_SIZE - 1], totallen; - int di; - int excess; - Bool oddSide = FALSE; - - totallen = 0; - if (angle >= 0) { - while (angle >= 90 * 64) { - angle -= 90 * 64; - totallen += sidelen; - oddSide = !oddSide; - } - } else { - while (angle < 0) { - angle += 90 * 64; - totallen -= sidelen; - oddSide = !oddSide; - } - } - if (oddSide) - angle = 90 * 64 - angle; - - di = xAngleToDashIndex (angle); - excess = angle - dashIndexToXAngle (di); - - len = map->map[di]; - /* - * linearly interpolate between this point and the next - */ - if (excess > 0) { - excesslen = (map->map[di + 1] - map->map[di]) * - ((double) excess) / dashXAngleStep; - len += excesslen; - } - if (oddSide) - totallen += (sidelen - len); - else - totallen += len; - return totallen; + double len, excesslen, sidelen = map->map[DASH_MAP_SIZE - 1], totallen; + int di; + int excess; + Bool oddSide = FALSE; + + totallen = 0; + if (angle >= 0) { + while (angle >= 90 * 64) { + angle -= 90 * 64; + totallen += sidelen; + oddSide = !oddSide; + } + } + else { + while (angle < 0) { + angle += 90 * 64; + totallen -= sidelen; + oddSide = !oddSide; + } + } + if (oddSide) + angle = 90 * 64 - angle; + + di = xAngleToDashIndex(angle); + excess = angle - dashIndexToXAngle(di); + + len = map->map[di]; + /* + * linearly interpolate between this point and the next + */ + if (excess > 0) { + excesslen = (map->map[di + 1] - map->map[di]) * + ((double) excess) / dashXAngleStep; + len += excesslen; + } + if (oddSide) + totallen += (sidelen - len); + else + totallen += len; + return totallen; } /* @@ -2216,63 +2120,62 @@ angleToLength ( */ static int -lengthToAngle ( - double len, - dashMap *map) +lengthToAngle(double len, dashMap * map) { - double sidelen = map->map[DASH_MAP_SIZE - 1]; - int angle, angleexcess; - Bool oddSide = FALSE; - int a0, a1, a; - - angle = 0; - /* - * step around the ellipse, subtracting sidelens and - * adding 90 degrees. oddSide will tell if the - * map should be interpolated in reverse - */ - if (len >= 0) { - if (sidelen == 0) - return 2 * FULLCIRCLE; /* infinity */ - while (len >= sidelen) { - angle += 90 * 64; - len -= sidelen; - oddSide = !oddSide; - } - } else { - if (sidelen == 0) - return -2 * FULLCIRCLE; /* infinity */ - while (len < 0) { - angle -= 90 * 64; - len += sidelen; - oddSide = !oddSide; - } - } - if (oddSide) - len = sidelen - len; - a0 = 0; - a1 = DASH_MAP_SIZE - 1; - /* - * binary search for the closest pre-computed length - */ - while (a1 - a0 > 1) { - a = (a0 + a1) / 2; - if (len > map->map[a]) - a0 = a; - else - a1 = a; - } - angleexcess = dashIndexToXAngle (a0); - /* - * linearly interpolate to the next point - */ - angleexcess += (len - map->map[a0]) / - (map->map[a0+1] - map->map[a0]) * dashXAngleStep; - if (oddSide) - angle += (90 * 64) - angleexcess; - else - angle += angleexcess; - return angle; + double sidelen = map->map[DASH_MAP_SIZE - 1]; + int angle, angleexcess; + Bool oddSide = FALSE; + int a0, a1, a; + + angle = 0; + /* + * step around the ellipse, subtracting sidelens and + * adding 90 degrees. oddSide will tell if the + * map should be interpolated in reverse + */ + if (len >= 0) { + if (sidelen == 0) + return 2 * FULLCIRCLE; /* infinity */ + while (len >= sidelen) { + angle += 90 * 64; + len -= sidelen; + oddSide = !oddSide; + } + } + else { + if (sidelen == 0) + return -2 * FULLCIRCLE; /* infinity */ + while (len < 0) { + angle -= 90 * 64; + len += sidelen; + oddSide = !oddSide; + } + } + if (oddSide) + len = sidelen - len; + a0 = 0; + a1 = DASH_MAP_SIZE - 1; + /* + * binary search for the closest pre-computed length + */ + while (a1 - a0 > 1) { + a = (a0 + a1) / 2; + if (len > map->map[a]) + a0 = a; + else + a1 = a; + } + angleexcess = dashIndexToXAngle(a0); + /* + * linearly interpolate to the next point + */ + angleexcess += (len - map->map[a0]) / + (map->map[a0 + 1] - map->map[a0]) * dashXAngleStep; + if (oddSide) + angle += (90 * 64) - angleexcess; + else + angle += angleexcess; + return angle; } /* @@ -2288,41 +2191,38 @@ lengthToAngle ( */ static int -computeAngleFromPath ( - int startAngle, - int endAngle, /* normalized absolute angles in *64 degrees */ - dashMap *map, - int *lenp, - int backwards) +computeAngleFromPath(int startAngle, int endAngle, /* normalized absolute angles in *64 degrees */ + dashMap * map, int *lenp, int backwards) { - int a0, a1, a; - double len0; - int len; - - a0 = startAngle; - a1 = endAngle; - len = *lenp; - if (backwards) { - /* - * flip the problem around to always be - * forwards - */ - a0 = FULLCIRCLE - a0; - a1 = FULLCIRCLE - a1; - } - if (a1 < a0) - a1 += FULLCIRCLE; - len0 = angleToLength (a0, map); - a = lengthToAngle (len0 + len, map); - if (a > a1) { - a = a1; - len -= angleToLength (a1, map) - len0; - } else - len = 0; - if (backwards) - a = FULLCIRCLE - a; - *lenp = len; - return a; + int a0, a1, a; + double len0; + int len; + + a0 = startAngle; + a1 = endAngle; + len = *lenp; + if (backwards) { + /* + * flip the problem around to always be + * forwards + */ + a0 = FULLCIRCLE - a0; + a1 = FULLCIRCLE - a1; + } + if (a1 < a0) + a1 += FULLCIRCLE; + len0 = angleToLength(a0, map); + a = lengthToAngle(len0 + len, map); + if (a > a1) { + a = a1; + len -= angleToLength(a1, map) - len0; + } + else + len = 0; + if (backwards) + a = FULLCIRCLE - a; + *lenp = len; + return a; } /* @@ -2334,133 +2234,122 @@ computeAngleFromPath ( */ static void -drawZeroArc ( - DrawablePtr pDraw, - GCPtr pGC, - xArc *tarc, - int lw, - miArcFacePtr left, - miArcFacePtr right) +drawZeroArc(DrawablePtr pDraw, + GCPtr pGC, + xArc * tarc, int lw, miArcFacePtr left, miArcFacePtr right) { - double x0 = 0.0, y0 = 0.0, x1 = 0.0, y1 = 0.0, w, h, x, y; - double xmax, ymax, xmin, ymin; - int a0, a1; - double a, startAngle, endAngle; - double l, lx, ly; - - l = lw / 2.0; - a0 = tarc->angle1; - a1 = tarc->angle2; - if (a1 > FULLCIRCLE) - a1 = FULLCIRCLE; - else if (a1 < -FULLCIRCLE) - a1 = -FULLCIRCLE; - w = (double)tarc->width / 2.0; - h = (double)tarc->height / 2.0; - /* - * play in X coordinates right away - */ - startAngle = - ((double) a0 / 64.0); - endAngle = - ((double) (a0 + a1) / 64.0); - - xmax = -w; - xmin = w; - ymax = -h; - ymin = h; - a = startAngle; - for (;;) - { - x = w * miDcos(a); - y = h * miDsin(a); - if (a == startAngle) - { - x0 = x; - y0 = y; - } - if (a == endAngle) - { - x1 = x; - y1 = y; - } - if (x > xmax) - xmax = x; - if (x < xmin) - xmin = x; - if (y > ymax) - ymax = y; - if (y < ymin) - ymin = y; - if (a == endAngle) - break; - if (a1 < 0) /* clockwise */ - { - if (floor (a / 90.0) == floor (endAngle / 90.0)) - a = endAngle; - else - a = 90 * (floor (a/90.0) + 1); - } - else - { - if (ceil (a / 90.0) == ceil (endAngle / 90.0)) - a = endAngle; - else - a = 90 * (ceil (a/90.0) - 1); - } - } - lx = ly = l; - if ((x1 - x0) + (y1 - y0) < 0) - lx = ly = -l; - if (h) - { - ly = 0.0; - lx = -lx; - } - else - lx = 0.0; - if (right) - { - right->center.x = x0; - right->center.y = y0; - right->clock.x = x0 - lx; - right->clock.y = y0 - ly; - right->counterClock.x = x0 + lx; - right->counterClock.y = y0 + ly; - } - if (left) - { - left->center.x = x1; - left->center.y = y1; - left->clock.x = x1 + lx; - left->clock.y = y1 + ly; - left->counterClock.x = x1 - lx; - left->counterClock.y = y1 - ly; - } - - x0 = xmin; - x1 = xmax; - y0 = ymin; - y1 = ymax; - if (ymin != y1) { - xmin = -l; - xmax = l; - } else { - ymin = -l; - ymax = l; - } - if (xmax != xmin && ymax != ymin) { - int minx, maxx, miny, maxy; - xRectangle rect; - - minx = ICEIL (xmin + w) + tarc->x; - maxx = ICEIL (xmax + w) + tarc->x; - miny = ICEIL (ymin + h) + tarc->y; - maxy = ICEIL (ymax + h) + tarc->y; - rect.x = minx; - rect.y = miny; - rect.width = maxx - minx; - rect.height = maxy - miny; - (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &rect); - } + double x0 = 0.0, y0 = 0.0, x1 = 0.0, y1 = 0.0, w, h, x, y; + double xmax, ymax, xmin, ymin; + int a0, a1; + double a, startAngle, endAngle; + double l, lx, ly; + + l = lw / 2.0; + a0 = tarc->angle1; + a1 = tarc->angle2; + if (a1 > FULLCIRCLE) + a1 = FULLCIRCLE; + else if (a1 < -FULLCIRCLE) + a1 = -FULLCIRCLE; + w = (double) tarc->width / 2.0; + h = (double) tarc->height / 2.0; + /* + * play in X coordinates right away + */ + startAngle = -((double) a0 / 64.0); + endAngle = -((double) (a0 + a1) / 64.0); + + xmax = -w; + xmin = w; + ymax = -h; + ymin = h; + a = startAngle; + for (;;) { + x = w * miDcos(a); + y = h * miDsin(a); + if (a == startAngle) { + x0 = x; + y0 = y; + } + if (a == endAngle) { + x1 = x; + y1 = y; + } + if (x > xmax) + xmax = x; + if (x < xmin) + xmin = x; + if (y > ymax) + ymax = y; + if (y < ymin) + ymin = y; + if (a == endAngle) + break; + if (a1 < 0) { /* clockwise */ + if (floor(a / 90.0) == floor(endAngle / 90.0)) + a = endAngle; + else + a = 90 * (floor(a / 90.0) + 1); + } + else { + if (ceil(a / 90.0) == ceil(endAngle / 90.0)) + a = endAngle; + else + a = 90 * (ceil(a / 90.0) - 1); + } + } + lx = ly = l; + if ((x1 - x0) + (y1 - y0) < 0) + lx = ly = -l; + if (h) { + ly = 0.0; + lx = -lx; + } + else + lx = 0.0; + if (right) { + right->center.x = x0; + right->center.y = y0; + right->clock.x = x0 - lx; + right->clock.y = y0 - ly; + right->counterClock.x = x0 + lx; + right->counterClock.y = y0 + ly; + } + if (left) { + left->center.x = x1; + left->center.y = y1; + left->clock.x = x1 + lx; + left->clock.y = y1 + ly; + left->counterClock.x = x1 - lx; + left->counterClock.y = y1 - ly; + } + + x0 = xmin; + x1 = xmax; + y0 = ymin; + y1 = ymax; + if (ymin != y1) { + xmin = -l; + xmax = l; + } + else { + ymin = -l; + ymax = l; + } + if (xmax != xmin && ymax != ymin) { + int minx, maxx, miny, maxy; + xRectangle rect; + + minx = ICEIL(xmin + w) + tarc->x; + maxx = ICEIL(xmax + w) + tarc->x; + miny = ICEIL(ymin + h) + tarc->y; + maxy = ICEIL(ymax + h) + tarc->y; + rect.x = minx; + rect.y = miny; + rect.width = maxx - minx; + rect.height = maxy - miny; + (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &rect); + } } /* @@ -2469,27 +2358,26 @@ drawZeroArc ( */ static void -tailEllipseY ( - struct arc_def *def, - struct accelerators *acc) +tailEllipseY(struct arc_def *def, struct accelerators *acc) { - double t; - - acc->tail_y = 0.0; - if (def->w == def->h) - return; - t = def->l * def->w; - if (def->w > def->h) { - if (t < acc->h2) - return; - } else { - if (t > acc->h2) - return; - } - t = 2.0 * def->h * t; - t = (CUBED_ROOT_4 * acc->h2 - cbrt(t * t)) / acc->h2mw2; - if (t > 0.0) - acc->tail_y = def->h / CUBED_ROOT_2 * sqrt(t); + double t; + + acc->tail_y = 0.0; + if (def->w == def->h) + return; + t = def->l * def->w; + if (def->w > def->h) { + if (t < acc->h2) + return; + } + else { + if (t > acc->h2) + return; + } + t = 2.0 * def->h * t; + t = (CUBED_ROOT_4 * acc->h2 - cbrt(t * t)) / acc->h2mw2; + if (t > 0.0) + acc->tail_y = def->h / CUBED_ROOT_2 * sqrt(t); } /* @@ -2498,73 +2386,49 @@ tailEllipseY ( */ static double -outerXfromXY ( - double x, - double y, - struct arc_def *def, - struct accelerators *acc) +outerXfromXY(double x, double y, struct arc_def *def, struct accelerators *acc) { - return x + (x * acc->h2l) / sqrt (x*x * acc->h4 + y*y * acc->w4); + return x + (x * acc->h2l) / sqrt(x * x * acc->h4 + y * y * acc->w4); } static double -outerYfromXY ( - double x, - double y, - struct arc_def *def, - struct accelerators *acc) +outerYfromXY(double x, double y, struct arc_def *def, struct accelerators *acc) { - return y + (y * acc->w2l) / sqrt (x*x * acc->h4 + y*y * acc->w4); + return y + (y * acc->w2l) / sqrt(x * x * acc->h4 + y * y * acc->w4); } static double -innerXfromXY ( - double x, - double y, - struct arc_def *def, - struct accelerators *acc) +innerXfromXY(double x, double y, struct arc_def *def, struct accelerators *acc) { - return x - (x * acc->h2l) / sqrt (x*x * acc->h4 + y*y * acc->w4); + return x - (x * acc->h2l) / sqrt(x * x * acc->h4 + y * y * acc->w4); } static double -innerYfromXY ( - double x, - double y, - struct arc_def *def, - struct accelerators *acc) +innerYfromXY(double x, double y, struct arc_def *def, struct accelerators *acc) { - return y - (y * acc->w2l) / sqrt (x*x * acc->h4 + y*y * acc->w4); + return y - (y * acc->w2l) / sqrt(x * x * acc->h4 + y * y * acc->w4); } static double -innerYfromY ( - double y, - struct arc_def *def, - struct accelerators *acc) +innerYfromY(double y, struct arc_def *def, struct accelerators *acc) { - double x; + double x; - x = (def->w / def->h) * sqrt (acc->h2 - y*y); + x = (def->w / def->h) * sqrt(acc->h2 - y * y); - return y - (y * acc->w2l) / sqrt (x*x * acc->h4 + y*y * acc->w4); + return y - (y * acc->w2l) / sqrt(x * x * acc->h4 + y * y * acc->w4); } static void -computeLine ( - double x1, - double y1, - double x2, - double y2, - struct line *line) +computeLine(double x1, double y1, double x2, double y2, struct line *line) { - if (y1 == y2) - line->valid = 0; - else { - line->m = (x1 - x2) / (y1 - y2); - line->b = x1 - y1 * line->m; - line->valid = 1; - } + if (y1 == y2) + line->valid = 0; + else { + line->m = (x1 - x2) / (y1 - y2); + line->b = x1 - y1 * line->m; + line->valid = 1; + } } /* @@ -2574,124 +2438,117 @@ computeLine ( */ static void -computeAcc ( - xArc *tarc, - int lw, - struct arc_def *def, - struct accelerators *acc) +computeAcc(xArc * tarc, int lw, struct arc_def *def, struct accelerators *acc) { - def->w = ((double) tarc->width) / 2.0; - def->h = ((double) tarc->height) / 2.0; - def->l = ((double) lw) / 2.0; - acc->h2 = def->h * def->h; - acc->w2 = def->w * def->w; - acc->h4 = acc->h2 * acc->h2; - acc->w4 = acc->w2 * acc->w2; - acc->h2l = acc->h2 * def->l; - acc->w2l = acc->w2 * def->l; - acc->h2mw2 = acc->h2 - acc->w2; - acc->fromIntX = (tarc->width & 1) ? 0.5 : 0.0; - acc->fromIntY = (tarc->height & 1) ? 0.5 : 0.0; - acc->xorg = tarc->x + (tarc->width >> 1); - acc->yorgu = tarc->y + (tarc->height >> 1); - acc->yorgl = acc->yorgu + (tarc->height & 1); - tailEllipseY (def, acc); + def->w = ((double) tarc->width) / 2.0; + def->h = ((double) tarc->height) / 2.0; + def->l = ((double) lw) / 2.0; + acc->h2 = def->h * def->h; + acc->w2 = def->w * def->w; + acc->h4 = acc->h2 * acc->h2; + acc->w4 = acc->w2 * acc->w2; + acc->h2l = acc->h2 * def->l; + acc->w2l = acc->w2 * def->l; + acc->h2mw2 = acc->h2 - acc->w2; + acc->fromIntX = (tarc->width & 1) ? 0.5 : 0.0; + acc->fromIntY = (tarc->height & 1) ? 0.5 : 0.0; + acc->xorg = tarc->x + (tarc->width >> 1); + acc->yorgu = tarc->y + (tarc->height >> 1); + acc->yorgl = acc->yorgu + (tarc->height & 1); + tailEllipseY(def, acc); } - + /* * compute y value bounds of various portions of the arc, * the outer edge, the ellipse and the inner edge. */ static void -computeBound ( - struct arc_def *def, - struct arc_bound *bound, - struct accelerators *acc, - miArcFacePtr right, - miArcFacePtr left) +computeBound(struct arc_def *def, + struct arc_bound *bound, + struct accelerators *acc, miArcFacePtr right, miArcFacePtr left) { - double t; - double innerTaily; - double tail_y; - struct bound innerx, outerx; - struct bound ellipsex; - - bound->ellipse.min = Dsin (def->a0) * def->h; - bound->ellipse.max = Dsin (def->a1) * def->h; - if (def->a0 == 45 && def->w == def->h) - ellipsex.min = bound->ellipse.min; - else - ellipsex.min = Dcos (def->a0) * def->w; - if (def->a1 == 45 && def->w == def->h) - ellipsex.max = bound->ellipse.max; - else - ellipsex.max = Dcos (def->a1) * def->w; - bound->outer.min = outerYfromXY (ellipsex.min, bound->ellipse.min, def, acc); - bound->outer.max = outerYfromXY (ellipsex.max, bound->ellipse.max, def, acc); - bound->inner.min = innerYfromXY (ellipsex.min, bound->ellipse.min, def, acc); - bound->inner.max = innerYfromXY (ellipsex.max, bound->ellipse.max, def, acc); - - outerx.min = outerXfromXY (ellipsex.min, bound->ellipse.min, def, acc); - outerx.max = outerXfromXY (ellipsex.max, bound->ellipse.max, def, acc); - innerx.min = innerXfromXY (ellipsex.min, bound->ellipse.min, def, acc); - innerx.max = innerXfromXY (ellipsex.max, bound->ellipse.max, def, acc); - - /* - * save the line end points for the - * cap code to use. Careful here, these are - * in cartesean coordinates (y increasing upwards) - * while the cap code uses inverted coordinates - * (y increasing downwards) - */ - - if (right) { - right->counterClock.y = bound->outer.min; - right->counterClock.x = outerx.min; - right->center.y = bound->ellipse.min; - right->center.x = ellipsex.min; - right->clock.y = bound->inner.min; - right->clock.x = innerx.min; - } - - if (left) { - left->clock.y = bound->outer.max; - left->clock.x = outerx.max; - left->center.y = bound->ellipse.max; - left->center.x = ellipsex.max; - left->counterClock.y = bound->inner.max; - left->counterClock.x = innerx.max; - } - - bound->left.min = bound->inner.max; - bound->left.max = bound->outer.max; - bound->right.min = bound->inner.min; - bound->right.max = bound->outer.min; - - computeLine (innerx.min, bound->inner.min, outerx.min, bound->outer.min, - &acc->right); - computeLine (innerx.max, bound->inner.max, outerx.max, bound->outer.max, - &acc->left); - - if (bound->inner.min > bound->inner.max) { - t = bound->inner.min; - bound->inner.min = bound->inner.max; - bound->inner.max = t; - } - tail_y = acc->tail_y; - if (tail_y > bound->ellipse.max) - tail_y = bound->ellipse.max; - else if (tail_y < bound->ellipse.min) - tail_y = bound->ellipse.min; - innerTaily = innerYfromY (tail_y, def, acc); - if (bound->inner.min > innerTaily) - bound->inner.min = innerTaily; - if (bound->inner.max < innerTaily) - bound->inner.max = innerTaily; - bound->inneri.min = ICEIL(bound->inner.min - acc->fromIntY); - bound->inneri.max = floor(bound->inner.max - acc->fromIntY); - bound->outeri.min = ICEIL(bound->outer.min - acc->fromIntY); - bound->outeri.max = floor(bound->outer.max - acc->fromIntY); + double t; + double innerTaily; + double tail_y; + struct bound innerx, outerx; + struct bound ellipsex; + + bound->ellipse.min = Dsin(def->a0) * def->h; + bound->ellipse.max = Dsin(def->a1) * def->h; + if (def->a0 == 45 && def->w == def->h) + ellipsex.min = bound->ellipse.min; + else + ellipsex.min = Dcos(def->a0) * def->w; + if (def->a1 == 45 && def->w == def->h) + ellipsex.max = bound->ellipse.max; + else + ellipsex.max = Dcos(def->a1) * def->w; + bound->outer.min = outerYfromXY(ellipsex.min, bound->ellipse.min, def, acc); + bound->outer.max = outerYfromXY(ellipsex.max, bound->ellipse.max, def, acc); + bound->inner.min = innerYfromXY(ellipsex.min, bound->ellipse.min, def, acc); + bound->inner.max = innerYfromXY(ellipsex.max, bound->ellipse.max, def, acc); + + outerx.min = outerXfromXY(ellipsex.min, bound->ellipse.min, def, acc); + outerx.max = outerXfromXY(ellipsex.max, bound->ellipse.max, def, acc); + innerx.min = innerXfromXY(ellipsex.min, bound->ellipse.min, def, acc); + innerx.max = innerXfromXY(ellipsex.max, bound->ellipse.max, def, acc); + + /* + * save the line end points for the + * cap code to use. Careful here, these are + * in cartesean coordinates (y increasing upwards) + * while the cap code uses inverted coordinates + * (y increasing downwards) + */ + + if (right) { + right->counterClock.y = bound->outer.min; + right->counterClock.x = outerx.min; + right->center.y = bound->ellipse.min; + right->center.x = ellipsex.min; + right->clock.y = bound->inner.min; + right->clock.x = innerx.min; + } + + if (left) { + left->clock.y = bound->outer.max; + left->clock.x = outerx.max; + left->center.y = bound->ellipse.max; + left->center.x = ellipsex.max; + left->counterClock.y = bound->inner.max; + left->counterClock.x = innerx.max; + } + + bound->left.min = bound->inner.max; + bound->left.max = bound->outer.max; + bound->right.min = bound->inner.min; + bound->right.max = bound->outer.min; + + computeLine(innerx.min, bound->inner.min, outerx.min, bound->outer.min, + &acc->right); + computeLine(innerx.max, bound->inner.max, outerx.max, bound->outer.max, + &acc->left); + + if (bound->inner.min > bound->inner.max) { + t = bound->inner.min; + bound->inner.min = bound->inner.max; + bound->inner.max = t; + } + tail_y = acc->tail_y; + if (tail_y > bound->ellipse.max) + tail_y = bound->ellipse.max; + else if (tail_y < bound->ellipse.min) + tail_y = bound->ellipse.min; + innerTaily = innerYfromY(tail_y, def, acc); + if (bound->inner.min > innerTaily) + bound->inner.min = innerTaily; + if (bound->inner.max < innerTaily) + bound->inner.max = innerTaily; + bound->inneri.min = ICEIL(bound->inner.min - acc->fromIntY); + bound->inneri.max = floor(bound->inner.max - acc->fromIntY); + bound->outeri.min = ICEIL(bound->outer.min - acc->fromIntY); + bound->outeri.max = floor(bound->outer.max - acc->fromIntY); } /* @@ -2745,24 +2602,21 @@ computeBound ( */ static double -hookEllipseY ( - double scan_y, - struct arc_bound *bound, - struct accelerators *acc, - int left) +hookEllipseY(double scan_y, + struct arc_bound *bound, struct accelerators *acc, int left) { - double ret; - - if (acc->h2mw2 == 0) { - if ( (scan_y > 0 && !left) || (scan_y < 0 && left) ) - return bound->ellipse.min; - return bound->ellipse.max; - } - ret = (acc->h4 * scan_y) / (acc->h2mw2); - if (ret >= 0) - return cbrt (ret); - else - return -cbrt (-ret); + double ret; + + if (acc->h2mw2 == 0) { + if ((scan_y > 0 && !left) || (scan_y < 0 && left)) + return bound->ellipse.min; + return bound->ellipse.max; + } + ret = (acc->h4 * scan_y) / (acc->h2mw2); + if (ret >= 0) + return cbrt(ret); + else + return -cbrt(-ret); } /* @@ -2771,55 +2625,55 @@ hookEllipseY ( */ static double -hookX ( - double scan_y, - struct arc_def *def, - struct arc_bound *bound, - struct accelerators *acc, - int left) +hookX(double scan_y, + struct arc_def *def, + struct arc_bound *bound, struct accelerators *acc, int left) { - double ellipse_y, x; - double maxMin; - - if (def->w != def->h) { - ellipse_y = hookEllipseY (scan_y, bound, acc, left); - if (boundedLe (ellipse_y, bound->ellipse)) { - /* - * compute the value of the second - * derivative - */ - maxMin = ellipse_y*ellipse_y*ellipse_y * acc->h2mw2 - - acc->h2 * scan_y * (3 * ellipse_y*ellipse_y - 2*acc->h2); - if ((left && maxMin > 0) || (!left && maxMin < 0)) { - if (ellipse_y == 0) - return def->w + left ? -def->l : def->l; - x = (acc->h2 * scan_y - ellipse_y * acc->h2mw2) * - sqrt (acc->h2 - ellipse_y * ellipse_y) / - (def->h * def->w * ellipse_y); - return x; - } - } - } - if (left) { - if (acc->left.valid && boundedLe (scan_y, bound->left)) { - x = intersectLine (scan_y, acc->left); - } else { - if (acc->right.valid) - x = intersectLine (scan_y, acc->right); - else - x = def->w - def->l; - } - } else { - if (acc->right.valid && boundedLe (scan_y, bound->right)) { - x = intersectLine (scan_y, acc->right); - } else { - if (acc->left.valid) - x = intersectLine (scan_y, acc->left); - else - x = def->w - def->l; - } - } - return x; + double ellipse_y, x; + double maxMin; + + if (def->w != def->h) { + ellipse_y = hookEllipseY(scan_y, bound, acc, left); + if (boundedLe(ellipse_y, bound->ellipse)) { + /* + * compute the value of the second + * derivative + */ + maxMin = ellipse_y * ellipse_y * ellipse_y * acc->h2mw2 - + acc->h2 * scan_y * (3 * ellipse_y * ellipse_y - 2 * acc->h2); + if ((left && maxMin > 0) || (!left && maxMin < 0)) { + if (ellipse_y == 0) + return def->w + left ? -def->l : def->l; + x = (acc->h2 * scan_y - ellipse_y * acc->h2mw2) * + sqrt(acc->h2 - ellipse_y * ellipse_y) / + (def->h * def->w * ellipse_y); + return x; + } + } + } + if (left) { + if (acc->left.valid && boundedLe(scan_y, bound->left)) { + x = intersectLine(scan_y, acc->left); + } + else { + if (acc->right.valid) + x = intersectLine(scan_y, acc->right); + else + x = def->w - def->l; + } + } + else { + if (acc->right.valid && boundedLe(scan_y, bound->right)) { + x = intersectLine(scan_y, acc->right); + } + else { + if (acc->left.valid) + x = intersectLine(scan_y, acc->left); + else + x = def->w - def->l; + } + } + return x; } /* @@ -2828,152 +2682,130 @@ hookX ( */ static void -arcSpan ( - int y, - int lx, - int lw, - int rx, - int rw, - struct arc_def *def, - struct arc_bound *bounds, - struct accelerators *acc, - int mask) +arcSpan(int y, + int lx, + int lw, + int rx, + int rw, + struct arc_def *def, + struct arc_bound *bounds, struct accelerators *acc, int mask) { - int linx, loutx, rinx, routx; - double x, altx; - - if (boundedLe (y, bounds->inneri)) { - linx = -(lx + lw); - rinx = rx; - } else { - /* - * intersection with left face - */ - x = hookX (y + acc->fromIntY, def, bounds, acc, 1); - if (acc->right.valid && - boundedLe (y + acc->fromIntY, bounds->right)) - { - altx = intersectLine (y + acc->fromIntY, acc->right); - if (altx < x) - x = altx; - } - linx = -ICEIL(acc->fromIntX - x); - rinx = ICEIL(acc->fromIntX + x); - } - if (boundedLe (y, bounds->outeri)) { - loutx = -lx; - routx = rx + rw; - } else { - /* - * intersection with right face - */ - x = hookX (y + acc->fromIntY, def, bounds, acc, 0); - if (acc->left.valid && - boundedLe (y + acc->fromIntY, bounds->left)) - { - altx = x; - x = intersectLine (y + acc->fromIntY, acc->left); - if (x < altx) - x = altx; - } - loutx = -ICEIL(acc->fromIntX - x); - routx = ICEIL(acc->fromIntX + x); - } - if (routx > rinx) { - if (mask & 1) - newFinalSpan (acc->yorgu - y, - acc->xorg + rinx, acc->xorg + routx); - if (mask & 8) - newFinalSpan (acc->yorgl + y, - acc->xorg + rinx, acc->xorg + routx); - } - if (loutx > linx) { - if (mask & 2) - newFinalSpan (acc->yorgu - y, - acc->xorg - loutx, acc->xorg - linx); - if (mask & 4) - newFinalSpan (acc->yorgl + y, - acc->xorg - loutx, acc->xorg - linx); - } + int linx, loutx, rinx, routx; + double x, altx; + + if (boundedLe(y, bounds->inneri)) { + linx = -(lx + lw); + rinx = rx; + } + else { + /* + * intersection with left face + */ + x = hookX(y + acc->fromIntY, def, bounds, acc, 1); + if (acc->right.valid && boundedLe(y + acc->fromIntY, bounds->right)) { + altx = intersectLine(y + acc->fromIntY, acc->right); + if (altx < x) + x = altx; + } + linx = -ICEIL(acc->fromIntX - x); + rinx = ICEIL(acc->fromIntX + x); + } + if (boundedLe(y, bounds->outeri)) { + loutx = -lx; + routx = rx + rw; + } + else { + /* + * intersection with right face + */ + x = hookX(y + acc->fromIntY, def, bounds, acc, 0); + if (acc->left.valid && boundedLe(y + acc->fromIntY, bounds->left)) { + altx = x; + x = intersectLine(y + acc->fromIntY, acc->left); + if (x < altx) + x = altx; + } + loutx = -ICEIL(acc->fromIntX - x); + routx = ICEIL(acc->fromIntX + x); + } + if (routx > rinx) { + if (mask & 1) + newFinalSpan(acc->yorgu - y, acc->xorg + rinx, acc->xorg + routx); + if (mask & 8) + newFinalSpan(acc->yorgl + y, acc->xorg + rinx, acc->xorg + routx); + } + if (loutx > linx) { + if (mask & 2) + newFinalSpan(acc->yorgu - y, acc->xorg - loutx, acc->xorg - linx); + if (mask & 4) + newFinalSpan(acc->yorgl + y, acc->xorg - loutx, acc->xorg - linx); + } } static void -arcSpan0 ( - int lx, - int lw, - int rx, - int rw, - struct arc_def *def, - struct arc_bound *bounds, - struct accelerators *acc, - int mask) +arcSpan0(int lx, + int lw, + int rx, + int rw, + struct arc_def *def, + struct arc_bound *bounds, struct accelerators *acc, int mask) { double x; - if (boundedLe (0, bounds->inneri) && - acc->left.valid && boundedLe (0, bounds->left) && - acc->left.b > 0) - { - x = def->w - def->l; - if (acc->left.b < x) - x = acc->left.b; - lw = ICEIL(acc->fromIntX - x) - lx; - rw += rx; - rx = ICEIL(acc->fromIntX + x); - rw -= rx; - } - arcSpan (0, lx, lw, rx, rw, def, bounds, acc, mask); + if (boundedLe(0, bounds->inneri) && + acc->left.valid && boundedLe(0, bounds->left) && acc->left.b > 0) { + x = def->w - def->l; + if (acc->left.b < x) + x = acc->left.b; + lw = ICEIL(acc->fromIntX - x) - lx; + rw += rx; + rx = ICEIL(acc->fromIntX + x); + rw -= rx; + } + arcSpan(0, lx, lw, rx, rw, def, bounds, acc, mask); } static void -tailSpan ( - int y, - int lw, - int rw, - struct arc_def *def, - struct arc_bound *bounds, - struct accelerators *acc, - int mask) +tailSpan(int y, + int lw, + int rw, + struct arc_def *def, + struct arc_bound *bounds, struct accelerators *acc, int mask) { double yy, xalt, x, lx, rx; int n; if (boundedLe(y, bounds->outeri)) - arcSpan (y, 0, lw, -rw, rw, def, bounds, acc, mask); + arcSpan(y, 0, lw, -rw, rw, def, bounds, acc, mask); else if (def->w != def->h) { - yy = y + acc->fromIntY; - x = tailX(yy, def, bounds, acc); - if (yy == 0.0 && x == -rw - acc->fromIntX) - return; - if (acc->right.valid && boundedLe (yy, bounds->right)) { - rx = x; - lx = -x; - xalt = intersectLine (yy, acc->right); - if (xalt >= -rw - acc->fromIntX && xalt <= rx) - rx = xalt; - n = ICEIL(acc->fromIntX + lx); - if (lw > n) { - if (mask & 2) - newFinalSpan (acc->yorgu - y, - acc->xorg + n, acc->xorg + lw); - if (mask & 4) - newFinalSpan (acc->yorgl + y, - acc->xorg + n, acc->xorg + lw); - } - n = ICEIL(acc->fromIntX + rx); - if (n > -rw) { - if (mask & 1) - newFinalSpan (acc->yorgu - y, - acc->xorg - rw, acc->xorg + n); - if (mask & 8) - newFinalSpan (acc->yorgl + y, - acc->xorg - rw, acc->xorg + n); - } - } - arcSpan (y, - ICEIL(acc->fromIntX - x), 0, - ICEIL(acc->fromIntX + x), 0, - def, bounds, acc, mask); + yy = y + acc->fromIntY; + x = tailX(yy, def, bounds, acc); + if (yy == 0.0 && x == -rw - acc->fromIntX) + return; + if (acc->right.valid && boundedLe(yy, bounds->right)) { + rx = x; + lx = -x; + xalt = intersectLine(yy, acc->right); + if (xalt >= -rw - acc->fromIntX && xalt <= rx) + rx = xalt; + n = ICEIL(acc->fromIntX + lx); + if (lw > n) { + if (mask & 2) + newFinalSpan(acc->yorgu - y, acc->xorg + n, acc->xorg + lw); + if (mask & 4) + newFinalSpan(acc->yorgl + y, acc->xorg + n, acc->xorg + lw); + } + n = ICEIL(acc->fromIntX + rx); + if (n > -rw) { + if (mask & 1) + newFinalSpan(acc->yorgu - y, acc->xorg - rw, acc->xorg + n); + if (mask & 8) + newFinalSpan(acc->yorgl + y, acc->xorg - rw, acc->xorg + n); + } + } + arcSpan(y, + ICEIL(acc->fromIntX - x), 0, + ICEIL(acc->fromIntX + x), 0, def, bounds, acc, mask); } } @@ -2982,254 +2814,247 @@ tailSpan ( * very bad. */ -static struct finalSpan **finalSpans = NULL; -static int finalMiny = 0, finalMaxy = -1; -static int finalSize = 0; +static struct finalSpan **finalSpans = NULL; +static int finalMiny = 0, finalMaxy = -1; +static int finalSize = 0; -static int nspans = 0; /* total spans, not just y coords */ +static int nspans = 0; /* total spans, not just y coords */ struct finalSpan { - struct finalSpan *next; - int min, max; /* x values */ + struct finalSpan *next; + int min, max; /* x values */ }; -static struct finalSpan *freeFinalSpans, *tmpFinalSpan; +static struct finalSpan *freeFinalSpans, *tmpFinalSpan; -# define allocFinalSpan() (freeFinalSpans ?\ +#define allocFinalSpan() (freeFinalSpans ?\ ((tmpFinalSpan = freeFinalSpans), \ (freeFinalSpans = freeFinalSpans->next), \ (tmpFinalSpan->next = 0), \ tmpFinalSpan) : \ realAllocSpan ()) -# define SPAN_CHUNK_SIZE 128 +#define SPAN_CHUNK_SIZE 128 struct finalSpanChunk { - struct finalSpan data[SPAN_CHUNK_SIZE]; - struct finalSpanChunk *next; + struct finalSpan data[SPAN_CHUNK_SIZE]; + struct finalSpanChunk *next; }; -static struct finalSpanChunk *chunks; +static struct finalSpanChunk *chunks; static struct finalSpan * -realAllocSpan (void) +realAllocSpan(void) { - struct finalSpanChunk *newChunk; - struct finalSpan *span; - int i; - - newChunk = malloc(sizeof (struct finalSpanChunk)); - if (!newChunk) - return (struct finalSpan *) NULL; - newChunk->next = chunks; - chunks = newChunk; - freeFinalSpans = span = newChunk->data + 1; - for (i = 1; i < SPAN_CHUNK_SIZE-1; i++) { - span->next = span+1; - span++; - } - span->next = 0; - span = newChunk->data; - span->next = 0; - return span; + struct finalSpanChunk *newChunk; + struct finalSpan *span; + int i; + + newChunk = malloc(sizeof(struct finalSpanChunk)); + if (!newChunk) + return (struct finalSpan *) NULL; + newChunk->next = chunks; + chunks = newChunk; + freeFinalSpans = span = newChunk->data + 1; + for (i = 1; i < SPAN_CHUNK_SIZE - 1; i++) { + span->next = span + 1; + span++; + } + span->next = 0; + span = newChunk->data; + span->next = 0; + return span; } static void -disposeFinalSpans (void) +disposeFinalSpans(void) { - struct finalSpanChunk *chunk, *next; - - for (chunk = chunks; chunk; chunk = next) { - next = chunk->next; - free(chunk); - } - chunks = 0; - freeFinalSpans = 0; - free(finalSpans); - finalSpans = 0; + struct finalSpanChunk *chunk, *next; + + for (chunk = chunks; chunk; chunk = next) { + next = chunk->next; + free(chunk); + } + chunks = 0; + freeFinalSpans = 0; + free(finalSpans); + finalSpans = 0; } static void -fillSpans ( - DrawablePtr pDrawable, - GCPtr pGC) +fillSpans(DrawablePtr pDrawable, GCPtr pGC) { - struct finalSpan *span; - DDXPointPtr xSpan; - int *xWidth; - int i; - struct finalSpan **f; - int spany; - DDXPointPtr xSpans; - int *xWidths; - - if (nspans == 0) - return; - xSpan = xSpans = malloc(nspans * sizeof (DDXPointRec)); - xWidth = xWidths = malloc(nspans * sizeof (int)); - if (xSpans && xWidths) - { - i = 0; - f = finalSpans; - for (spany = finalMiny; spany <= finalMaxy; spany++, f++) { - for (span = *f; span; span=span->next) { - if (span->max <= span->min) - continue; - xSpan->x = span->min; - xSpan->y = spany; - ++xSpan; - *xWidth++ = span->max - span->min; - ++i; - } - } - (*pGC->ops->FillSpans) (pDrawable, pGC, i, xSpans, xWidths, TRUE); - } - disposeFinalSpans (); - free(xSpans); - free(xWidths); - finalMiny = 0; - finalMaxy = -1; - finalSize = 0; - nspans = 0; + struct finalSpan *span; + DDXPointPtr xSpan; + int *xWidth; + int i; + struct finalSpan **f; + int spany; + DDXPointPtr xSpans; + int *xWidths; + + if (nspans == 0) + return; + xSpan = xSpans = malloc(nspans * sizeof(DDXPointRec)); + xWidth = xWidths = malloc(nspans * sizeof(int)); + if (xSpans && xWidths) { + i = 0; + f = finalSpans; + for (spany = finalMiny; spany <= finalMaxy; spany++, f++) { + for (span = *f; span; span = span->next) { + if (span->max <= span->min) + continue; + xSpan->x = span->min; + xSpan->y = spany; + ++xSpan; + *xWidth++ = span->max - span->min; + ++i; + } + } + (*pGC->ops->FillSpans) (pDrawable, pGC, i, xSpans, xWidths, TRUE); + } + disposeFinalSpans(); + free(xSpans); + free(xWidths); + finalMiny = 0; + finalMaxy = -1; + finalSize = 0; + nspans = 0; } -# define SPAN_REALLOC 100 +#define SPAN_REALLOC 100 -# define findSpan(y) ((finalMiny <= (y) && (y) <= finalMaxy) ? \ +#define findSpan(y) ((finalMiny <= (y) && (y) <= finalMaxy) ? \ &finalSpans[(y) - finalMiny] : \ realFindSpan (y)) static struct finalSpan ** -realFindSpan (int y) +realFindSpan(int y) { - struct finalSpan **newSpans; - int newSize, newMiny, newMaxy; - int change; - int i; - - if (y < finalMiny || y > finalMaxy) { - if (!finalSize) { - finalMiny = y; - finalMaxy = y - 1; - } - if (y < finalMiny) - change = finalMiny - y; - else - change = y - finalMaxy; - if (change >= SPAN_REALLOC) - change += SPAN_REALLOC; - else - change = SPAN_REALLOC; - newSize = finalSize + change; - newSpans = malloc(newSize * sizeof (struct finalSpan *)); - if (!newSpans) - return NULL; - newMiny = finalMiny; - newMaxy = finalMaxy; - if (y < finalMiny) - newMiny = finalMiny - change; - else - newMaxy = finalMaxy + change; - if (finalSpans) { - memmove(((char *) newSpans) + (finalMiny-newMiny) * sizeof (struct finalSpan *), - (char *) finalSpans, - finalSize * sizeof (struct finalSpan *)); - free(finalSpans); - } - if ((i = finalMiny - newMiny) > 0) - memset((char *)newSpans, 0, i * sizeof (struct finalSpan *)); - if ((i = newMaxy - finalMaxy) > 0) - memset((char *)(newSpans + newSize - i), 0, - i * sizeof (struct finalSpan *)); - finalSpans = newSpans; - finalMaxy = newMaxy; - finalMiny = newMiny; - finalSize = newSize; - } - return &finalSpans[y - finalMiny]; + struct finalSpan **newSpans; + int newSize, newMiny, newMaxy; + int change; + int i; + + if (y < finalMiny || y > finalMaxy) { + if (!finalSize) { + finalMiny = y; + finalMaxy = y - 1; + } + if (y < finalMiny) + change = finalMiny - y; + else + change = y - finalMaxy; + if (change >= SPAN_REALLOC) + change += SPAN_REALLOC; + else + change = SPAN_REALLOC; + newSize = finalSize + change; + newSpans = malloc(newSize * sizeof(struct finalSpan *)); + if (!newSpans) + return NULL; + newMiny = finalMiny; + newMaxy = finalMaxy; + if (y < finalMiny) + newMiny = finalMiny - change; + else + newMaxy = finalMaxy + change; + if (finalSpans) { + memmove(((char *) newSpans) + + (finalMiny - newMiny) * sizeof(struct finalSpan *), + (char *) finalSpans, + finalSize * sizeof(struct finalSpan *)); + free(finalSpans); + } + if ((i = finalMiny - newMiny) > 0) + memset((char *) newSpans, 0, i * sizeof(struct finalSpan *)); + if ((i = newMaxy - finalMaxy) > 0) + memset((char *) (newSpans + newSize - i), 0, + i * sizeof(struct finalSpan *)); + finalSpans = newSpans; + finalMaxy = newMaxy; + finalMiny = newMiny; + finalSize = newSize; + } + return &finalSpans[y - finalMiny]; } static void -newFinalSpan ( - int y, - int xmin, - int xmax) +newFinalSpan(int y, int xmin, int xmax) { - struct finalSpan *x; - struct finalSpan **f; - struct finalSpan *oldx; - struct finalSpan *prev; - - f = findSpan (y); - if (!f) - return; - oldx = 0; - for (;;) { - prev = 0; - for (x = *f; x; x=x->next) { - if (x == oldx) { - prev = x; - continue; - } - if (x->min <= xmax && xmin <= x->max) { - if (oldx) { - oldx->min = min (x->min, xmin); - oldx->max = max (x->max, xmax); - if (prev) - prev->next = x->next; - else - *f = x->next; - --nspans; - } else { - x->min = min (x->min, xmin); - x->max = max (x->max, xmax); - oldx = x; - } - xmin = oldx->min; - xmax = oldx->max; - break; - } - prev = x; - } - if (!x) - break; - } - if (!oldx) { - x = allocFinalSpan (); - if (x) - { - x->min = xmin; - x->max = xmax; - x->next = *f; - *f = x; - ++nspans; - } - } + struct finalSpan *x; + struct finalSpan **f; + struct finalSpan *oldx; + struct finalSpan *prev; + + f = findSpan(y); + if (!f) + return; + oldx = 0; + for (;;) { + prev = 0; + for (x = *f; x; x = x->next) { + if (x == oldx) { + prev = x; + continue; + } + if (x->min <= xmax && xmin <= x->max) { + if (oldx) { + oldx->min = min(x->min, xmin); + oldx->max = max(x->max, xmax); + if (prev) + prev->next = x->next; + else + *f = x->next; + --nspans; + } + else { + x->min = min(x->min, xmin); + x->max = max(x->max, xmax); + oldx = x; + } + xmin = oldx->min; + xmax = oldx->max; + break; + } + prev = x; + } + if (!x) + break; + } + if (!oldx) { + x = allocFinalSpan(); + if (x) { + x->min = xmin; + x->max = xmax; + x->next = *f; + *f = x; + ++nspans; + } + } } static void -mirrorSppPoint ( - int quadrant, - SppPointPtr sppPoint) +mirrorSppPoint(int quadrant, SppPointPtr sppPoint) { - switch (quadrant) { - case 0: - break; - case 1: - sppPoint->x = -sppPoint->x; - break; - case 2: - sppPoint->x = -sppPoint->x; - sppPoint->y = -sppPoint->y; - break; - case 3: - sppPoint->y = -sppPoint->y; - break; - } - /* - * and translate to X coordinate system - */ - sppPoint->y = -sppPoint->y; + switch (quadrant) { + case 0: + break; + case 1: + sppPoint->x = -sppPoint->x; + break; + case 2: + sppPoint->x = -sppPoint->x; + sppPoint->y = -sppPoint->y; + break; + case 3: + sppPoint->y = -sppPoint->y; + break; + } + /* + * and translate to X coordinate system + */ + sppPoint->y = -sppPoint->y; } /* @@ -3241,350 +3066,337 @@ mirrorSppPoint ( */ static void -drawArc ( - xArc *tarc, - int l, - int a0, - int a1, - miArcFacePtr right, - miArcFacePtr left) /* save end line points */ -{ - struct arc_def def; - struct accelerators acc; - int startq, endq, curq; - int rightq, leftq = 0, righta = 0, lefta = 0; - miArcFacePtr passRight, passLeft; - int q0 = 0, q1 = 0, mask; - struct band { - int a0, a1; - int mask; - } band[5], sweep[20]; - int bandno, sweepno; - int i, j; - int flipRight = 0, flipLeft = 0; - int copyEnd = 0; - miArcSpanData *spdata; - - spdata = miComputeWideEllipse(l, tarc); - if (!spdata) - return; - - if (a1 < a0) - a1 += 360 * 64; - startq = a0 / (90 * 64); - if (a0 == a1) - endq = startq; - else - endq = (a1-1) / (90 * 64); - bandno = 0; - curq = startq; - rightq = -1; - for (;;) { - switch (curq) { - case 0: - if (a0 > 90 * 64) - q0 = 0; - else - q0 = a0; - if (a1 < 360 * 64) - q1 = min (a1, 90 * 64); - else - q1 = 90 * 64; - if (curq == startq && a0 == q0 && rightq < 0) { - righta = q0; - rightq = curq; - } - if (curq == endq && a1 == q1) { - lefta = q1; - leftq = curq; - } - break; - case 1: - if (a1 < 90 * 64) - q0 = 0; - else - q0 = 180 * 64 - min (a1, 180 * 64); - if (a0 > 180 * 64) - q1 = 90 * 64; - else - q1 = 180 * 64 - max (a0, 90 * 64); - if (curq == startq && 180 * 64 - a0 == q1) { - righta = q1; - rightq = curq; - } - if (curq == endq && 180 * 64 - a1 == q0) { - lefta = q0; - leftq = curq; - } - break; - case 2: - if (a0 > 270 * 64) - q0 = 0; - else - q0 = max (a0, 180 * 64) - 180 * 64; - if (a1 < 180 * 64) - q1 = 90 * 64; - else - q1 = min (a1, 270 * 64) - 180 * 64; - if (curq == startq && a0 - 180*64 == q0) { - righta = q0; - rightq = curq; - } - if (curq == endq && a1 - 180 * 64 == q1) { - lefta = q1; - leftq = curq; - } - break; - case 3: - if (a1 < 270 * 64) - q0 = 0; - else - q0 = 360 * 64 - min (a1, 360 * 64); - q1 = 360 * 64 - max (a0, 270 * 64); - if (curq == startq && 360 * 64 - a0 == q1) { - righta = q1; - rightq = curq; - } - if (curq == endq && 360 * 64 - a1 == q0) { - lefta = q0; - leftq = curq; - } - break; - } - band[bandno].a0 = q0; - band[bandno].a1 = q1; - band[bandno].mask = 1 << curq; - bandno++; - if (curq == endq) - break; - curq++; - if (curq == 4) { - a0 = 0; - a1 -= 360 * 64; - curq = 0; - endq -= 4; - } - } - sweepno = 0; - for (;;) { - q0 = 90 * 64; - mask = 0; - /* - * find left-most point - */ - for (i = 0; i < bandno; i++) - if (band[i].a0 <= q0) { - q0 = band[i].a0; - q1 = band[i].a1; - mask = band[i].mask; - } - if (!mask) - break; - /* - * locate next point of change - */ - for (i = 0; i < bandno; i++) - if (!(mask & band[i].mask)) { - if (band[i].a0 == q0) { - if (band[i].a1 < q1) - q1 = band[i].a1; - mask |= band[i].mask; - } else if (band[i].a0 < q1) - q1 = band[i].a0; - } - /* - * create a new sweep - */ - sweep[sweepno].a0 = q0; - sweep[sweepno].a1 = q1; - sweep[sweepno].mask = mask; - sweepno++; - /* - * subtract the sweep from the affected bands - */ - for (i = 0; i < bandno; i++) - if (band[i].a0 == q0) { - band[i].a0 = q1; - /* - * check if this band is empty - */ - if (band[i].a0 == band[i].a1) - band[i].a1 = band[i].a0 = 90 * 64 + 1; - } - } - computeAcc (tarc, l, &def, &acc); - for (j = 0; j < sweepno; j++) { - mask = sweep[j].mask; - passRight = passLeft = 0; - if (mask & (1 << rightq)) { - if (sweep[j].a0 == righta) - passRight = right; - else if (sweep[j].a1 == righta) { - passLeft = right; - flipRight = 1; - } - } - if (mask & (1 << leftq)) { - if (sweep[j].a1 == lefta) - { - if (passLeft) - copyEnd = 1; - passLeft = left; - } - else if (sweep[j].a0 == lefta) { - if (passRight) - copyEnd = 1; - passRight = left; - flipLeft = 1; - } - } - drawQuadrant (&def, &acc, sweep[j].a0, sweep[j].a1, mask, - passRight, passLeft, spdata); - } - /* - * when copyEnd is set, both ends of the arc were computed - * at the same time; drawQuadrant only takes one end though, - * so the left end will be the only one holding the data. Copy - * it from there. - */ - if (copyEnd) - *right = *left; - /* - * mirror the coordinates generated for the - * faces of the arc - */ - if (right) { - mirrorSppPoint (rightq, &right->clock); - mirrorSppPoint (rightq, &right->center); - mirrorSppPoint (rightq, &right->counterClock); - if (flipRight) { - SppPointRec temp; - - temp = right->clock; - right->clock = right->counterClock; - right->counterClock = temp; - } - } - if (left) { - mirrorSppPoint (leftq, &left->counterClock); - mirrorSppPoint (leftq, &left->center); - mirrorSppPoint (leftq, &left->clock); - if (flipLeft) { - SppPointRec temp; - - temp = left->clock; - left->clock = left->counterClock; - left->counterClock = temp; - } - } - free(spdata); +drawArc(xArc * tarc, + int l, int a0, int a1, miArcFacePtr right, miArcFacePtr left) +{ /* save end line points */ + struct arc_def def; + struct accelerators acc; + int startq, endq, curq; + int rightq, leftq = 0, righta = 0, lefta = 0; + miArcFacePtr passRight, passLeft; + int q0 = 0, q1 = 0, mask; + struct band { + int a0, a1; + int mask; + } band[5], sweep[20]; + int bandno, sweepno; + int i, j; + int flipRight = 0, flipLeft = 0; + int copyEnd = 0; + miArcSpanData *spdata; + + spdata = miComputeWideEllipse(l, tarc); + if (!spdata) + return; + + if (a1 < a0) + a1 += 360 * 64; + startq = a0 / (90 * 64); + if (a0 == a1) + endq = startq; + else + endq = (a1 - 1) / (90 * 64); + bandno = 0; + curq = startq; + rightq = -1; + for (;;) { + switch (curq) { + case 0: + if (a0 > 90 * 64) + q0 = 0; + else + q0 = a0; + if (a1 < 360 * 64) + q1 = min(a1, 90 * 64); + else + q1 = 90 * 64; + if (curq == startq && a0 == q0 && rightq < 0) { + righta = q0; + rightq = curq; + } + if (curq == endq && a1 == q1) { + lefta = q1; + leftq = curq; + } + break; + case 1: + if (a1 < 90 * 64) + q0 = 0; + else + q0 = 180 * 64 - min(a1, 180 * 64); + if (a0 > 180 * 64) + q1 = 90 * 64; + else + q1 = 180 * 64 - max(a0, 90 * 64); + if (curq == startq && 180 * 64 - a0 == q1) { + righta = q1; + rightq = curq; + } + if (curq == endq && 180 * 64 - a1 == q0) { + lefta = q0; + leftq = curq; + } + break; + case 2: + if (a0 > 270 * 64) + q0 = 0; + else + q0 = max(a0, 180 * 64) - 180 * 64; + if (a1 < 180 * 64) + q1 = 90 * 64; + else + q1 = min(a1, 270 * 64) - 180 * 64; + if (curq == startq && a0 - 180 * 64 == q0) { + righta = q0; + rightq = curq; + } + if (curq == endq && a1 - 180 * 64 == q1) { + lefta = q1; + leftq = curq; + } + break; + case 3: + if (a1 < 270 * 64) + q0 = 0; + else + q0 = 360 * 64 - min(a1, 360 * 64); + q1 = 360 * 64 - max(a0, 270 * 64); + if (curq == startq && 360 * 64 - a0 == q1) { + righta = q1; + rightq = curq; + } + if (curq == endq && 360 * 64 - a1 == q0) { + lefta = q0; + leftq = curq; + } + break; + } + band[bandno].a0 = q0; + band[bandno].a1 = q1; + band[bandno].mask = 1 << curq; + bandno++; + if (curq == endq) + break; + curq++; + if (curq == 4) { + a0 = 0; + a1 -= 360 * 64; + curq = 0; + endq -= 4; + } + } + sweepno = 0; + for (;;) { + q0 = 90 * 64; + mask = 0; + /* + * find left-most point + */ + for (i = 0; i < bandno; i++) + if (band[i].a0 <= q0) { + q0 = band[i].a0; + q1 = band[i].a1; + mask = band[i].mask; + } + if (!mask) + break; + /* + * locate next point of change + */ + for (i = 0; i < bandno; i++) + if (!(mask & band[i].mask)) { + if (band[i].a0 == q0) { + if (band[i].a1 < q1) + q1 = band[i].a1; + mask |= band[i].mask; + } + else if (band[i].a0 < q1) + q1 = band[i].a0; + } + /* + * create a new sweep + */ + sweep[sweepno].a0 = q0; + sweep[sweepno].a1 = q1; + sweep[sweepno].mask = mask; + sweepno++; + /* + * subtract the sweep from the affected bands + */ + for (i = 0; i < bandno; i++) + if (band[i].a0 == q0) { + band[i].a0 = q1; + /* + * check if this band is empty + */ + if (band[i].a0 == band[i].a1) + band[i].a1 = band[i].a0 = 90 * 64 + 1; + } + } + computeAcc(tarc, l, &def, &acc); + for (j = 0; j < sweepno; j++) { + mask = sweep[j].mask; + passRight = passLeft = 0; + if (mask & (1 << rightq)) { + if (sweep[j].a0 == righta) + passRight = right; + else if (sweep[j].a1 == righta) { + passLeft = right; + flipRight = 1; + } + } + if (mask & (1 << leftq)) { + if (sweep[j].a1 == lefta) { + if (passLeft) + copyEnd = 1; + passLeft = left; + } + else if (sweep[j].a0 == lefta) { + if (passRight) + copyEnd = 1; + passRight = left; + flipLeft = 1; + } + } + drawQuadrant(&def, &acc, sweep[j].a0, sweep[j].a1, mask, + passRight, passLeft, spdata); + } + /* + * when copyEnd is set, both ends of the arc were computed + * at the same time; drawQuadrant only takes one end though, + * so the left end will be the only one holding the data. Copy + * it from there. + */ + if (copyEnd) + *right = *left; + /* + * mirror the coordinates generated for the + * faces of the arc + */ + if (right) { + mirrorSppPoint(rightq, &right->clock); + mirrorSppPoint(rightq, &right->center); + mirrorSppPoint(rightq, &right->counterClock); + if (flipRight) { + SppPointRec temp; + + temp = right->clock; + right->clock = right->counterClock; + right->counterClock = temp; + } + } + if (left) { + mirrorSppPoint(leftq, &left->counterClock); + mirrorSppPoint(leftq, &left->center); + mirrorSppPoint(leftq, &left->clock); + if (flipLeft) { + SppPointRec temp; + + temp = left->clock; + left->clock = left->counterClock; + left->counterClock = temp; + } + } + free(spdata); } static void -drawQuadrant ( - struct arc_def *def, - struct accelerators *acc, - int a0, - int a1, - int mask, - miArcFacePtr right, - miArcFacePtr left, - miArcSpanData *spdata) +drawQuadrant(struct arc_def *def, + struct accelerators *acc, + int a0, + int a1, + int mask, + miArcFacePtr right, miArcFacePtr left, miArcSpanData * spdata) { - struct arc_bound bound; - double yy, x, xalt; - int y, miny, maxy; - int n; - miArcSpan *span; - - def->a0 = ((double) a0) / 64.0; - def->a1 = ((double) a1) / 64.0; - computeBound (def, &bound, acc, right, left); - yy = bound.inner.min; - if (bound.outer.min < yy) - yy = bound.outer.min; - miny = ICEIL(yy - acc->fromIntY); - yy = bound.inner.max; - if (bound.outer.max > yy) - yy = bound.outer.max; - maxy = floor(yy - acc->fromIntY); - y = spdata->k; - span = spdata->spans; - if (spdata->top) - { - if (a1 == 90 * 64 && (mask & 1)) - newFinalSpan (acc->yorgu - y - 1, acc->xorg, acc->xorg + 1); - span++; - } - for (n = spdata->count1; --n >= 0; ) - { - if (y < miny) - return; - if (y <= maxy) { - arcSpan (y, - span->lx, -span->lx, 0, span->lx + span->lw, - def, &bound, acc, mask); - if (span->rw + span->rx) - tailSpan (y, -span->rw, -span->rx, def, &bound, acc, mask); - } - y--; - span++; - } - if (y < miny) - return; - if (spdata->hole) - { - if (y <= maxy) - arcSpan (y, 0, 0, 0, 1, def, &bound, acc, mask & 0xc); - } - for (n = spdata->count2; --n >= 0; ) - { - if (y < miny) - return; - if (y <= maxy) - arcSpan (y, span->lx, span->lw, span->rx, span->rw, - def, &bound, acc, mask); - y--; - span++; - } - if (spdata->bot && miny <= y && y <= maxy) - { - n = mask; - if (y == miny) - n &= 0xc; - if (span->rw <= 0) { - arcSpan0 (span->lx, -span->lx, 0, span->lx + span->lw, - def, &bound, acc, n); - if (span->rw + span->rx) - tailSpan (y, -span->rw, -span->rx, def, &bound, acc, n); - } - else - arcSpan0 (span->lx, span->lw, span->rx, span->rw, - def, &bound, acc, n); - y--; - } - while (y >= miny) { - yy = y + acc->fromIntY; - if (def->w == def->h) { - xalt = def->w - def->l; - x = -sqrt(xalt * xalt - yy * yy); - } else { - x = tailX(yy, def, &bound, acc); - if (acc->left.valid && boundedLe (yy, bound.left)) { - xalt = intersectLine (yy, acc->left); - if (xalt < x) - x = xalt; - } - if (acc->right.valid && boundedLe (yy, bound.right)) { - xalt = intersectLine (yy, acc->right); - if (xalt < x) - x = xalt; - } - } - arcSpan (y, - ICEIL(acc->fromIntX - x), 0, - ICEIL(acc->fromIntX + x), 0, - def, &bound, acc, mask); - y--; - } + struct arc_bound bound; + double yy, x, xalt; + int y, miny, maxy; + int n; + miArcSpan *span; + + def->a0 = ((double) a0) / 64.0; + def->a1 = ((double) a1) / 64.0; + computeBound(def, &bound, acc, right, left); + yy = bound.inner.min; + if (bound.outer.min < yy) + yy = bound.outer.min; + miny = ICEIL(yy - acc->fromIntY); + yy = bound.inner.max; + if (bound.outer.max > yy) + yy = bound.outer.max; + maxy = floor(yy - acc->fromIntY); + y = spdata->k; + span = spdata->spans; + if (spdata->top) { + if (a1 == 90 * 64 && (mask & 1)) + newFinalSpan(acc->yorgu - y - 1, acc->xorg, acc->xorg + 1); + span++; + } + for (n = spdata->count1; --n >= 0;) { + if (y < miny) + return; + if (y <= maxy) { + arcSpan(y, + span->lx, -span->lx, 0, span->lx + span->lw, + def, &bound, acc, mask); + if (span->rw + span->rx) + tailSpan(y, -span->rw, -span->rx, def, &bound, acc, mask); + } + y--; + span++; + } + if (y < miny) + return; + if (spdata->hole) { + if (y <= maxy) + arcSpan(y, 0, 0, 0, 1, def, &bound, acc, mask & 0xc); + } + for (n = spdata->count2; --n >= 0;) { + if (y < miny) + return; + if (y <= maxy) + arcSpan(y, span->lx, span->lw, span->rx, span->rw, + def, &bound, acc, mask); + y--; + span++; + } + if (spdata->bot && miny <= y && y <= maxy) { + n = mask; + if (y == miny) + n &= 0xc; + if (span->rw <= 0) { + arcSpan0(span->lx, -span->lx, 0, span->lx + span->lw, + def, &bound, acc, n); + if (span->rw + span->rx) + tailSpan(y, -span->rw, -span->rx, def, &bound, acc, n); + } + else + arcSpan0(span->lx, span->lw, span->rx, span->rw, + def, &bound, acc, n); + y--; + } + while (y >= miny) { + yy = y + acc->fromIntY; + if (def->w == def->h) { + xalt = def->w - def->l; + x = -sqrt(xalt * xalt - yy * yy); + } + else { + x = tailX(yy, def, &bound, acc); + if (acc->left.valid && boundedLe(yy, bound.left)) { + xalt = intersectLine(yy, acc->left); + if (xalt < x) + x = xalt; + } + if (acc->right.valid && boundedLe(yy, bound.right)) { + xalt = intersectLine(yy, acc->right); + if (xalt < x) + x = xalt; + } + } + arcSpan(y, + ICEIL(acc->fromIntX - x), 0, + ICEIL(acc->fromIntX + x), 0, def, &bound, acc, mask); + y--; + } } diff --git a/xorg-server/mi/mibitblt.c b/xorg-server/mi/mibitblt.c index fc6eb8d6e..b9873c16d 100644 --- a/xorg-server/mi/mibitblt.c +++ b/xorg-server/mi/mibitblt.c @@ -22,7 +22,6 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved @@ -74,73 +73,67 @@ extern int ffs(int); * We let SetSpans worry about clipping to the destination. */ RegionPtr -miCopyArea(DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - int xIn, - int yIn, - int widthSrc, - int heightSrc, - int xOut, - int yOut) +miCopyArea(DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, int yIn, int widthSrc, int heightSrc, int xOut, int yOut) { - DDXPointPtr ppt, pptFirst; - unsigned int *pwidthFirst, *pwidth, *pbits; - BoxRec srcBox, *prect; - /* may be a new region, or just a copy */ - RegionPtr prgnSrcClip; - /* non-0 if we've created a src clip */ - RegionPtr prgnExposed; - int realSrcClip = 0; - int srcx, srcy, dstx, dsty, i, j, y, width, height, - xMin, xMax, yMin, yMax; - unsigned int *ordering; - int numRects; - BoxPtr boxes; + DDXPointPtr ppt, pptFirst; + unsigned int *pwidthFirst, *pwidth, *pbits; + BoxRec srcBox, *prect; + + /* may be a new region, or just a copy */ + RegionPtr prgnSrcClip; + + /* non-0 if we've created a src clip */ + RegionPtr prgnExposed; + int realSrcClip = 0; + int srcx, srcy, dstx, dsty, i, j, y, width, height, xMin, xMax, yMin, yMax; + unsigned int *ordering; + int numRects; + BoxPtr boxes; srcx = xIn + pSrcDrawable->x; srcy = yIn + pSrcDrawable->y; /* If the destination isn't realized, this is easy */ if (pDstDrawable->type == DRAWABLE_WINDOW && - !((WindowPtr)pDstDrawable)->realized) - return NULL; + !((WindowPtr) pDstDrawable)->realized) + return NULL; /* clip the source */ - if (pSrcDrawable->type == DRAWABLE_PIXMAP) - { - BoxRec box; + if (pSrcDrawable->type == DRAWABLE_PIXMAP) { + BoxRec box; - box.x1 = pSrcDrawable->x; - box.y1 = pSrcDrawable->y; - box.x2 = pSrcDrawable->x + (int) pSrcDrawable->width; - box.y2 = pSrcDrawable->y + (int) pSrcDrawable->height; + box.x1 = pSrcDrawable->x; + box.y1 = pSrcDrawable->y; + box.x2 = pSrcDrawable->x + (int) pSrcDrawable->width; + box.y2 = pSrcDrawable->y + (int) pSrcDrawable->height; - prgnSrcClip = RegionCreate(&box, 1); - realSrcClip = 1; + prgnSrcClip = RegionCreate(&box, 1); + realSrcClip = 1; } - else - { - if (pGC->subWindowMode == IncludeInferiors) { - prgnSrcClip = NotClippedByChildren ((WindowPtr) pSrcDrawable); - realSrcClip = 1; - } else - prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList; + else { + if (pGC->subWindowMode == IncludeInferiors) { + prgnSrcClip = NotClippedByChildren((WindowPtr) pSrcDrawable); + realSrcClip = 1; + } + else + prgnSrcClip = &((WindowPtr) pSrcDrawable)->clipList; } /* If the src drawable is a window, we need to translate the srcBox so * that we can compare it with the window's clip region later on. */ srcBox.x1 = srcx; srcBox.y1 = srcy; - srcBox.x2 = srcx + widthSrc; - srcBox.y2 = srcy + heightSrc; + srcBox.x2 = srcx + widthSrc; + srcBox.y2 = srcy + heightSrc; dstx = xOut; dsty = yOut; - if (pGC->miTranslate) - { - dstx += pDstDrawable->x; - dsty += pDstDrawable->y; + if (pGC->miTranslate) { + dstx += pDstDrawable->x; + dsty += pDstDrawable->y; } pptFirst = ppt = malloc(heightSrc * sizeof(DDXPointRec)); @@ -148,116 +141,112 @@ miCopyArea(DrawablePtr pSrcDrawable, numRects = RegionNumRects(prgnSrcClip); boxes = RegionRects(prgnSrcClip); ordering = malloc(numRects * sizeof(unsigned int)); - if(!pptFirst || !pwidthFirst || !ordering) - { - free(ordering); - free(pwidthFirst); - free(pptFirst); - return NULL; + if (!pptFirst || !pwidthFirst || !ordering) { + free(ordering); + free(pwidthFirst); + free(pptFirst); + return NULL; } /* If not the same drawable then order of move doesn't matter. Following assumes that boxes are sorted from top to bottom and left to right. - */ + */ if ((pSrcDrawable != pDstDrawable) && - ((pGC->subWindowMode != IncludeInferiors) || - (pSrcDrawable->type == DRAWABLE_PIXMAP) || - (pDstDrawable->type == DRAWABLE_PIXMAP))) - for (i=0; i < numRects; i++) - ordering[i] = i; - else { /* within same drawable, must sequence moves carefully! */ - if (dsty <= srcBox.y1) { /* Scroll up or stationary vertical. - Vertical order OK */ - if (dstx <= srcBox.x1) /* Scroll left or stationary horizontal. - Horizontal order OK as well */ - for (i=0; i < numRects; i++) + ((pGC->subWindowMode != IncludeInferiors) || + (pSrcDrawable->type == DRAWABLE_PIXMAP) || + (pDstDrawable->type == DRAWABLE_PIXMAP))) + for (i = 0; i < numRects; i++) ordering[i] = i; - else { /* scroll right. must reverse horizontal banding of rects. */ - for (i=0, j=1, xMax=0; i < numRects; j=i+1, xMax=i) { - /* find extent of current horizontal band */ - y=boxes[i].y1; /* band has this y coordinate */ - while ((j < numRects) && (boxes[j].y1 == y)) - j++; - /* reverse the horizontal band in the output ordering */ - for (j-- ; j >= xMax; j--, i++) - ordering[i] = j; - } + else { /* within same drawable, must sequence moves carefully! */ + if (dsty <= srcBox.y1) { /* Scroll up or stationary vertical. + Vertical order OK */ + if (dstx <= srcBox.x1) /* Scroll left or stationary horizontal. + Horizontal order OK as well */ + for (i = 0; i < numRects; i++) + ordering[i] = i; + else { /* scroll right. must reverse horizontal banding of rects. */ + for (i = 0, j = 1, xMax = 0; i < numRects; j = i + 1, xMax = i) { + /* find extent of current horizontal band */ + y = boxes[i].y1; /* band has this y coordinate */ + while ((j < numRects) && (boxes[j].y1 == y)) + j++; + /* reverse the horizontal band in the output ordering */ + for (j--; j >= xMax; j--, i++) + ordering[i] = j; + } + } } - } - else { /* Scroll down. Must reverse vertical banding. */ - if (dstx < srcBox.x1) { /* Scroll left. Horizontal order OK. */ - for (i=numRects-1, j=i-1, yMin=i, yMax=0; - i >= 0; - j=i-1, yMin=i) { - /* find extent of current horizontal band */ - y=boxes[i].y1; /* band has this y coordinate */ - while ((j >= 0) && (boxes[j].y1 == y)) - j--; - /* reverse the horizontal band in the output ordering */ - for (j++ ; j <= yMin; j++, i--, yMax++) - ordering[yMax] = j; - } + else { /* Scroll down. Must reverse vertical banding. */ + if (dstx < srcBox.x1) { /* Scroll left. Horizontal order OK. */ + for (i = numRects - 1, j = i - 1, yMin = i, yMax = 0; + i >= 0; j = i - 1, yMin = i) { + /* find extent of current horizontal band */ + y = boxes[i].y1; /* band has this y coordinate */ + while ((j >= 0) && (boxes[j].y1 == y)) + j--; + /* reverse the horizontal band in the output ordering */ + for (j++; j <= yMin; j++, i--, yMax++) + ordering[yMax] = j; + } + } + else /* Scroll right or horizontal stationary. + Reverse horizontal order as well (if stationary, horizontal + order can be swapped without penalty and this is faster + to compute). */ + for (i = 0, j = numRects - 1; i < numRects; i++, j--) + ordering[i] = j; } - else /* Scroll right or horizontal stationary. - Reverse horizontal order as well (if stationary, horizontal - order can be swapped without penalty and this is faster - to compute). */ - for (i=0, j=numRects-1; i < numRects; i++, j--) - ordering[i] = j; - } } - - for(i = 0; i < numRects; i++) - { + + for (i = 0; i < numRects; i++) { prect = &boxes[ordering[i]]; - xMin = max(prect->x1, srcBox.x1); - xMax = min(prect->x2, srcBox.x2); - yMin = max(prect->y1, srcBox.y1); - yMax = min(prect->y2, srcBox.y2); - /* is there anything visible here? */ - if(xMax <= xMin || yMax <= yMin) - continue; + xMin = max(prect->x1, srcBox.x1); + xMax = min(prect->x2, srcBox.x2); + yMin = max(prect->y1, srcBox.y1); + yMax = min(prect->y2, srcBox.y2); + /* is there anything visible here? */ + if (xMax <= xMin || yMax <= yMin) + continue; ppt = pptFirst; - pwidth = pwidthFirst; - y = yMin; - height = yMax - yMin; - width = xMax - xMin; - - for(j = 0; j < height; j++) - { - /* We must untranslate before calling GetSpans */ - ppt->x = xMin; - ppt++->y = y++; - *pwidth++ = width; - } - pbits = malloc(height * PixmapBytePad(width, pSrcDrawable->depth)); - if (pbits) - { - (*pSrcDrawable->pScreen->GetSpans)(pSrcDrawable, width, pptFirst, - (int *)pwidthFirst, height, (char *)pbits); - ppt = pptFirst; - pwidth = pwidthFirst; - xMin -= (srcx - dstx); - y = yMin - (srcy - dsty); - for(j = 0; j < height; j++) - { - ppt->x = xMin; - ppt++->y = y++; - *pwidth++ = width; - } - - (*pGC->ops->SetSpans)(pDstDrawable, pGC, (char *)pbits, pptFirst, - (int *)pwidthFirst, height, TRUE); - free(pbits); - } + pwidth = pwidthFirst; + y = yMin; + height = yMax - yMin; + width = xMax - xMin; + + for (j = 0; j < height; j++) { + /* We must untranslate before calling GetSpans */ + ppt->x = xMin; + ppt++->y = y++; + *pwidth++ = width; + } + pbits = malloc(height * PixmapBytePad(width, pSrcDrawable->depth)); + if (pbits) { + (*pSrcDrawable->pScreen->GetSpans) (pSrcDrawable, width, pptFirst, + (int *) pwidthFirst, height, + (char *) pbits); + ppt = pptFirst; + pwidth = pwidthFirst; + xMin -= (srcx - dstx); + y = yMin - (srcy - dsty); + for (j = 0; j < height; j++) { + ppt->x = xMin; + ppt++->y = y++; + *pwidth++ = width; + } + + (*pGC->ops->SetSpans) (pDstDrawable, pGC, (char *) pbits, pptFirst, + (int *) pwidthFirst, height, TRUE); + free(pbits); + } } prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, - widthSrc, heightSrc, xOut, yOut, (unsigned long)0); - if(realSrcClip) - RegionDestroy(prgnSrcClip); - + widthSrc, heightSrc, xOut, yOut, + (unsigned long) 0); + if (realSrcClip) + RegionDestroy(prgnSrcClip); + free(ordering); free(pwidthFirst); free(pptFirst); @@ -274,21 +263,15 @@ miCopyArea(DrawablePtr pSrcDrawable, * care about such things as scanline padding et alia. */ static -MiBits * -miGetPlane( - DrawablePtr pDraw, - int planeNum, /* number of the bitPlane */ - int sx, - int sy, - int w, - int h, - MiBits *result) +MiBits * +miGetPlane(DrawablePtr pDraw, int planeNum, /* number of the bitPlane */ + int sx, int sy, int w, int h, MiBits * result) { - int i, j, k, width, bitsPerPixel, widthInBytes; - DDXPointRec pt = {0, 0}; - MiBits pixel; - MiBits bit; - unsigned char *pCharsOut = NULL; + int i, j, k, width, bitsPerPixel, widthInBytes; + DDXPointRec pt = { 0, 0 }; + MiBits pixel; + MiBits bit; + unsigned char *pCharsOut = NULL; #if BITMAP_SCANLINE_UNIT == 8 #define OUT_TYPE unsigned char @@ -303,81 +286,74 @@ miGetPlane( #define OUT_TYPE CARD64 #endif - OUT_TYPE *pOut; - int delta = 0; + OUT_TYPE *pOut; + int delta = 0; sx += pDraw->x; sy += pDraw->y; widthInBytes = BitmapBytePad(w); - if(!result) + if (!result) result = calloc(h, widthInBytes); if (!result) - return NULL; + return NULL; bitsPerPixel = pDraw->bitsPerPixel; pOut = (OUT_TYPE *) result; - if(bitsPerPixel == 1) - { - pCharsOut = (unsigned char *) result; - width = w; + if (bitsPerPixel == 1) { + pCharsOut = (unsigned char *) result; + width = w; } - else - { - delta = (widthInBytes / (BITMAP_SCANLINE_UNIT / 8)) - - (w / BITMAP_SCANLINE_UNIT); - width = 1; + else { + delta = (widthInBytes / (BITMAP_SCANLINE_UNIT / 8)) - + (w / BITMAP_SCANLINE_UNIT); + width = 1; #if IMAGE_BYTE_ORDER == MSBFirst - planeNum += (32 - bitsPerPixel); + planeNum += (32 - bitsPerPixel); #endif } pt.y = sy; - for (i = h; --i >= 0; pt.y++) - { - pt.x = sx; - if(bitsPerPixel == 1) - { - (*pDraw->pScreen->GetSpans)(pDraw, width, &pt, &width, 1, - (char *)pCharsOut); - pCharsOut += widthInBytes; - } - else - { - k = 0; - for(j = w; --j >= 0; pt.x++) - { - /* Fetch the next pixel */ - (*pDraw->pScreen->GetSpans)(pDraw, width, &pt, &width, 1, - (char *)&pixel); - /* - * Now get the bit and insert into a bitmap in XY format. - */ - bit = (pixel >> planeNum) & 1; + for (i = h; --i >= 0; pt.y++) { + pt.x = sx; + if (bitsPerPixel == 1) { + (*pDraw->pScreen->GetSpans) (pDraw, width, &pt, &width, 1, + (char *) pCharsOut); + pCharsOut += widthInBytes; + } + else { + k = 0; + for (j = w; --j >= 0; pt.x++) { + /* Fetch the next pixel */ + (*pDraw->pScreen->GetSpans) (pDraw, width, &pt, &width, 1, + (char *) &pixel); + /* + * Now get the bit and insert into a bitmap in XY format. + */ + bit = (pixel >> planeNum) & 1; #if 0 - /* XXX assuming bit order == byte order */ + /* XXX assuming bit order == byte order */ #if BITMAP_BIT_ORDER == LSBFirst - bit <<= k; + bit <<= k; #else - bit <<= ((BITMAP_SCANLINE_UNIT - 1) - k); + bit <<= ((BITMAP_SCANLINE_UNIT - 1) - k); #endif #else - /* XXX assuming byte order == LSBFirst */ - if (screenInfo.bitmapBitOrder == LSBFirst) - bit <<= k; - else - bit <<= ((screenInfo.bitmapScanlineUnit - 1) - - (k % screenInfo.bitmapScanlineUnit)) + - ((k / screenInfo.bitmapScanlineUnit) * - screenInfo.bitmapScanlineUnit); + /* XXX assuming byte order == LSBFirst */ + if (screenInfo.bitmapBitOrder == LSBFirst) + bit <<= k; + else + bit <<= ((screenInfo.bitmapScanlineUnit - 1) - + (k % screenInfo.bitmapScanlineUnit)) + + ((k / screenInfo.bitmapScanlineUnit) * + screenInfo.bitmapScanlineUnit); #endif - *pOut |= (OUT_TYPE) bit; - k++; - if (k == BITMAP_SCANLINE_UNIT) - { - pOut++; - k = 0; - } - } - pOut += delta; - } + *pOut |= (OUT_TYPE) bit; + k++; + if (k == BITMAP_SCANLINE_UNIT) { + pOut++; + k = 0; + } + } + pOut += delta; + } } return result; @@ -395,76 +371,71 @@ miGetPlane( */ static void miOpqStipDrawable(DrawablePtr pDraw, GCPtr pGC, RegionPtr prgnSrc, - MiBits *pbits, int srcx, int w, int h, int dstx, int dsty) + MiBits * pbits, int srcx, int w, int h, int dstx, int dsty) { - int oldfill, i; + int oldfill, i; unsigned long oldfg; - int *pwidth, *pwidthFirst; - ChangeGCVal gcv[6]; - PixmapPtr pStipple, pPixmap; - DDXPointRec oldOrg; - GCPtr pGCT; + int *pwidth, *pwidthFirst; + ChangeGCVal gcv[6]; + PixmapPtr pStipple, pPixmap; + DDXPointRec oldOrg; + GCPtr pGCT; DDXPointPtr ppt, pptFirst; xRectangle rect; - RegionPtr prgnSrcClip; + RegionPtr prgnSrcClip; pPixmap = (*pDraw->pScreen->CreatePixmap) - (pDraw->pScreen, w + srcx, h, 1, - CREATE_PIXMAP_USAGE_SCRATCH); + (pDraw->pScreen, w + srcx, h, 1, CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) - return; + return; /* Put the image into a 1 bit deep pixmap */ pGCT = GetScratchGC(1, pDraw->pScreen); - if (!pGCT) - { - (*pDraw->pScreen->DestroyPixmap)(pPixmap); - return; + if (!pGCT) { + (*pDraw->pScreen->DestroyPixmap) (pPixmap); + return; } /* First set the whole pixmap to 0 */ gcv[0].val = 0; ChangeGC(NullClient, pGCT, GCBackground, gcv); - ValidateGC((DrawablePtr)pPixmap, pGCT); - miClearDrawable((DrawablePtr)pPixmap, pGCT); + ValidateGC((DrawablePtr) pPixmap, pGCT); + miClearDrawable((DrawablePtr) pPixmap, pGCT); ppt = pptFirst = malloc(h * sizeof(DDXPointRec)); pwidth = pwidthFirst = malloc(h * sizeof(int)); - if(!pptFirst || !pwidthFirst) - { - free(pwidthFirst); - free(pptFirst); - FreeScratchGC(pGCT); - return; + if (!pptFirst || !pwidthFirst) { + free(pwidthFirst); + free(pptFirst); + FreeScratchGC(pGCT); + return; } /* we need a temporary region because ChangeClip must be assumed to destroy what it's sent. note that this means we don't have to free prgnSrcClip ourselves. - */ + */ prgnSrcClip = RegionCreate(NULL, 0); RegionCopy(prgnSrcClip, prgnSrc); RegionTranslate(prgnSrcClip, srcx, 0); - (*pGCT->funcs->ChangeClip)(pGCT, CT_REGION, prgnSrcClip, 0); - ValidateGC((DrawablePtr)pPixmap, pGCT); + (*pGCT->funcs->ChangeClip) (pGCT, CT_REGION, prgnSrcClip, 0); + ValidateGC((DrawablePtr) pPixmap, pGCT); /* Since we know pDraw is always a pixmap, we never need to think * about translation here */ - for(i = 0; i < h; i++) - { - ppt->x = 0; - ppt++->y = i; - *pwidth++ = w + srcx; + for (i = 0; i < h; i++) { + ppt->x = 0; + ppt++->y = i; + *pwidth++ = w + srcx; } - (*pGCT->ops->SetSpans)((DrawablePtr)pPixmap, pGCT, (char *)pbits, - pptFirst, pwidthFirst, h, TRUE); + (*pGCT->ops->SetSpans) ((DrawablePtr) pPixmap, pGCT, (char *) pbits, + pptFirst, pwidthFirst, h, TRUE); free(pwidthFirst); free(pptFirst); - /* Save current values from the client GC */ oldfill = pGC->fillStyle; pStipple = pGC->stipple; - if(pStipple) + if (pStipple) pStipple->refcnt++; oldOrg = pGC->patOrg; @@ -476,7 +447,7 @@ miOpqStipDrawable(DrawablePtr pDraw, GCPtr pGC, RegionPtr prgnSrc, ChangeGC(NullClient, pGC, GCFillStyle | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin, - gcv); + gcv); ValidateGC(pDraw, pGC); /* Fill the drawable with the stipple. This will draw the @@ -487,15 +458,15 @@ miOpqStipDrawable(DrawablePtr pDraw, GCPtr pGC, RegionPtr prgnSrc, rect.y = dsty; rect.width = w; rect.height = h; - (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect); + (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &rect); /* Invert the tiling pixmap. This sets 0s for 1s and 1s for 0s, only * within the clipping region, the part outside is still all 0s */ gcv[0].val = GXinvert; ChangeGC(NullClient, pGCT, GCFunction, gcv); - ValidateGC((DrawablePtr)pPixmap, pGCT); - (*pGCT->ops->CopyArea)((DrawablePtr)pPixmap, (DrawablePtr)pPixmap, - pGCT, 0, 0, w + srcx, h, 0, 0); + ValidateGC((DrawablePtr) pPixmap, pGCT); + (*pGCT->ops->CopyArea) ((DrawablePtr) pPixmap, (DrawablePtr) pPixmap, + pGCT, 0, 0, w + srcx, h, 0, 0); /* Swap foreground and background colors on the GC for the drawable. * Now when we fill the drawable, we will fill in the "Background" @@ -511,10 +482,10 @@ miOpqStipDrawable(DrawablePtr pDraw, GCPtr pGC, RegionPtr prgnSrc, rect.y = dsty; rect.width = w; rect.height = h; - (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect); + (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &rect); /* Now put things back */ - if(pStipple) + if (pStipple) pStipple->refcnt--; gcv[0].val = oldfg; gcv[1].val = pGC->fgPixel; @@ -523,14 +494,14 @@ miOpqStipDrawable(DrawablePtr pDraw, GCPtr pGC, RegionPtr prgnSrc, gcv[4].val = oldOrg.x; gcv[5].val = oldOrg.y; ChangeGC(NullClient, pGC, - GCForeground | GCBackground | GCFillStyle | GCStipple | - GCTileStipXOrigin | GCTileStipYOrigin, gcv); + GCForeground | GCBackground | GCFillStyle | GCStipple | + GCTileStipXOrigin | GCTileStipYOrigin, gcv); ValidateGC(pDraw, pGC); /* put what we hope is a smaller clip region back in the scratch gc */ - (*pGCT->funcs->ChangeClip)(pGCT, CT_NONE, NULL, 0); + (*pGCT->funcs->ChangeClip) (pGCT, CT_NONE, NULL, 0); FreeScratchGC(pGCT); - (*pDraw->pScreen->DestroyPixmap)(pPixmap); + (*pDraw->pScreen->DestroyPixmap) (pPixmap); } @@ -541,20 +512,16 @@ miOpqStipDrawable(DrawablePtr pDraw, GCPtr pGC, RegionPtr prgnSrc, * Use the bitmap we've built up as a Stipple for the destination */ RegionPtr -miCopyPlane( DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - int srcx, - int srcy, - int width, - int height, - int dstx, - int dsty, - unsigned long bitPlane) +miCopyPlane(DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int srcx, + int srcy, + int width, int height, int dstx, int dsty, unsigned long bitPlane) { - MiBits *ptile; - BoxRec box; - RegionPtr prgnSrc, prgnExposed; + MiBits *ptile; + BoxRec box; + RegionPtr prgnSrc, prgnExposed; /* incorporate the source clip */ @@ -564,57 +531,55 @@ miCopyPlane( DrawablePtr pSrcDrawable, box.y2 = box.y1 + height; /* clip to visible drawable */ if (box.x1 < pSrcDrawable->x) - box.x1 = pSrcDrawable->x; + box.x1 = pSrcDrawable->x; if (box.y1 < pSrcDrawable->y) - box.y1 = pSrcDrawable->y; + box.y1 = pSrcDrawable->y; if (box.x2 > pSrcDrawable->x + (int) pSrcDrawable->width) - box.x2 = pSrcDrawable->x + (int) pSrcDrawable->width; + box.x2 = pSrcDrawable->x + (int) pSrcDrawable->width; if (box.y2 > pSrcDrawable->y + (int) pSrcDrawable->height) - box.y2 = pSrcDrawable->y + (int) pSrcDrawable->height; + box.y2 = pSrcDrawable->y + (int) pSrcDrawable->height; if (box.x1 > box.x2) - box.x2 = box.x1; + box.x2 = box.x1; if (box.y1 > box.y2) - box.y2 = box.y1; + box.y2 = box.y1; prgnSrc = RegionCreate(&box, 1); if (pSrcDrawable->type != DRAWABLE_PIXMAP) { - /* clip to visible drawable */ - - if (pGC->subWindowMode == IncludeInferiors) - { - RegionPtr clipList = NotClippedByChildren ((WindowPtr) pSrcDrawable); - RegionIntersect(prgnSrc, prgnSrc, clipList); - RegionDestroy(clipList); - } else - RegionIntersect(prgnSrc, prgnSrc, - &((WindowPtr)pSrcDrawable)->clipList); + /* clip to visible drawable */ + + if (pGC->subWindowMode == IncludeInferiors) { + RegionPtr clipList = NotClippedByChildren((WindowPtr) pSrcDrawable); + + RegionIntersect(prgnSrc, prgnSrc, clipList); + RegionDestroy(clipList); + } + else + RegionIntersect(prgnSrc, prgnSrc, + &((WindowPtr) pSrcDrawable)->clipList); } box = *RegionExtents(prgnSrc); RegionTranslate(prgnSrc, -box.x1, -box.y1); - if ((box.x2 > box.x1) && (box.y2 > box.y1)) - { - /* minimize the size of the data extracted */ - /* note that we convert the plane mask bitPlane into a plane number */ - box.x1 -= pSrcDrawable->x; - box.x2 -= pSrcDrawable->x; - box.y1 -= pSrcDrawable->y; - box.y2 -= pSrcDrawable->y; - ptile = miGetPlane(pSrcDrawable, ffs(bitPlane) - 1, - box.x1, box.y1, - box.x2 - box.x1, box.y2 - box.y1, - (MiBits *) NULL); - if (ptile) - { - miOpqStipDrawable(pDstDrawable, pGC, prgnSrc, ptile, 0, - box.x2 - box.x1, box.y2 - box.y1, - dstx + box.x1 - srcx, dsty + box.y1 - srcy); - free(ptile); - } + if ((box.x2 > box.x1) && (box.y2 > box.y1)) { + /* minimize the size of the data extracted */ + /* note that we convert the plane mask bitPlane into a plane number */ + box.x1 -= pSrcDrawable->x; + box.x2 -= pSrcDrawable->x; + box.y1 -= pSrcDrawable->y; + box.y2 -= pSrcDrawable->y; + ptile = miGetPlane(pSrcDrawable, ffs(bitPlane) - 1, + box.x1, box.y1, + box.x2 - box.x1, box.y2 - box.y1, (MiBits *) NULL); + if (ptile) { + miOpqStipDrawable(pDstDrawable, pGC, prgnSrc, ptile, 0, + box.x2 - box.x1, box.y2 - box.y1, + dstx + box.x1 - srcx, dsty + box.y1 - srcy); + free(ptile); + } } prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, - width, height, dstx, dsty, bitPlane); + width, height, dstx, dsty, bitPlane); RegionDestroy(prgnSrc); return prgnExposed; } @@ -636,80 +601,72 @@ miCopyPlane( DrawablePtr pSrcDrawable, * get the single plane specified in planemask */ void -miGetImage( DrawablePtr pDraw, int sx, int sy, int w, int h, - unsigned int format, unsigned long planeMask, char *pDst) +miGetImage(DrawablePtr pDraw, int sx, int sy, int w, int h, + unsigned int format, unsigned long planeMask, char *pDst) { - unsigned char depth; - int i, linelength, width, srcx, srcy; - DDXPointRec pt = {0, 0}; - PixmapPtr pPixmap = NULL; - GCPtr pGC = NULL; + unsigned char depth; + int i, linelength, width, srcx, srcy; + DDXPointRec pt = { 0, 0 }; + PixmapPtr pPixmap = NULL; + GCPtr pGC = NULL; depth = pDraw->depth; - if(format == ZPixmap) - { - if ( (((1LL<<depth)-1)&planeMask) != (1LL<<depth)-1 ) - { - ChangeGCVal gcv; - xPoint pt; - - pGC = GetScratchGC(depth, pDraw->pScreen); - if (!pGC) - return; + if (format == ZPixmap) { + if ((((1LL << depth) - 1) & planeMask) != (1LL << depth) - 1) { + ChangeGCVal gcv; + xPoint pt; + + pGC = GetScratchGC(depth, pDraw->pScreen); + if (!pGC) + return; pPixmap = (*pDraw->pScreen->CreatePixmap) - (pDraw->pScreen, w, 1, depth, - CREATE_PIXMAP_USAGE_SCRATCH); - if (!pPixmap) - { - FreeScratchGC(pGC); - return; - } - /* - * Clear the pixmap before doing anything else - */ - ValidateGC((DrawablePtr)pPixmap, pGC); - pt.x = pt.y = 0; + (pDraw->pScreen, w, 1, depth, CREATE_PIXMAP_USAGE_SCRATCH); + if (!pPixmap) { + FreeScratchGC(pGC); + return; + } + /* + * Clear the pixmap before doing anything else + */ + ValidateGC((DrawablePtr) pPixmap, pGC); + pt.x = pt.y = 0; width = w; - (*pGC->ops->FillSpans)((DrawablePtr)pPixmap, pGC, 1, &pt, &width, - TRUE); - - /* alu is already GXCopy */ - gcv.val = (XID)planeMask; - ChangeGC(NullClient, pGC, GCPlaneMask, &gcv); - ValidateGC((DrawablePtr)pPixmap, pGC); - } + (*pGC->ops->FillSpans) ((DrawablePtr) pPixmap, pGC, 1, &pt, &width, + TRUE); + + /* alu is already GXCopy */ + gcv.val = (XID) planeMask; + ChangeGC(NullClient, pGC, GCPlaneMask, &gcv); + ValidateGC((DrawablePtr) pPixmap, pGC); + } linelength = PixmapBytePad(w, depth); - srcx = sx + pDraw->x; - srcy = sy + pDraw->y; - for(i = 0; i < h; i++) - { - pt.x = srcx; - pt.y = srcy + i; - width = w; - (*pDraw->pScreen->GetSpans)(pDraw, w, &pt, &width, 1, pDst); - if (pPixmap) - { - pt.x = 0; - pt.y = 0; - width = w; - (*pGC->ops->SetSpans)((DrawablePtr)pPixmap, pGC, pDst, - &pt, &width, 1, TRUE); - (*pDraw->pScreen->GetSpans)((DrawablePtr)pPixmap, w, &pt, - &width, 1, pDst); - } - pDst += linelength; - } - if (pPixmap) - { - (*pGC->pScreen->DestroyPixmap)(pPixmap); - FreeScratchGC(pGC); - } + srcx = sx + pDraw->x; + srcy = sy + pDraw->y; + for (i = 0; i < h; i++) { + pt.x = srcx; + pt.y = srcy + i; + width = w; + (*pDraw->pScreen->GetSpans) (pDraw, w, &pt, &width, 1, pDst); + if (pPixmap) { + pt.x = 0; + pt.y = 0; + width = w; + (*pGC->ops->SetSpans) ((DrawablePtr) pPixmap, pGC, pDst, + &pt, &width, 1, TRUE); + (*pDraw->pScreen->GetSpans) ((DrawablePtr) pPixmap, w, &pt, + &width, 1, pDst); + } + pDst += linelength; + } + if (pPixmap) { + (*pGC->pScreen->DestroyPixmap) (pPixmap); + FreeScratchGC(pGC); + } } - else - { - (void) miGetPlane(pDraw, ffs(planeMask) - 1, sx, sy, w, h, - (MiBits *)pDst); + else { + (void) miGetPlane(pDraw, ffs(planeMask) - 1, sx, sy, w, h, + (MiBits *) pDst); } } @@ -734,92 +691,86 @@ miGetImage( DrawablePtr pDraw, int sx, int sy, int w, int h, * This part is simple, just call SetSpans */ void -miPutImage( DrawablePtr pDraw, GCPtr pGC, int depth, - int x, int y, int w, int h, - int leftPad, int format, char *pImage) +miPutImage(DrawablePtr pDraw, GCPtr pGC, int depth, + int x, int y, int w, int h, int leftPad, int format, char *pImage) { - DDXPointPtr pptFirst, ppt; - int *pwidthFirst, *pwidth; - RegionPtr prgnSrc; - BoxRec box; - unsigned long oldFg, oldBg; - ChangeGCVal gcv[3]; - unsigned long oldPlanemask; - unsigned long i; - long bytesPer; + DDXPointPtr pptFirst, ppt; + int *pwidthFirst, *pwidth; + RegionPtr prgnSrc; + BoxRec box; + unsigned long oldFg, oldBg; + ChangeGCVal gcv[3]; + unsigned long oldPlanemask; + unsigned long i; + long bytesPer; if (!w || !h) - return; - switch(format) - { - case XYBitmap: + return; + switch (format) { + case XYBitmap: - box.x1 = 0; - box.y1 = 0; - box.x2 = w; - box.y2 = h; - prgnSrc = RegionCreate(&box, 1); + box.x1 = 0; + box.y1 = 0; + box.x2 = w; + box.y2 = h; + prgnSrc = RegionCreate(&box, 1); miOpqStipDrawable(pDraw, pGC, prgnSrc, (MiBits *) pImage, - leftPad, w, h, x, y); - RegionDestroy(prgnSrc); - break; - - case XYPixmap: - depth = pGC->depth; - oldPlanemask = pGC->planemask; - oldFg = pGC->fgPixel; - oldBg = pGC->bgPixel; - gcv[0].val = (XID)~0; - gcv[1].val = (XID)0; - ChangeGC(NullClient, pGC, GCForeground | GCBackground, gcv); - bytesPer = (long)h * BitmapBytePad(w + leftPad); - - for (i = 1 << (depth-1); i != 0; i >>= 1, pImage += bytesPer) - { - if (i & oldPlanemask) - { - gcv[0].val = (XID)i; - ChangeGC(NullClient, pGC, GCPlaneMask, gcv); - ValidateGC(pDraw, pGC); - (*pGC->ops->PutImage)(pDraw, pGC, 1, x, y, w, h, leftPad, - XYBitmap, (char *)pImage); - } - } - gcv[0].val = (XID)oldPlanemask; - gcv[1].val = (XID)oldFg; - gcv[2].val = (XID)oldBg; - ChangeGC(NullClient, pGC, GCPlaneMask | GCForeground | GCBackground, gcv); - ValidateGC(pDraw, pGC); - break; - - case ZPixmap: + leftPad, w, h, x, y); + RegionDestroy(prgnSrc); + break; + + case XYPixmap: + depth = pGC->depth; + oldPlanemask = pGC->planemask; + oldFg = pGC->fgPixel; + oldBg = pGC->bgPixel; + gcv[0].val = (XID) ~0; + gcv[1].val = (XID) 0; + ChangeGC(NullClient, pGC, GCForeground | GCBackground, gcv); + bytesPer = (long) h *BitmapBytePad(w + leftPad); + + for (i = 1 << (depth - 1); i != 0; i >>= 1, pImage += bytesPer) { + if (i & oldPlanemask) { + gcv[0].val = (XID) i; + ChangeGC(NullClient, pGC, GCPlaneMask, gcv); + ValidateGC(pDraw, pGC); + (*pGC->ops->PutImage) (pDraw, pGC, 1, x, y, w, h, leftPad, + XYBitmap, (char *) pImage); + } + } + gcv[0].val = (XID) oldPlanemask; + gcv[1].val = (XID) oldFg; + gcv[2].val = (XID) oldBg; + ChangeGC(NullClient, pGC, GCPlaneMask | GCForeground | GCBackground, + gcv); + ValidateGC(pDraw, pGC); + break; + + case ZPixmap: ppt = pptFirst = malloc(h * sizeof(DDXPointRec)); pwidth = pwidthFirst = malloc(h * sizeof(int)); - if(!pptFirst || !pwidthFirst) - { - free(pwidthFirst); - free(pptFirst); - return; + if (!pptFirst || !pwidthFirst) { + free(pwidthFirst); + free(pptFirst); + return; + } + if (pGC->miTranslate) { + x += pDraw->x; + y += pDraw->y; } - if (pGC->miTranslate) - { - x += pDraw->x; - y += pDraw->y; - } - - for(i = 0; i < h; i++) - { - ppt->x = x; - ppt->y = y + i; - ppt++; - *pwidth++ = w; - } - - (*pGC->ops->SetSpans)(pDraw, pGC, (char *)pImage, pptFirst, - pwidthFirst, h, TRUE); - free(pwidthFirst); - free(pptFirst); - break; + + for (i = 0; i < h; i++) { + ppt->x = x; + ppt->y = y + i; + ppt++; + *pwidth++ = w; + } + + (*pGC->ops->SetSpans) (pDraw, pGC, (char *) pImage, pptFirst, + pwidthFirst, h, TRUE); + free(pwidthFirst); + free(pptFirst); + break; } } diff --git a/xorg-server/mi/micmap.c b/xorg-server/mi/micmap.c index 3746cad7f..90ca85d67 100644 --- a/xorg-server/mi/micmap.c +++ b/xorg-server/mi/micmap.c @@ -27,7 +27,6 @@ * are may be debatable. */ - #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> #endif @@ -43,11 +42,11 @@ DevPrivateKeyRec micmapScrPrivateKeyRec; int -miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps) +miListInstalledColormaps(ScreenPtr pScreen, Colormap * pmaps) { if (GetInstalledmiColormap(pScreen)) { - *pmaps = GetInstalledmiColormap(pScreen)->mid; - return 1; + *pmaps = GetInstalledmiColormap(pScreen)->mid; + return 1; } return 0; } @@ -57,15 +56,14 @@ miInstallColormap(ColormapPtr pmap) { ColormapPtr oldpmap = GetInstalledmiColormap(pmap->pScreen); - if(pmap != oldpmap) - { - /* Uninstall pInstalledMap. No hardware changes required, just - * notify all interested parties. */ - if(oldpmap != (ColormapPtr)None) - WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid); - /* Install pmap */ - SetInstalledmiColormap(pmap->pScreen, pmap); - WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid); + if (pmap != oldpmap) { + /* Uninstall pInstalledMap. No hardware changes required, just + * notify all interested parties. */ + if (oldpmap != (ColormapPtr) None) + WalkTree(pmap->pScreen, TellLostMap, (char *) &oldpmap->mid); + /* Install pmap */ + SetInstalledmiColormap(pmap->pScreen, pmap); + WalkTree(pmap->pScreen, TellGainedMap, (char *) &pmap->mid); } } @@ -75,38 +73,33 @@ miUninstallColormap(ColormapPtr pmap) { ColormapPtr curpmap = GetInstalledmiColormap(pmap->pScreen); - if(pmap == curpmap) - { - if (pmap->mid != pmap->pScreen->defColormap) - { - dixLookupResourceByType((pointer *)&curpmap, - pmap->pScreen->defColormap, - RT_COLORMAP, serverClient, - DixUseAccess); - (*pmap->pScreen->InstallColormap)(curpmap); - } + if (pmap == curpmap) { + if (pmap->mid != pmap->pScreen->defColormap) { + dixLookupResourceByType((pointer *) &curpmap, + pmap->pScreen->defColormap, + RT_COLORMAP, serverClient, DixUseAccess); + (*pmap->pScreen->InstallColormap) (curpmap); + } } } void miResolveColor(unsigned short *pred, unsigned short *pgreen, - unsigned short *pblue, VisualPtr pVisual) + unsigned short *pblue, VisualPtr pVisual) { int shift = 16 - pVisual->bitsPerRGBValue; unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1; - if ((pVisual->class | DynamicClass) == GrayScale) - { - /* rescale to gray then rgb bits */ - *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100; - *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim; + if ((pVisual->class | DynamicClass) == GrayScale) { + /* rescale to gray then rgb bits */ + *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100; + *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim; } - else - { - /* rescale to rgb bits */ - *pred = ((*pred >> shift) * 65535) / lim; - *pgreen = ((*pgreen >> shift) * 65535) / lim; - *pblue = ((*pblue >> shift) * 65535) / lim; + else { + /* rescale to rgb bits */ + *pred = ((*pred >> shift) * 65535) / lim; + *pgreen = ((*pgreen >> shift) * 65535) / lim; + *pblue = ((*pblue >> shift) * 65535) / lim; } } @@ -121,66 +114,58 @@ miInitializeColormap(ColormapPtr pmap) lim = (1 << pVisual->bitsPerRGBValue) - 1; shift = 16 - pVisual->bitsPerRGBValue; maxent = pVisual->ColormapEntries - 1; - if (pVisual->class == TrueColor) - { - unsigned limr, limg, limb; - - limr = pVisual->redMask >> pVisual->offsetRed; - for(i = 0; i <= min(limr,maxent); i++) - { - /* rescale to [0..65535] then rgb bits */ - pmap->red[i].co.local.red = - ((((i * 65535) / limr) >> shift) * 65535) / lim; - } - for(; i <= maxent; i++) pmap->red[i].co.local.red = 65535; - limg = pVisual->greenMask >> pVisual->offsetGreen; - for(i = 0; i <= min(limg,maxent); i++) - { - /* rescale to [0..65535] then rgb bits */ - pmap->green[i].co.local.green = - ((((i * 65535) / limg) >> shift) * 65535) / lim; - } - for(; i <= maxent; i++) pmap->green[i].co.local.green = 65535; - limb = pVisual->blueMask >> pVisual->offsetBlue; - for(i = 0; i <= min(limb,maxent); i++) - { - /* rescale to [0..65535] then rgb bits */ - pmap->blue[i].co.local.blue = - ((((i * 65535) / limb) >> shift) * 65535) / lim; - } - for(; i <= maxent; i++) pmap->blue[i].co.local.blue = 65535; + if (pVisual->class == TrueColor) { + unsigned limr, limg, limb; + + limr = pVisual->redMask >> pVisual->offsetRed; + for(i = 0; i <= min(limr,maxent); i++) { + /* rescale to [0..65535] then rgb bits */ + pmap->red[i].co.local.red = + ((((i * 65535) / limr) >> shift) * 65535) / lim; + } + for(; i <= maxent; i++) pmap->red[i].co.local.red = 65535; + limg = pVisual->greenMask >> pVisual->offsetGreen; + for(i = 0; i <= min(limg,maxent); i++) { + /* rescale to [0..65535] then rgb bits */ + pmap->green[i].co.local.green = + ((((i * 65535) / limg) >> shift) * 65535) / lim; + } + for(; i <= maxent; i++) pmap->green[i].co.local.green = 65535; + limb = pVisual->blueMask >> pVisual->offsetBlue; + for(i = 0; i <= min(limb,maxent); i++) { + /* rescale to [0..65535] then rgb bits */ + pmap->blue[i].co.local.blue = + ((((i * 65535) / limb) >> shift) * 65535) / lim; + } + for(; i <= maxent; i++) pmap->blue[i].co.local.blue = 65535; } - else if (pVisual->class == StaticColor) - { - unsigned limr, limg, limb; - - limr = pVisual->redMask >> pVisual->offsetRed; - limg = pVisual->greenMask >> pVisual->offsetGreen; - limb = pVisual->blueMask >> pVisual->offsetBlue; - for(i = 0; i <= maxent; i++) - { - /* rescale to [0..65535] then rgb bits */ - pmap->red[i].co.local.red = - ((((((i & pVisual->redMask) >> pVisual->offsetRed) - * 65535) / limr) >> shift) * 65535) / lim; - pmap->red[i].co.local.green = - ((((((i & pVisual->greenMask) >> pVisual->offsetGreen) - * 65535) / limg) >> shift) * 65535) / lim; - pmap->red[i].co.local.blue = - ((((((i & pVisual->blueMask) >> pVisual->offsetBlue) - * 65535) / limb) >> shift) * 65535) / lim; - } + else if (pVisual->class == StaticColor) { + unsigned limr, limg, limb; + + limr = pVisual->redMask >> pVisual->offsetRed; + limg = pVisual->greenMask >> pVisual->offsetGreen; + limb = pVisual->blueMask >> pVisual->offsetBlue; + for (i = 0; i <= maxent; i++) { + /* rescale to [0..65535] then rgb bits */ + pmap->red[i].co.local.red = + ((((((i & pVisual->redMask) >> pVisual->offsetRed) + * 65535) / limr) >> shift) * 65535) / lim; + pmap->red[i].co.local.green = + ((((((i & pVisual->greenMask) >> pVisual->offsetGreen) + * 65535) / limg) >> shift) * 65535) / lim; + pmap->red[i].co.local.blue = + ((((((i & pVisual->blueMask) >> pVisual->offsetBlue) + * 65535) / limb) >> shift) * 65535) / lim; + } } - else if (pVisual->class == StaticGray) - { - for(i = 0; i <= maxent; i++) - { - /* rescale to [0..65535] then rgb bits */ - pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift) - * 65535) / lim; - pmap->red[i].co.local.green = pmap->red[i].co.local.red; - pmap->red[i].co.local.blue = pmap->red[i].co.local.red; - } + else if (pVisual->class == StaticGray) { + for (i = 0; i <= maxent; i++) { + /* rescale to [0..65535] then rgb bits */ + pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift) + * 65535) / lim; + pmap->red[i].co.local.green = pmap->red[i].co.local.red; + pmap->red[i].co.local.blue = pmap->red[i].co.local.red; + } } return TRUE; } @@ -207,16 +192,16 @@ miInitializeColormap(ColormapPtr pmap) } int -miExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem *indefs, - xColorItem *outdefs) +miExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem * indefs, + xColorItem * outdefs) { - int red, green, blue; - int maxred, maxgreen, maxblue; - int stepred, stepgreen, stepblue; - VisualPtr pVisual; - int pixel; - int nresult; - int i; + int red, green, blue; + int maxred, maxgreen, maxblue; + int stepred, stepgreen, stepblue; + VisualPtr pVisual; + int pixel; + int nresult; + int i; pVisual = pmap->pVisual; @@ -227,41 +212,31 @@ miExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem *indefs, maxgreen = pVisual->greenMask; maxblue = pVisual->blueMask; nresult = 0; - for (;ndef--; indefs++) - { - if (indefs->flags & DoRed) - { - red = indefs->pixel & pVisual->redMask; - for (green = 0; green <= maxgreen; green += stepgreen) - { - for (blue = 0; blue <= maxblue; blue += stepblue) - { - AddElement (DoRed) - } - } - } - if (indefs->flags & DoGreen) - { - green = indefs->pixel & pVisual->greenMask; - for (red = 0; red <= maxred; red += stepred) - { - for (blue = 0; blue <= maxblue; blue += stepblue) - { - AddElement (DoGreen) - } - } - } - if (indefs->flags & DoBlue) - { - blue = indefs->pixel & pVisual->blueMask; - for (red = 0; red <= maxred; red += stepred) - { - for (green = 0; green <= maxgreen; green += stepgreen) - { - AddElement (DoBlue) - } - } - } + for (; ndef--; indefs++) { + if (indefs->flags & DoRed) { + red = indefs->pixel & pVisual->redMask; + for (green = 0; green <= maxgreen; green += stepgreen) { + for (blue = 0; blue <= maxblue; blue += stepblue) { + AddElement(DoRed) + } + } + } + if (indefs->flags & DoGreen) { + green = indefs->pixel & pVisual->greenMask; + for (red = 0; red <= maxred; red += stepred) { + for (blue = 0; blue <= maxblue; blue += stepblue) { + AddElement(DoGreen) + } + } + } + if (indefs->flags & DoBlue) { + blue = indefs->pixel & pVisual->blueMask; + for (red = 0; red <= maxred; red += stepred) { + for (green = 0; green <= maxgreen; green += stepgreen) { + AddElement(DoBlue) + } + } + } } return nresult; } @@ -279,76 +254,73 @@ miCreateDefColormap(ScreenPtr pScreen) * color specifications. */ static xColorItem citems[] = { - { 0, 0, 0, 0, 0, 0 }, - { 1, 0x8000, 0, 0, 0, 0 }, - { 2, 0, 0x8000, 0, 0, 0 }, - { 3, 0x8000, 0x8000, 0, 0, 0 }, - { 4, 0, 0, 0x8000, 0, 0 }, - { 5, 0x8000, 0, 0x8000, 0, 0 }, - { 6, 0, 0x8000, 0x8000, 0, 0 }, - { 7, 0xc000, 0xc000, 0xc000, 0, 0 }, - { 8, 0xc000, 0xdc00, 0xc000, 0, 0 }, - { 9, 0xa600, 0xca00, 0xf000, 0, 0 }, - { 246, 0xff00, 0xfb00, 0xf000, 0, 0 }, - { 247, 0xa000, 0xa000, 0xa400, 0, 0 }, - { 248, 0x8000, 0x8000, 0x8000, 0, 0 }, - { 249, 0xff00, 0, 0, 0, 0 }, - { 250, 0, 0xff00, 0, 0, 0 }, - { 251, 0xff00, 0xff00, 0, 0, 0 }, - { 252, 0, 0, 0xff00, 0, 0 }, - { 253, 0xff00, 0, 0xff00, 0, 0 }, - { 254, 0, 0xff00, 0xff00, 0, 0 }, - { 255, 0xff00, 0xff00, 0xff00, 0, 0 } + {0, 0, 0, 0, 0, 0}, + {1, 0x8000, 0, 0, 0, 0}, + {2, 0, 0x8000, 0, 0, 0}, + {3, 0x8000, 0x8000, 0, 0, 0}, + {4, 0, 0, 0x8000, 0, 0}, + {5, 0x8000, 0, 0x8000, 0, 0}, + {6, 0, 0x8000, 0x8000, 0, 0}, + {7, 0xc000, 0xc000, 0xc000, 0, 0}, + {8, 0xc000, 0xdc00, 0xc000, 0, 0}, + {9, 0xa600, 0xca00, 0xf000, 0, 0}, + {246, 0xff00, 0xfb00, 0xf000, 0, 0}, + {247, 0xa000, 0xa000, 0xa400, 0, 0}, + {248, 0x8000, 0x8000, 0x8000, 0, 0}, + {249, 0xff00, 0, 0, 0, 0}, + {250, 0, 0xff00, 0, 0, 0}, + {251, 0xff00, 0xff00, 0, 0, 0}, + {252, 0, 0, 0xff00, 0, 0}, + {253, 0xff00, 0, 0xff00, 0, 0}, + {254, 0, 0xff00, 0xff00, 0, 0}, + {255, 0xff00, 0xff00, 0xff00, 0, 0} }; #define NUM_DESKTOP_COLORS sizeof citems / sizeof citems[0] int i; #else - unsigned short zero = 0, ones = 0xFFFF; + unsigned short zero = 0, ones = 0xFFFF; #endif Pixel wp, bp; - VisualPtr pVisual; - ColormapPtr cmap; + VisualPtr pVisual; + ColormapPtr cmap; int alloctype; - + if (!dixRegisterPrivateKey(&micmapScrPrivateKeyRec, PRIVATE_SCREEN, 0)) - return FALSE; + return FALSE; for (pVisual = pScreen->visuals; - pVisual->vid != pScreen->rootVisual; - pVisual++) - ; + pVisual->vid != pScreen->rootVisual; pVisual++); if (pScreen->rootDepth == 1 || (pVisual->class & DynamicClass)) - alloctype = AllocNone; + alloctype = AllocNone; else - alloctype = AllocAll; + alloctype = AllocAll; if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap, - alloctype, 0) != Success) - return FALSE; + alloctype, 0) != Success) + return FALSE; if (pScreen->rootDepth > 1) { - wp = pScreen->whitePixel; - bp = pScreen->blackPixel; + wp = pScreen->whitePixel; + bp = pScreen->blackPixel; #ifdef WIN32_not_tog - for (i = 0; i < NUM_DESKTOP_COLORS; i++) { - if (AllocColor (cmap, - &citems[i].red, &citems[i].green, &citems[i].blue, - &citems[i].pixel, 0) != Success) - return FALSE; - } + for (i = 0; i < NUM_DESKTOP_COLORS; i++) { + if (AllocColor(cmap, + &citems[i].red, &citems[i].green, &citems[i].blue, + &citems[i].pixel, 0) != Success) + return FALSE; + } #else - if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) != - Success) || - (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) != - Success)) - return FALSE; - pScreen->whitePixel = wp; - pScreen->blackPixel = bp; + if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) != + Success) || + (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) != Success)) + return FALSE; + pScreen->whitePixel = wp; + pScreen->blackPixel = bp; #endif } - (*pScreen->InstallColormap)(cmap); + (*pScreen->InstallColormap) (cmap); return TRUE; } @@ -369,22 +341,22 @@ miCreateDefColormap(ScreenPtr pScreen) #define _CE(d) (1 << _RZ(d)) typedef struct _miVisuals { - struct _miVisuals *next; - int depth; - int bitsPerRGB; - int visuals; - int count; - int preferredCVC; - Pixel redMask, greenMask, blueMask; + struct _miVisuals *next; + int depth; + int bitsPerRGB; + int visuals; + int count; + int preferredCVC; + Pixel redMask, greenMask, blueMask; } miVisualsRec, *miVisualsPtr; -static int miVisualPriority[] = { +static int miVisualPriority[] = { PseudoColor, GrayScale, StaticColor, TrueColor, DirectColor, StaticGray }; #define NUM_PRIORITY 6 -static miVisualsPtr miVisuals; +static miVisualsPtr miVisuals; void miClearVisualTypes(void) @@ -392,28 +364,26 @@ miClearVisualTypes(void) miVisualsPtr v; while ((v = miVisuals)) { - miVisuals = v->next; - free(v); + miVisuals = v->next; + free(v); } } - Bool -miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB, - int preferredCVC, - Pixel redMask, Pixel greenMask, Pixel blueMask) +miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB, + int preferredCVC, + Pixel redMask, Pixel greenMask, Pixel blueMask) { - miVisualsPtr new, *prev, v; - int count; + miVisualsPtr new, *prev, v; + int count; new = malloc(sizeof *new); if (!new) - return FALSE; - if (!redMask || !greenMask || !blueMask) - { - redMask = _RM(depth); - greenMask = _GM(depth); - blueMask = _BM(depth); + return FALSE; + if (!redMask || !greenMask || !blueMask) { + redMask = _RM(depth); + greenMask = _GM(depth); + blueMask = _BM(depth); } new->next = 0; new->depth = depth; @@ -425,7 +395,7 @@ miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB, new->blueMask = blueMask; count = (visuals >> 1) & 033333333333; count = visuals - count - ((count >> 1) & 033333333333); - count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */ + count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */ new->count = count; for (prev = &miVisuals; (v = *prev); prev = &v->next); *prev = new; @@ -435,48 +405,46 @@ miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB, Bool miSetVisualTypes(int depth, int visuals, int bitsPerRGB, int preferredCVC) { - return miSetVisualTypesAndMasks (depth, visuals, bitsPerRGB, - preferredCVC, 0, 0, 0); + return miSetVisualTypesAndMasks(depth, visuals, bitsPerRGB, + preferredCVC, 0, 0, 0); } int miGetDefaultVisualMask(int depth) { if (depth > MAX_PSEUDO_DEPTH) - return LARGE_VISUALS; + return LARGE_VISUALS; else if (depth >= MIN_TRUE_DEPTH) - return ALL_VISUALS; + return ALL_VISUALS; else if (depth == 1) - return StaticGrayMask; + return StaticGrayMask; else - return SMALL_VISUALS; + return SMALL_VISUALS; } static Bool -miVisualTypesSet (int depth) +miVisualTypesSet(int depth) { - miVisualsPtr visuals; + miVisualsPtr visuals; for (visuals = miVisuals; visuals; visuals = visuals->next) - if (visuals->depth == depth) - return TRUE; + if (visuals->depth == depth) + return TRUE; return FALSE; } Bool -miSetPixmapDepths (void) +miSetPixmapDepths(void) { - int d, f; - + int d, f; + /* Add any unlisted depths from the pixmap formats */ - for (f = 0; f < screenInfo.numPixmapFormats; f++) - { - d = screenInfo.formats[f].depth; - if (!miVisualTypesSet (d)) - { - if (!miSetVisualTypes (d, 0, 0, -1)) - return FALSE; - } + for (f = 0; f < screenInfo.numPixmapFormats; f++) { + d = screenInfo.formats[f].depth; + if (!miVisualTypesSet(d)) { + if (!miSetVisualTypes(d, 0, 0, -1)) + return FALSE; + } } return TRUE; } @@ -485,16 +453,16 @@ miSetPixmapDepths (void) * Distance to least significant one bit */ static int -maskShift (Pixel p) +maskShift(Pixel p) { - int s; + int s; - if (!p) return 0; + if (!p) + return 0; s = 0; - while (!(p & 1)) - { - s++; - p >>= 1; + while (!(p & 1)) { + s++; + p >>= 1; } return s; } @@ -506,120 +474,113 @@ maskShift (Pixel p) */ Bool -miInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp, - int *ndepthp, int *rootDepthp, VisualID *defaultVisp, - unsigned long sizes, int bitsPerRGB, int preferredVis) - +miInitVisuals(VisualPtr * visualp, DepthPtr * depthp, int *nvisualp, + int *ndepthp, int *rootDepthp, VisualID * defaultVisp, + unsigned long sizes, int bitsPerRGB, int preferredVis) { - int i, j = 0, k; - VisualPtr visual; - DepthPtr depth; - VisualID *vid; - int d, b; - int f; - int ndepth, nvisual; - int nvtype; - int vtype; - miVisualsPtr visuals, nextVisuals; - int *preferredCVCs, *prefp; - int first_depth; + int i, j = 0, k; + VisualPtr visual; + DepthPtr depth; + VisualID *vid; + int d, b; + int f; + int ndepth, nvisual; + int nvtype; + int vtype; + miVisualsPtr visuals, nextVisuals; + int *preferredCVCs, *prefp; + int first_depth; /* none specified, we'll guess from pixmap formats */ - if (!miVisuals) - { - for (f = 0; f < screenInfo.numPixmapFormats; f++) - { - d = screenInfo.formats[f].depth; - b = screenInfo.formats[f].bitsPerPixel; - if (sizes & (1 << (b - 1))) - vtype = miGetDefaultVisualMask(d); - else - vtype = 0; - if (!miSetVisualTypes (d, vtype, bitsPerRGB, -1)) - return FALSE; - } + if (!miVisuals) { + for (f = 0; f < screenInfo.numPixmapFormats; f++) { + d = screenInfo.formats[f].depth; + b = screenInfo.formats[f].bitsPerPixel; + if (sizes & (1 << (b - 1))) + vtype = miGetDefaultVisualMask(d); + else + vtype = 0; + if (!miSetVisualTypes(d, vtype, bitsPerRGB, -1)) + return FALSE; + } } nvisual = 0; ndepth = 0; - for (visuals = miVisuals; visuals; visuals = nextVisuals) - { - nextVisuals = visuals->next; - ndepth++; - nvisual += visuals->count; + for (visuals = miVisuals; visuals; visuals = nextVisuals) { + nextVisuals = visuals->next; + ndepth++; + nvisual += visuals->count; } - depth = malloc(ndepth * sizeof (DepthRec)); - visual = malloc(nvisual * sizeof (VisualRec)); + depth = malloc(ndepth * sizeof(DepthRec)); + visual = malloc(nvisual * sizeof(VisualRec)); preferredCVCs = malloc(ndepth * sizeof(int)); - if (!depth || !visual || !preferredCVCs) - { - free(depth); - free(visual); - free(preferredCVCs); - return FALSE; + if (!depth || !visual || !preferredCVCs) { + free(depth); + free(visual); + free(preferredCVCs); + return FALSE; } *depthp = depth; *visualp = visual; *ndepthp = ndepth; *nvisualp = nvisual; prefp = preferredCVCs; - for (visuals = miVisuals; visuals; visuals = nextVisuals) - { - nextVisuals = visuals->next; - d = visuals->depth; - vtype = visuals->visuals; - nvtype = visuals->count; - *prefp = visuals->preferredCVC; - prefp++; - vid = NULL; - if (nvtype) - { - vid = malloc(nvtype * sizeof (VisualID)); - if (!vid) { - free(depth); - free(visual); - free(preferredCVCs); - return FALSE; - } - } - depth->depth = d; - depth->numVids = nvtype; - depth->vids = vid; - depth++; - for (i = 0; i < NUM_PRIORITY; i++) { - if (! (vtype & (1 << miVisualPriority[i]))) - continue; - visual->class = miVisualPriority[i]; - visual->bitsPerRGBValue = visuals->bitsPerRGB; - visual->ColormapEntries = 1 << d; - visual->nplanes = d; - visual->vid = *vid = FakeClientID (0); - switch (visual->class) { - case PseudoColor: - case GrayScale: - case StaticGray: - visual->redMask = 0; - visual->greenMask = 0; - visual->blueMask = 0; - visual->offsetRed = 0; - visual->offsetGreen = 0; - visual->offsetBlue = 0; - break; - case DirectColor: - case TrueColor: - visual->ColormapEntries = _CE(d); - /* fall through */ - case StaticColor: - visual->redMask = visuals->redMask; - visual->greenMask = visuals->greenMask; - visual->blueMask = visuals->blueMask; - visual->offsetRed = maskShift (visuals->redMask); - visual->offsetGreen = maskShift (visuals->greenMask); - visual->offsetBlue = maskShift (visuals->blueMask); - } - vid++; - visual++; - } - free(visuals); + for (visuals = miVisuals; visuals; visuals = nextVisuals) { + nextVisuals = visuals->next; + d = visuals->depth; + vtype = visuals->visuals; + nvtype = visuals->count; + *prefp = visuals->preferredCVC; + prefp++; + vid = NULL; + if (nvtype) { + vid = malloc(nvtype * sizeof(VisualID)); + if (!vid) { + free(depth); + free(visual); + free(preferredCVCs); + return FALSE; + } + } + depth->depth = d; + depth->numVids = nvtype; + depth->vids = vid; + depth++; + for (i = 0; i < NUM_PRIORITY; i++) { + if (!(vtype & (1 << miVisualPriority[i]))) + continue; + visual->class = miVisualPriority[i]; + visual->bitsPerRGBValue = visuals->bitsPerRGB; + visual->ColormapEntries = 1 << d; + visual->nplanes = d; + visual->vid = *vid = FakeClientID(0); + switch (visual->class) { + case PseudoColor: + case GrayScale: + case StaticGray: + visual->redMask = 0; + visual->greenMask = 0; + visual->blueMask = 0; + visual->offsetRed = 0; + visual->offsetGreen = 0; + visual->offsetBlue = 0; + break; + case DirectColor: + case TrueColor: + visual->ColormapEntries = _CE(d); + /* fall through */ + case StaticColor: + visual->redMask = visuals->redMask; + visual->greenMask = visuals->greenMask; + visual->blueMask = visuals->blueMask; + visual->offsetRed = maskShift(visuals->redMask); + visual->offsetGreen = maskShift(visuals->greenMask); + visual->offsetBlue = maskShift(visuals->blueMask); + } + vid++; + visual++; + } + free(visuals); } miVisuals = NULL; visual = *visualp; @@ -632,46 +593,44 @@ miInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp, * default visual/depth from that depth. */ first_depth = 0; - if (preferredVis < 0 && defaultColorVisualClass < 0 ) { - for (i = 0; i < ndepth; i++) { - if (preferredCVCs[i] >= 0) { - first_depth = i; - break; - } - } + if (preferredVis < 0 && defaultColorVisualClass < 0) { + for (i = 0; i < ndepth; i++) { + if (preferredCVCs[i] >= 0) { + first_depth = i; + break; + } + } } - for (i = first_depth; i < ndepth; i++) - { - int prefColorVisualClass = -1; - - if (defaultColorVisualClass >= 0) - prefColorVisualClass = defaultColorVisualClass; - else if (preferredVis >= 0) - prefColorVisualClass = preferredVis; - else if (preferredCVCs[i] >= 0) - prefColorVisualClass = preferredCVCs[i]; - - if (*rootDepthp && *rootDepthp != depth[i].depth) - continue; - - for (j = 0; j < depth[i].numVids; j++) - { - for (k = 0; k < nvisual; k++) - if (visual[k].vid == depth[i].vids[j]) - break; - if (k == nvisual) - continue; - if (prefColorVisualClass < 0 || - visual[k].class == prefColorVisualClass) - break; - } - if (j != depth[i].numVids) - break; + for (i = first_depth; i < ndepth; i++) { + int prefColorVisualClass = -1; + + if (defaultColorVisualClass >= 0) + prefColorVisualClass = defaultColorVisualClass; + else if (preferredVis >= 0) + prefColorVisualClass = preferredVis; + else if (preferredCVCs[i] >= 0) + prefColorVisualClass = preferredCVCs[i]; + + if (*rootDepthp && *rootDepthp != depth[i].depth) + continue; + + for (j = 0; j < depth[i].numVids; j++) { + for (k = 0; k < nvisual; k++) + if (visual[k].vid == depth[i].vids[j]) + break; + if (k == nvisual) + continue; + if (prefColorVisualClass < 0 || + visual[k].class == prefColorVisualClass) + break; + } + if (j != depth[i].numVids) + break; } if (i == ndepth) { - i = 0; - j = 0; + i = 0; + j = 0; } *rootDepthp = depth[i].depth; *defaultVisp = depth[i].vids[j]; diff --git a/xorg-server/mi/micmap.h b/xorg-server/mi/micmap.h index dcfcfd47f..0e344b7ac 100644 --- a/xorg-server/mi/micmap.h +++ b/xorg-server/mi/micmap.h @@ -1,63 +1,67 @@ -
-#include "colormapst.h"
-
-#ifndef _MICMAP_H_
-#define _MICMAP_H_
-
-#define GetInstalledmiColormap(s) \
- ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, micmapScrPrivateKey))
-#define SetInstalledmiColormap(s,c) \
- (dixSetPrivate(&(s)->devPrivates, micmapScrPrivateKey, c))
-
-extern _X_EXPORT DevPrivateKeyRec micmapScrPrivateKeyRec;
-#define micmapScrPrivateKey (&micmapScrPrivateKeyRec)
-
-typedef Bool (* miInitVisualsProcPtr)(VisualPtr *, DepthPtr *, int *, int *,
- int *, VisualID *, unsigned long, int,
- int);
-
-extern _X_EXPORT int miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps);
-extern _X_EXPORT void miInstallColormap(ColormapPtr pmap);
-extern _X_EXPORT void miUninstallColormap(ColormapPtr pmap);
-
-extern _X_EXPORT void miResolveColor(unsigned short *, unsigned short *, unsigned short *,
- VisualPtr);
-extern _X_EXPORT Bool miInitializeColormap(ColormapPtr);
-extern _X_EXPORT int miExpandDirectColors(ColormapPtr, int, xColorItem *, xColorItem *);
-extern _X_EXPORT Bool miCreateDefColormap(ScreenPtr);
-extern _X_EXPORT void miClearVisualTypes(void);
-extern _X_EXPORT Bool miSetVisualTypes(int, int, int, int);
-extern _X_EXPORT Bool miSetPixmapDepths(void);
-extern _X_EXPORT Bool miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB,
- int preferredCVC,
- Pixel redMask, Pixel greenMask, Pixel blueMask);
-extern _X_EXPORT int miGetDefaultVisualMask(int);
-extern _X_EXPORT Bool miInitVisuals(VisualPtr *, DepthPtr *, int *, int *, int *, VisualID *,
- unsigned long, int, int);
-
-#define MAX_PSEUDO_DEPTH 10
-#define MIN_TRUE_DEPTH 6
-
-#define StaticGrayMask (1 << StaticGray)
-#define GrayScaleMask (1 << GrayScale)
-#define StaticColorMask (1 << StaticColor)
-#define PseudoColorMask (1 << PseudoColor)
-#define TrueColorMask (1 << TrueColor)
-#define DirectColorMask (1 << DirectColor)
-
-#define ALL_VISUALS (StaticGrayMask|\
- GrayScaleMask|\
- StaticColorMask|\
- PseudoColorMask|\
- TrueColorMask|\
- DirectColorMask)
-
-#define LARGE_VISUALS (TrueColorMask|\
- DirectColorMask)
-
-#define SMALL_VISUALS (StaticGrayMask|\
- GrayScaleMask|\
- StaticColorMask|\
- PseudoColorMask)
-
-#endif /* _MICMAP_H_ */
+ +#include "colormapst.h" + +#ifndef _MICMAP_H_ +#define _MICMAP_H_ + +#define GetInstalledmiColormap(s) \ + ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, micmapScrPrivateKey)) +#define SetInstalledmiColormap(s,c) \ + (dixSetPrivate(&(s)->devPrivates, micmapScrPrivateKey, c)) + +extern _X_EXPORT DevPrivateKeyRec micmapScrPrivateKeyRec; + +#define micmapScrPrivateKey (&micmapScrPrivateKeyRec) + +typedef Bool (*miInitVisualsProcPtr) (VisualPtr *, DepthPtr *, int *, int *, + int *, VisualID *, unsigned long, int, + int); + +extern _X_EXPORT int miListInstalledColormaps(ScreenPtr pScreen, + Colormap * pmaps); +extern _X_EXPORT void miInstallColormap(ColormapPtr pmap); +extern _X_EXPORT void miUninstallColormap(ColormapPtr pmap); + +extern _X_EXPORT void miResolveColor(unsigned short *, unsigned short *, + unsigned short *, VisualPtr); +extern _X_EXPORT Bool miInitializeColormap(ColormapPtr); +extern _X_EXPORT int miExpandDirectColors(ColormapPtr, int, xColorItem *, + xColorItem *); +extern _X_EXPORT Bool miCreateDefColormap(ScreenPtr); +extern _X_EXPORT void miClearVisualTypes(void); +extern _X_EXPORT Bool miSetVisualTypes(int, int, int, int); +extern _X_EXPORT Bool miSetPixmapDepths(void); +extern _X_EXPORT Bool miSetVisualTypesAndMasks(int depth, int visuals, + int bitsPerRGB, int preferredCVC, + Pixel redMask, Pixel greenMask, + Pixel blueMask); +extern _X_EXPORT int miGetDefaultVisualMask(int); +extern _X_EXPORT Bool miInitVisuals(VisualPtr *, DepthPtr *, int *, int *, + int *, VisualID *, unsigned long, int, int); + +#define MAX_PSEUDO_DEPTH 10 +#define MIN_TRUE_DEPTH 6 + +#define StaticGrayMask (1 << StaticGray) +#define GrayScaleMask (1 << GrayScale) +#define StaticColorMask (1 << StaticColor) +#define PseudoColorMask (1 << PseudoColor) +#define TrueColorMask (1 << TrueColor) +#define DirectColorMask (1 << DirectColor) + +#define ALL_VISUALS (StaticGrayMask|\ + GrayScaleMask|\ + StaticColorMask|\ + PseudoColorMask|\ + TrueColorMask|\ + DirectColorMask) + +#define LARGE_VISUALS (TrueColorMask|\ + DirectColorMask) + +#define SMALL_VISUALS (StaticGrayMask|\ + GrayScaleMask|\ + StaticColorMask|\ + PseudoColorMask) + +#endif /* _MICMAP_H_ */ diff --git a/xorg-server/mi/micopy.c b/xorg-server/mi/micopy.c index ce01249e8..30795114d 100644 --- a/xorg-server/mi/micopy.c +++ b/xorg-server/mi/micopy.c @@ -1,350 +1,313 @@ -/*
- * Copyright © 1998 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "mi.h"
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "pixmap.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-
-void
-miCopyRegion (DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- RegionPtr pDstRegion,
- int dx,
- int dy,
- miCopyProc copyProc,
- Pixel bitPlane,
- void *closure)
-{
- int careful;
- Bool reverse;
- Bool upsidedown;
- BoxPtr pbox;
- int nbox;
- BoxPtr pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp;
-
- pbox = RegionRects(pDstRegion);
- nbox = RegionNumRects(pDstRegion);
-
- /* XXX we have to err on the side of safety when both are windows,
- * because we don't know if IncludeInferiors is being used.
- */
- careful = ((pSrcDrawable == pDstDrawable) ||
- ((pSrcDrawable->type == DRAWABLE_WINDOW) &&
- (pDstDrawable->type == DRAWABLE_WINDOW)));
-
- pboxNew1 = NULL;
- pboxNew2 = NULL;
- if (careful && dy < 0)
- {
- upsidedown = TRUE;
-
- if (nbox > 1)
- {
- /* keep ordering in each band, reverse order of bands */
- pboxNew1 = (BoxPtr)malloc(sizeof(BoxRec) * nbox);
- if(!pboxNew1)
- return;
- pboxBase = pboxNext = pbox+nbox-1;
- while (pboxBase >= pbox)
- {
- while ((pboxNext >= pbox) &&
- (pboxBase->y1 == pboxNext->y1))
- pboxNext--;
- pboxTmp = pboxNext+1;
- while (pboxTmp <= pboxBase)
- {
- *pboxNew1++ = *pboxTmp++;
- }
- pboxBase = pboxNext;
- }
- pboxNew1 -= nbox;
- pbox = pboxNew1;
- }
- }
- else
- {
- /* walk source top to bottom */
- upsidedown = FALSE;
- }
-
- if (careful && dx < 0)
- {
- /* walk source right to left */
- if (dy <= 0)
- reverse = TRUE;
- else
- reverse = FALSE;
-
- if (nbox > 1)
- {
- /* reverse order of rects in each band */
- pboxNew2 = (BoxPtr)malloc(sizeof(BoxRec) * nbox);
- if(!pboxNew2)
- {
- free(pboxNew1);
- return;
- }
- pboxBase = pboxNext = pbox;
- while (pboxBase < pbox+nbox)
- {
- while ((pboxNext < pbox+nbox) &&
- (pboxNext->y1 == pboxBase->y1))
- pboxNext++;
- pboxTmp = pboxNext;
- while (pboxTmp != pboxBase)
- {
- *pboxNew2++ = *--pboxTmp;
- }
- pboxBase = pboxNext;
- }
- pboxNew2 -= nbox;
- pbox = pboxNew2;
- }
- }
- else
- {
- /* walk source left to right */
- reverse = FALSE;
- }
-
- (*copyProc) (pSrcDrawable,
- pDstDrawable,
- pGC,
- pbox,
- nbox,
- dx, dy,
- reverse, upsidedown, bitPlane, closure);
-
- free(pboxNew1);
- free(pboxNew2);
-}
-
-RegionPtr
-miDoCopy (DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- int xIn,
- int yIn,
- int widthSrc,
- int heightSrc,
- int xOut,
- int yOut,
- miCopyProc copyProc,
- Pixel bitPlane,
- void *closure)
-{
- RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
- Bool freeSrcClip = FALSE;
- RegionPtr prgnExposed = NULL;
- RegionRec rgnDst;
- int dx;
- int dy;
- int numRects;
- int box_x1;
- int box_y1;
- int box_x2;
- int box_y2;
- Bool fastSrc = FALSE; /* for fast clipping with pixmap source */
- Bool fastDst = FALSE; /* for fast clipping with one rect dest */
- Bool fastExpose = FALSE; /* for fast exposures with pixmap source */
-
- /* Short cut for unmapped windows */
-
- if (pDstDrawable->type == DRAWABLE_WINDOW &&
- !((WindowPtr)pDstDrawable)->realized)
- {
- return NULL;
- }
-
- if (pSrcDrawable->pScreen->SourceValidate)
- {
- (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, widthSrc, heightSrc,
- pGC->subWindowMode);
- }
-
- /* Compute source clip region */
- if (pSrcDrawable->type == DRAWABLE_PIXMAP)
- {
- if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
- prgnSrcClip = miGetCompositeClip(pGC);
- else
- fastSrc = TRUE;
- }
- else
- {
- if (pGC->subWindowMode == IncludeInferiors)
- {
- /*
- * XFree86 DDX empties the border clip when the
- * VT is inactive, make sure the region isn't empty
- */
- if (!((WindowPtr) pSrcDrawable)->parent &&
- RegionNotEmpty(&((WindowPtr) pSrcDrawable)->borderClip))
- {
- /*
- * special case bitblt from root window in
- * IncludeInferiors mode; just like from a pixmap
- */
- fastSrc = TRUE;
- }
- else if ((pSrcDrawable == pDstDrawable) &&
- (pGC->clientClipType == CT_NONE))
- {
- prgnSrcClip = miGetCompositeClip(pGC);
- }
- else
- {
- prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
- freeSrcClip = TRUE;
- }
- }
- else
- {
- prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
- }
- }
-
- xIn += pSrcDrawable->x;
- yIn += pSrcDrawable->y;
-
- xOut += pDstDrawable->x;
- yOut += pDstDrawable->y;
-
- box_x1 = xIn;
- box_y1 = yIn;
- box_x2 = xIn + widthSrc;
- box_y2 = yIn + heightSrc;
-
- dx = xIn - xOut;
- dy = yIn - yOut;
-
- /* Don't create a source region if we are doing a fast clip */
- if (fastSrc)
- {
- RegionPtr cclip;
-
- fastExpose = TRUE;
- /*
- * clip the source; if regions extend beyond the source size,
- * make sure exposure events get sent
- */
- if (box_x1 < pSrcDrawable->x)
- {
- box_x1 = pSrcDrawable->x;
- fastExpose = FALSE;
- }
- if (box_y1 < pSrcDrawable->y)
- {
- box_y1 = pSrcDrawable->y;
- fastExpose = FALSE;
- }
- if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
- {
- box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
- fastExpose = FALSE;
- }
- if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
- {
- box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
- fastExpose = FALSE;
- }
-
- /* Translate and clip the dst to the destination composite clip */
- box_x1 -= dx;
- box_x2 -= dx;
- box_y1 -= dy;
- box_y2 -= dy;
-
- /* If the destination composite clip is one rectangle we can
- do the clip directly. Otherwise we have to create a full
- blown region and call intersect */
-
- cclip = miGetCompositeClip(pGC);
- if (RegionNumRects(cclip) == 1)
- {
- BoxPtr pBox = RegionRects(cclip);
-
- if (box_x1 < pBox->x1) box_x1 = pBox->x1;
- if (box_x2 > pBox->x2) box_x2 = pBox->x2;
- if (box_y1 < pBox->y1) box_y1 = pBox->y1;
- if (box_y2 > pBox->y2) box_y2 = pBox->y2;
- fastDst = TRUE;
- }
- }
-
- /* Check to see if the region is empty */
- if (box_x1 >= box_x2 || box_y1 >= box_y2)
- {
- RegionNull(&rgnDst);
- }
- else
- {
- BoxRec box;
- box.x1 = box_x1;
- box.y1 = box_y1;
- box.x2 = box_x2;
- box.y2 = box_y2;
- RegionInit(&rgnDst, &box, 1);
- }
-
- /* Clip against complex source if needed */
- if (!fastSrc)
- {
- RegionIntersect(&rgnDst, &rgnDst, prgnSrcClip);
- RegionTranslate(&rgnDst, -dx, -dy);
- }
-
- /* Clip against complex dest if needed */
- if (!fastDst)
- {
- RegionIntersect(&rgnDst, &rgnDst,
- miGetCompositeClip(pGC));
- }
-
- /* Do bit blitting */
- numRects = RegionNumRects(&rgnDst);
- if (numRects && widthSrc && heightSrc)
- miCopyRegion (pSrcDrawable, pDstDrawable, pGC,
- &rgnDst, dx, dy, copyProc, bitPlane, closure);
-
- /* Pixmap sources generate a NoExposed (we return NULL to do this) */
- if (!fastExpose && pGC->fExpose)
- prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
- xIn - pSrcDrawable->x,
- yIn - pSrcDrawable->y,
- widthSrc, heightSrc,
- xOut - pDstDrawable->x,
- yOut - pDstDrawable->y,
- (unsigned long) bitPlane);
- RegionUninit(&rgnDst);
- if (freeSrcClip)
- RegionDestroy(prgnSrcClip);
- return prgnExposed;
-}
+/* + * Copyright © 1998 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "mi.h" +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmap.h" +#include "pixmapstr.h" +#include "windowstr.h" + +void +miCopyRegion(DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + RegionPtr pDstRegion, + int dx, int dy, miCopyProc copyProc, Pixel bitPlane, void *closure) +{ + int careful; + Bool reverse; + Bool upsidedown; + BoxPtr pbox; + int nbox; + BoxPtr pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp; + + pbox = RegionRects(pDstRegion); + nbox = RegionNumRects(pDstRegion); + + /* XXX we have to err on the side of safety when both are windows, + * because we don't know if IncludeInferiors is being used. + */ + careful = ((pSrcDrawable == pDstDrawable) || + ((pSrcDrawable->type == DRAWABLE_WINDOW) && + (pDstDrawable->type == DRAWABLE_WINDOW))); + + pboxNew1 = NULL; + pboxNew2 = NULL; + if (careful && dy < 0) { + upsidedown = TRUE; + + if (nbox > 1) { + /* keep ordering in each band, reverse order of bands */ + pboxNew1 = (BoxPtr) malloc(sizeof(BoxRec) * nbox); + if (!pboxNew1) + return; + pboxBase = pboxNext = pbox + nbox - 1; + while (pboxBase >= pbox) { + while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1)) + pboxNext--; + pboxTmp = pboxNext + 1; + while (pboxTmp <= pboxBase) { + *pboxNew1++ = *pboxTmp++; + } + pboxBase = pboxNext; + } + pboxNew1 -= nbox; + pbox = pboxNew1; + } + } + else { + /* walk source top to bottom */ + upsidedown = FALSE; + } + + if (careful && dx < 0) { + /* walk source right to left */ + if (dy <= 0) + reverse = TRUE; + else + reverse = FALSE; + + if (nbox > 1) { + /* reverse order of rects in each band */ + pboxNew2 = (BoxPtr) malloc(sizeof(BoxRec) * nbox); + if (!pboxNew2) { + free(pboxNew1); + return; + } + pboxBase = pboxNext = pbox; + while (pboxBase < pbox + nbox) { + while ((pboxNext < pbox + nbox) && + (pboxNext->y1 == pboxBase->y1)) + pboxNext++; + pboxTmp = pboxNext; + while (pboxTmp != pboxBase) { + *pboxNew2++ = *--pboxTmp; + } + pboxBase = pboxNext; + } + pboxNew2 -= nbox; + pbox = pboxNew2; + } + } + else { + /* walk source left to right */ + reverse = FALSE; + } + + (*copyProc) (pSrcDrawable, + pDstDrawable, + pGC, + pbox, nbox, dx, dy, reverse, upsidedown, bitPlane, closure); + + free(pboxNew1); + free(pboxNew2); +} + +RegionPtr +miDoCopy(DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, int yOut, miCopyProc copyProc, Pixel bitPlane, void *closure) +{ + RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */ + Bool freeSrcClip = FALSE; + RegionPtr prgnExposed = NULL; + RegionRec rgnDst; + int dx; + int dy; + int numRects; + int box_x1; + int box_y1; + int box_x2; + int box_y2; + Bool fastSrc = FALSE; /* for fast clipping with pixmap source */ + Bool fastDst = FALSE; /* for fast clipping with one rect dest */ + Bool fastExpose = FALSE; /* for fast exposures with pixmap source */ + + /* Short cut for unmapped windows */ + + if (pDstDrawable->type == DRAWABLE_WINDOW && + !((WindowPtr) pDstDrawable)->realized) { + return NULL; + } + + if (pSrcDrawable->pScreen->SourceValidate) { + (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, + widthSrc, heightSrc, + pGC->subWindowMode); + } + + /* Compute source clip region */ + if (pSrcDrawable->type == DRAWABLE_PIXMAP) { + if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE)) + prgnSrcClip = miGetCompositeClip(pGC); + else + fastSrc = TRUE; + } + else { + if (pGC->subWindowMode == IncludeInferiors) { + /* + * XFree86 DDX empties the border clip when the + * VT is inactive, make sure the region isn't empty + */ + if (!((WindowPtr) pSrcDrawable)->parent && + RegionNotEmpty(&((WindowPtr) pSrcDrawable)->borderClip)) { + /* + * special case bitblt from root window in + * IncludeInferiors mode; just like from a pixmap + */ + fastSrc = TRUE; + } + else if ((pSrcDrawable == pDstDrawable) && + (pGC->clientClipType == CT_NONE)) { + prgnSrcClip = miGetCompositeClip(pGC); + } + else { + prgnSrcClip = NotClippedByChildren((WindowPtr) pSrcDrawable); + freeSrcClip = TRUE; + } + } + else { + prgnSrcClip = &((WindowPtr) pSrcDrawable)->clipList; + } + } + + xIn += pSrcDrawable->x; + yIn += pSrcDrawable->y; + + xOut += pDstDrawable->x; + yOut += pDstDrawable->y; + + box_x1 = xIn; + box_y1 = yIn; + box_x2 = xIn + widthSrc; + box_y2 = yIn + heightSrc; + + dx = xIn - xOut; + dy = yIn - yOut; + + /* Don't create a source region if we are doing a fast clip */ + if (fastSrc) { + RegionPtr cclip; + + fastExpose = TRUE; + /* + * clip the source; if regions extend beyond the source size, + * make sure exposure events get sent + */ + if (box_x1 < pSrcDrawable->x) { + box_x1 = pSrcDrawable->x; + fastExpose = FALSE; + } + if (box_y1 < pSrcDrawable->y) { + box_y1 = pSrcDrawable->y; + fastExpose = FALSE; + } + if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width) { + box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width; + fastExpose = FALSE; + } + if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height) { + box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height; + fastExpose = FALSE; + } + + /* Translate and clip the dst to the destination composite clip */ + box_x1 -= dx; + box_x2 -= dx; + box_y1 -= dy; + box_y2 -= dy; + + /* If the destination composite clip is one rectangle we can + do the clip directly. Otherwise we have to create a full + blown region and call intersect */ + + cclip = miGetCompositeClip(pGC); + if (RegionNumRects(cclip) == 1) { + BoxPtr pBox = RegionRects(cclip); + + if (box_x1 < pBox->x1) + box_x1 = pBox->x1; + if (box_x2 > pBox->x2) + box_x2 = pBox->x2; + if (box_y1 < pBox->y1) + box_y1 = pBox->y1; + if (box_y2 > pBox->y2) + box_y2 = pBox->y2; + fastDst = TRUE; + } + } + + /* Check to see if the region is empty */ + if (box_x1 >= box_x2 || box_y1 >= box_y2) { + RegionNull(&rgnDst); + } + else { + BoxRec box; + + box.x1 = box_x1; + box.y1 = box_y1; + box.x2 = box_x2; + box.y2 = box_y2; + RegionInit(&rgnDst, &box, 1); + } + + /* Clip against complex source if needed */ + if (!fastSrc) { + RegionIntersect(&rgnDst, &rgnDst, prgnSrcClip); + RegionTranslate(&rgnDst, -dx, -dy); + } + + /* Clip against complex dest if needed */ + if (!fastDst) { + RegionIntersect(&rgnDst, &rgnDst, miGetCompositeClip(pGC)); + } + + /* Do bit blitting */ + numRects = RegionNumRects(&rgnDst); + if (numRects && widthSrc && heightSrc) + miCopyRegion(pSrcDrawable, pDstDrawable, pGC, + &rgnDst, dx, dy, copyProc, bitPlane, closure); + + /* Pixmap sources generate a NoExposed (we return NULL to do this) */ + if (!fastExpose && pGC->fExpose) + prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, + xIn - pSrcDrawable->x, + yIn - pSrcDrawable->y, + widthSrc, heightSrc, + xOut - pDstDrawable->x, + yOut - pDstDrawable->y, + (unsigned long) bitPlane); + RegionUninit(&rgnDst); + if (freeSrcClip) + RegionDestroy(prgnSrcClip); + return prgnExposed; +} diff --git a/xorg-server/mi/midash.c b/xorg-server/mi/midash.c index ba64d354f..78cbaf25e 100644 --- a/xorg-server/mi/midash.c +++ b/xorg-server/mi/midash.c @@ -22,7 +22,6 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved @@ -53,38 +52,35 @@ SOFTWARE. #include "mifpoly.h" void -miStepDash ( - int dist, /* distance to step */ - int *pDashIndex, /* current dash */ - unsigned char *pDash, /* dash list */ - int numInDashList, /* total length of dash list */ - int *pDashOffset /* offset into current dash */ +miStepDash(int dist, /* distance to step */ + int *pDashIndex, /* current dash */ + unsigned char *pDash, /* dash list */ + int numInDashList, /* total length of dash list */ + int *pDashOffset /* offset into current dash */ ) { - int dashIndex, dashOffset; + int dashIndex, dashOffset; int totallen; - int i; - + int i; + dashIndex = *pDashIndex; dashOffset = *pDashOffset; - if (dist < pDash[dashIndex] - dashOffset) - { - *pDashOffset = dashOffset + dist; - return; + if (dist < pDash[dashIndex] - dashOffset) { + *pDashOffset = dashOffset + dist; + return; } dist -= pDash[dashIndex] - dashOffset; if (++dashIndex == numInDashList) - dashIndex = 0; + dashIndex = 0; totallen = 0; for (i = 0; i < numInDashList; i++) - totallen += pDash[i]; + totallen += pDash[i]; if (totallen <= dist) - dist = dist % totallen; - while (dist >= pDash[dashIndex]) - { - dist -= pDash[dashIndex]; - if (++dashIndex == numInDashList) - dashIndex = 0; + dist = dist % totallen; + while (dist >= pDash[dashIndex]) { + dist -= pDash[dashIndex]; + if (++dashIndex == numInDashList) + dashIndex = 0; } *pDashIndex = dashIndex; *pDashOffset = dist; diff --git a/xorg-server/mi/midispcur.c b/xorg-server/mi/midispcur.c index 32c5c9df6..24b9a700d 100644 --- a/xorg-server/mi/midispcur.c +++ b/xorg-server/mi/midispcur.c @@ -4,7 +4,6 @@ * machine independent cursor display routines */ - /* Copyright 1989, 1998 The Open Group @@ -34,42 +33,45 @@ in this Software without prior written authorization from The Open Group. #include <dix-config.h> #endif -# include <X11/X.h> -# include "misc.h" -# include "input.h" -# include "cursorstr.h" -# include "windowstr.h" -# include "regionstr.h" -# include "dixstruct.h" -# include "scrnintstr.h" -# include "servermd.h" -# include "mipointer.h" -# include "misprite.h" -# include "gcstruct.h" +#include <X11/X.h> +#include "misc.h" +#include "input.h" +#include "cursorstr.h" +#include "windowstr.h" +#include "regionstr.h" +#include "dixstruct.h" +#include "scrnintstr.h" +#include "servermd.h" +#include "mipointer.h" +#include "misprite.h" +#include "gcstruct.h" #ifdef ARGB_CURSOR -# include "picturestr.h" +#include "picturestr.h" #endif -# include "inputstr.h" +#include "inputstr.h" /* per-screen private data */ static DevPrivateKeyRec miDCScreenKeyRec; + #define miDCScreenKey (&miDCScreenKeyRec) static DevScreenPrivateKeyRec miDCCursorBitsKeyRec; + #define miDCCursorBitsKey (&miDCCursorBitsKeyRec) static DevScreenPrivateKeyRec miDCDeviceKeyRec; + #define miDCDeviceKey (&miDCDeviceKeyRec) -static Bool miDCCloseScreen(int index, ScreenPtr pScreen); +static Bool miDCCloseScreen(int index, ScreenPtr pScreen); /* per device private data */ typedef struct { - GCPtr pSourceGC, pMaskGC; - GCPtr pSaveGC, pRestoreGC; - PixmapPtr pSave; + GCPtr pSourceGC, pMaskGC; + GCPtr pSaveGC, pRestoreGC; + PixmapPtr pSave; #ifdef ARGB_CURSOR - PicturePtr pRootPicture; + PicturePtr pRootPicture; #endif } miDCBufferRec, *miDCBufferPtr; @@ -83,64 +85,66 @@ typedef struct { * in the pCursorBuffers array. */ typedef struct { - CloseScreenProcPtr CloseScreen; + CloseScreenProcPtr CloseScreen; } miDCScreenRec, *miDCScreenPtr; #define miGetDCScreen(s) ((miDCScreenPtr)(dixLookupPrivate(&(s)->devPrivates, miDCScreenKey))) /* per-cursor per-screen private data */ typedef struct { - PixmapPtr sourceBits; /* source bits */ - PixmapPtr maskBits; /* mask bits */ + PixmapPtr sourceBits; /* source bits */ + PixmapPtr maskBits; /* mask bits */ #ifdef ARGB_CURSOR - PicturePtr pPicture; + PicturePtr pPicture; #endif } miDCCursorRec, *miDCCursorPtr; Bool -miDCInitialize (ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs) +miDCInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs) { - miDCScreenPtr pScreenPriv; + miDCScreenPtr pScreenPriv; if (!dixRegisterPrivateKey(&miDCScreenKeyRec, PRIVATE_SCREEN, 0) || - !dixRegisterScreenPrivateKey(&miDCCursorBitsKeyRec, pScreen, PRIVATE_CURSOR_BITS, 0) || - !dixRegisterScreenPrivateKey(&miDCDeviceKeyRec, pScreen, PRIVATE_DEVICE, 0)) - return FALSE; + !dixRegisterScreenPrivateKey(&miDCCursorBitsKeyRec, pScreen, + PRIVATE_CURSOR_BITS, 0) || + !dixRegisterScreenPrivateKey(&miDCDeviceKeyRec, pScreen, PRIVATE_DEVICE, + 0)) + return FALSE; - pScreenPriv = malloc(sizeof (miDCScreenRec)); + pScreenPriv = malloc(sizeof(miDCScreenRec)); if (!pScreenPriv) - return FALSE; + return FALSE; pScreenPriv->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = miDCCloseScreen; dixSetPrivate(&pScreen->devPrivates, miDCScreenKey, pScreenPriv); - if (!miSpriteInitialize (pScreen, screenFuncs)) - { - free((pointer) pScreenPriv); - return FALSE; + if (!miSpriteInitialize(pScreen, screenFuncs)) { + free((pointer) pScreenPriv); + return FALSE; } return TRUE; } static Bool -miDCCloseScreen (int index, ScreenPtr pScreen) +miDCCloseScreen(int index, ScreenPtr pScreen) { - miDCScreenPtr pScreenPriv; + miDCScreenPtr pScreenPriv; - pScreenPriv = (miDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates, - miDCScreenKey); + pScreenPriv = (miDCScreenPtr) dixLookupPrivate(&pScreen->devPrivates, + miDCScreenKey); pScreen->CloseScreen = pScreenPriv->CloseScreen; free((pointer) pScreenPriv); return (*pScreen->CloseScreen) (index, pScreen); } Bool -miDCRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) +miDCRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) { if (pCursor->bits->refcnt <= 1) - dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, pScreen, NULL); + dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, + pScreen, NULL); return TRUE; } @@ -148,228 +152,217 @@ miDCRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) #define EnsurePicture(picture,draw,win) (picture || miDCMakePicture(&picture,draw,win)) static VisualPtr -miDCGetWindowVisual (WindowPtr pWin) +miDCGetWindowVisual(WindowPtr pWin) { - ScreenPtr pScreen = pWin->drawable.pScreen; - VisualID vid = wVisual (pWin); - int i; + ScreenPtr pScreen = pWin->drawable.pScreen; + VisualID vid = wVisual(pWin); + int i; for (i = 0; i < pScreen->numVisuals; i++) - if (pScreen->visuals[i].vid == vid) - return &pScreen->visuals[i]; + if (pScreen->visuals[i].vid == vid) + return &pScreen->visuals[i]; return 0; } static PicturePtr -miDCMakePicture (PicturePtr *ppPicture, DrawablePtr pDraw, WindowPtr pWin) +miDCMakePicture(PicturePtr * ppPicture, DrawablePtr pDraw, WindowPtr pWin) { - ScreenPtr pScreen = pDraw->pScreen; - VisualPtr pVisual; - PictFormatPtr pFormat; - XID subwindow_mode = IncludeInferiors; - PicturePtr pPicture; - int error; - - pVisual = miDCGetWindowVisual (pWin); + ScreenPtr pScreen = pDraw->pScreen; + VisualPtr pVisual; + PictFormatPtr pFormat; + XID subwindow_mode = IncludeInferiors; + PicturePtr pPicture; + int error; + + pVisual = miDCGetWindowVisual(pWin); if (!pVisual) - return 0; - pFormat = PictureMatchVisual (pScreen, pDraw->depth, pVisual); + return 0; + pFormat = PictureMatchVisual(pScreen, pDraw->depth, pVisual); if (!pFormat) - return 0; - pPicture = CreatePicture (0, pDraw, pFormat, - CPSubwindowMode, &subwindow_mode, - serverClient, &error); + return 0; + pPicture = CreatePicture(0, pDraw, pFormat, + CPSubwindowMode, &subwindow_mode, + serverClient, &error); *ppPicture = pPicture; return pPicture; } #endif static miDCCursorPtr -miDCRealize (ScreenPtr pScreen, CursorPtr pCursor) +miDCRealize(ScreenPtr pScreen, CursorPtr pCursor) { - miDCCursorPtr pPriv; - GCPtr pGC; - ChangeGCVal gcvals; + miDCCursorPtr pPriv; + GCPtr pGC; + ChangeGCVal gcvals; - pPriv = malloc(sizeof (miDCCursorRec)); + pPriv = malloc(sizeof(miDCCursorRec)); if (!pPriv) - return NULL; + return NULL; #ifdef ARGB_CURSOR - if (pCursor->bits->argb) - { - PixmapPtr pPixmap; - PictFormatPtr pFormat; - int error; - - pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8); - if (!pFormat) - { - free((pointer) pPriv); - return NULL; - } - - pPriv->sourceBits = 0; - pPriv->maskBits = 0; - pPixmap = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, - pCursor->bits->height, 32, - CREATE_PIXMAP_USAGE_SCRATCH); - if (!pPixmap) - { - free((pointer) pPriv); - return NULL; - } - pGC = GetScratchGC (32, pScreen); - if (!pGC) - { - (*pScreen->DestroyPixmap) (pPixmap); - free((pointer) pPriv); - return NULL; - } - ValidateGC (&pPixmap->drawable, pGC); - (*pGC->ops->PutImage) (&pPixmap->drawable, pGC, 32, - 0, 0, pCursor->bits->width, - pCursor->bits->height, - 0, ZPixmap, (char *) pCursor->bits->argb); - FreeScratchGC (pGC); - pPriv->pPicture = CreatePicture (0, &pPixmap->drawable, - pFormat, 0, 0, serverClient, &error); + if (pCursor->bits->argb) { + PixmapPtr pPixmap; + PictFormatPtr pFormat; + int error; + + pFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8); + if (!pFormat) { + free((pointer) pPriv); + return NULL; + } + + pPriv->sourceBits = 0; + pPriv->maskBits = 0; + pPixmap = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, + pCursor->bits->height, 32, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!pPixmap) { + free((pointer) pPriv); + return NULL; + } + pGC = GetScratchGC(32, pScreen); + if (!pGC) { + (*pScreen->DestroyPixmap) (pPixmap); + free((pointer) pPriv); + return NULL; + } + ValidateGC(&pPixmap->drawable, pGC); + (*pGC->ops->PutImage) (&pPixmap->drawable, pGC, 32, + 0, 0, pCursor->bits->width, + pCursor->bits->height, + 0, ZPixmap, (char *) pCursor->bits->argb); + FreeScratchGC(pGC); + pPriv->pPicture = CreatePicture(0, &pPixmap->drawable, + pFormat, 0, 0, serverClient, &error); (*pScreen->DestroyPixmap) (pPixmap); - if (!pPriv->pPicture) - { - free((pointer) pPriv); - return NULL; - } - dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, pScreen, pPriv); - return pPriv; + if (!pPriv->pPicture) { + free((pointer) pPriv); + return NULL; + } + dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, + pScreen, pPriv); + return pPriv; } pPriv->pPicture = 0; #endif - pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0); - if (!pPriv->sourceBits) - { - free((pointer) pPriv); - return NULL; + pPriv->sourceBits = + (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, + pCursor->bits->height, 1, 0); + if (!pPriv->sourceBits) { + free((pointer) pPriv); + return NULL; } - pPriv->maskBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0); - if (!pPriv->maskBits) - { - (*pScreen->DestroyPixmap) (pPriv->sourceBits); - free((pointer) pPriv); - return NULL; + pPriv->maskBits = + (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, + pCursor->bits->height, 1, 0); + if (!pPriv->maskBits) { + (*pScreen->DestroyPixmap) (pPriv->sourceBits); + free((pointer) pPriv); + return NULL; } - dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, pScreen, pPriv); + dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, pScreen, + pPriv); /* create the two sets of bits, clipping as appropriate */ - pGC = GetScratchGC (1, pScreen); - if (!pGC) - { - (void) miDCUnrealizeCursor (pScreen, pCursor); - return NULL; + pGC = GetScratchGC(1, pScreen); + if (!pGC) { + (void) miDCUnrealizeCursor(pScreen, pCursor); + return NULL; } - ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC); - (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1, - 0, 0, pCursor->bits->width, pCursor->bits->height, - 0, XYPixmap, (char *)pCursor->bits->source); + ValidateGC((DrawablePtr) pPriv->sourceBits, pGC); + (*pGC->ops->PutImage) ((DrawablePtr) pPriv->sourceBits, pGC, 1, + 0, 0, pCursor->bits->width, pCursor->bits->height, + 0, XYPixmap, (char *) pCursor->bits->source); gcvals.val = GXand; - ChangeGC (NullClient, pGC, GCFunction, &gcvals); - ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC); - (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1, - 0, 0, pCursor->bits->width, pCursor->bits->height, - 0, XYPixmap, (char *)pCursor->bits->mask); + ChangeGC(NullClient, pGC, GCFunction, &gcvals); + ValidateGC((DrawablePtr) pPriv->sourceBits, pGC); + (*pGC->ops->PutImage) ((DrawablePtr) pPriv->sourceBits, pGC, 1, + 0, 0, pCursor->bits->width, pCursor->bits->height, + 0, XYPixmap, (char *) pCursor->bits->mask); /* mask bits -- pCursor->mask & ~pCursor->source */ gcvals.val = GXcopy; - ChangeGC (NullClient, pGC, GCFunction, &gcvals); - ValidateGC ((DrawablePtr)pPriv->maskBits, pGC); - (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1, - 0, 0, pCursor->bits->width, pCursor->bits->height, - 0, XYPixmap, (char *)pCursor->bits->mask); + ChangeGC(NullClient, pGC, GCFunction, &gcvals); + ValidateGC((DrawablePtr) pPriv->maskBits, pGC); + (*pGC->ops->PutImage) ((DrawablePtr) pPriv->maskBits, pGC, 1, + 0, 0, pCursor->bits->width, pCursor->bits->height, + 0, XYPixmap, (char *) pCursor->bits->mask); gcvals.val = GXandInverted; - ChangeGC (NullClient, pGC, GCFunction, &gcvals); - ValidateGC ((DrawablePtr)pPriv->maskBits, pGC); - (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1, - 0, 0, pCursor->bits->width, pCursor->bits->height, - 0, XYPixmap, (char *)pCursor->bits->source); - FreeScratchGC (pGC); + ChangeGC(NullClient, pGC, GCFunction, &gcvals); + ValidateGC((DrawablePtr) pPriv->maskBits, pGC); + (*pGC->ops->PutImage) ((DrawablePtr) pPriv->maskBits, pGC, 1, + 0, 0, pCursor->bits->width, pCursor->bits->height, + 0, XYPixmap, (char *) pCursor->bits->source); + FreeScratchGC(pGC); return pPriv; } Bool -miDCUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) +miDCUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) { - miDCCursorPtr pPriv; - - pPriv = (miDCCursorPtr)dixLookupScreenPrivate(&pCursor->bits->devPrivates, - miDCCursorBitsKey, pScreen); - if (pPriv && (pCursor->bits->refcnt <= 1)) - { - if (pPriv->sourceBits) - (*pScreen->DestroyPixmap) (pPriv->sourceBits); - if (pPriv->maskBits) - (*pScreen->DestroyPixmap) (pPriv->maskBits); + miDCCursorPtr pPriv; + + pPriv = (miDCCursorPtr) dixLookupScreenPrivate(&pCursor->bits->devPrivates, + miDCCursorBitsKey, pScreen); + if (pPriv && (pCursor->bits->refcnt <= 1)) { + if (pPriv->sourceBits) + (*pScreen->DestroyPixmap) (pPriv->sourceBits); + if (pPriv->maskBits) + (*pScreen->DestroyPixmap) (pPriv->maskBits); #ifdef ARGB_CURSOR - if (pPriv->pPicture) - FreePicture (pPriv->pPicture, 0); + if (pPriv->pPicture) + FreePicture(pPriv->pPicture, 0); #endif - free((pointer) pPriv); - dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, pScreen, NULL); + free((pointer) pPriv); + dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, + pScreen, NULL); } return TRUE; } static void -miDCPutBits ( - DrawablePtr pDrawable, - miDCCursorPtr pPriv, - GCPtr sourceGC, - GCPtr maskGC, - int x_org, - int y_org, - unsigned w, - unsigned h, - unsigned long source, - unsigned long mask) +miDCPutBits(DrawablePtr pDrawable, + miDCCursorPtr pPriv, + GCPtr sourceGC, + GCPtr maskGC, + int x_org, + int y_org, + unsigned w, unsigned h, unsigned long source, unsigned long mask) { ChangeGCVal gcval; - int x, y; + int x, y; - if (sourceGC->fgPixel != source) - { - gcval.val = source; - ChangeGC (NullClient, sourceGC, GCForeground, &gcval); + if (sourceGC->fgPixel != source) { + gcval.val = source; + ChangeGC(NullClient, sourceGC, GCForeground, &gcval); } if (sourceGC->serialNumber != pDrawable->serialNumber) - ValidateGC (pDrawable, sourceGC); + ValidateGC(pDrawable, sourceGC); - if(sourceGC->miTranslate) - { + if (sourceGC->miTranslate) { x = pDrawable->x + x_org; y = pDrawable->y + y_org; - } - else - { + } + else { x = x_org; y = y_org; } - (*sourceGC->ops->PushPixels) (sourceGC, pPriv->sourceBits, pDrawable, w, h, x, y); - if (maskGC->fgPixel != mask) - { - gcval.val = mask; - ChangeGC (NullClient, maskGC, GCForeground, &gcval); + (*sourceGC->ops->PushPixels) (sourceGC, pPriv->sourceBits, pDrawable, w, h, + x, y); + if (maskGC->fgPixel != mask) { + gcval.val = mask; + ChangeGC(NullClient, maskGC, GCForeground, &gcval); } if (maskGC->serialNumber != pDrawable->serialNumber) - ValidateGC (pDrawable, maskGC); + ValidateGC(pDrawable, maskGC); - if(maskGC->miTranslate) - { + if (maskGC->miTranslate) { x = pDrawable->x + x_org; y = pDrawable->y + y_org; - } - else - { + } + else { x = x_org; y = y_org; } @@ -381,137 +374,131 @@ static GCPtr miDCMakeGC(WindowPtr pWin) { GCPtr pGC; - int status; - XID gcvals[2]; + int status; + XID gcvals[2]; gcvals[0] = IncludeInferiors; gcvals[1] = FALSE; - pGC = CreateGC((DrawablePtr)pWin, - GCSubwindowMode|GCGraphicsExposures, gcvals, &status, - (XID)0, serverClient); + pGC = CreateGC((DrawablePtr) pWin, + GCSubwindowMode | GCGraphicsExposures, gcvals, &status, + (XID) 0, serverClient); return pGC; } - Bool -miDCPutUpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, - int x, int y, unsigned long source, unsigned long mask) +miDCPutUpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, + int x, int y, unsigned long source, unsigned long mask) { - miDCCursorPtr pPriv; - miDCBufferPtr pBuffer; - WindowPtr pWin; - - pPriv = (miDCCursorPtr)dixLookupScreenPrivate(&pCursor->bits->devPrivates, - miDCCursorBitsKey, pScreen); - if (!pPriv) - { - pPriv = miDCRealize(pScreen, pCursor); - if (!pPriv) - return FALSE; + miDCCursorPtr pPriv; + miDCBufferPtr pBuffer; + WindowPtr pWin; + + pPriv = (miDCCursorPtr) dixLookupScreenPrivate(&pCursor->bits->devPrivates, + miDCCursorBitsKey, pScreen); + if (!pPriv) { + pPriv = miDCRealize(pScreen, pCursor); + if (!pPriv) + return FALSE; } pWin = pScreen->root; pBuffer = miGetDCDevice(pDev, pScreen); #ifdef ARGB_CURSOR - if (pPriv->pPicture) - { - if (!EnsurePicture(pBuffer->pRootPicture, &pWin->drawable, pWin)) - return FALSE; - CompositePicture (PictOpOver, - pPriv->pPicture, - NULL, - pBuffer->pRootPicture, - 0, 0, 0, 0, - x, y, - pCursor->bits->width, - pCursor->bits->height); + if (pPriv->pPicture) { + if (!EnsurePicture(pBuffer->pRootPicture, &pWin->drawable, pWin)) + return FALSE; + CompositePicture(PictOpOver, + pPriv->pPicture, + NULL, + pBuffer->pRootPicture, + 0, 0, 0, 0, + x, y, pCursor->bits->width, pCursor->bits->height); } else #endif { - miDCPutBits ((DrawablePtr)pWin, pPriv, - pBuffer->pSourceGC, pBuffer->pMaskGC, - x, y, pCursor->bits->width, pCursor->bits->height, - source, mask); + miDCPutBits((DrawablePtr) pWin, pPriv, + pBuffer->pSourceGC, pBuffer->pMaskGC, + x, y, pCursor->bits->width, pCursor->bits->height, + source, mask); } return TRUE; } Bool -miDCSaveUnderCursor (DeviceIntPtr pDev, ScreenPtr pScreen, - int x, int y, int w, int h) +miDCSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y, int w, int h) { - miDCBufferPtr pBuffer; - PixmapPtr pSave; - WindowPtr pWin; - GCPtr pGC; + miDCBufferPtr pBuffer; + PixmapPtr pSave; + WindowPtr pWin; + GCPtr pGC; pBuffer = miGetDCDevice(pDev, pScreen); pSave = pBuffer->pSave; pWin = pScreen->root; - if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h) - { - if (pSave) - (*pScreen->DestroyPixmap) (pSave); - pBuffer->pSave = pSave = - (*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth, 0); - if (!pSave) - return FALSE; + if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h) { + if (pSave) + (*pScreen->DestroyPixmap) (pSave); + pBuffer->pSave = pSave = + (*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth, 0); + if (!pSave) + return FALSE; } pGC = pBuffer->pSaveGC; if (pSave->drawable.serialNumber != pGC->serialNumber) - ValidateGC ((DrawablePtr) pSave, pGC); + ValidateGC((DrawablePtr) pSave, pGC); (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC, - x, y, w, h, 0, 0); + x, y, w, h, 0, 0); return TRUE; } Bool -miDCRestoreUnderCursor (DeviceIntPtr pDev, ScreenPtr pScreen, - int x, int y, int w, int h) +miDCRestoreUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y, int w, int h) { - miDCBufferPtr pBuffer; - PixmapPtr pSave; - WindowPtr pWin; - GCPtr pGC; + miDCBufferPtr pBuffer; + PixmapPtr pSave; + WindowPtr pWin; + GCPtr pGC; pBuffer = miGetDCDevice(pDev, pScreen); pSave = pBuffer->pSave; pWin = pScreen->root; if (!pSave) - return FALSE; + return FALSE; pGC = pBuffer->pRestoreGC; if (pWin->drawable.serialNumber != pGC->serialNumber) - ValidateGC ((DrawablePtr) pWin, pGC); + ValidateGC((DrawablePtr) pWin, pGC); (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC, - 0, 0, w, h, x, y); + 0, 0, w, h, x, y); return TRUE; } Bool miDCDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) { - miDCBufferPtr pBuffer; - WindowPtr pWin; - int i; + miDCBufferPtr pBuffer; + WindowPtr pWin; + int i; if (!DevHasCursor(pDev)) return TRUE; - for (i = 0; i < screenInfo.numScreens; i++) - { + for (i = 0; i < screenInfo.numScreens; i++) { pScreen = screenInfo.screens[i]; pBuffer = calloc(1, sizeof(miDCBufferRec)); if (!pBuffer) goto failure; - dixSetScreenPrivate(&pDev->devPrivates, miDCDeviceKey, pScreen, pBuffer); + dixSetScreenPrivate(&pDev->devPrivates, miDCDeviceKey, pScreen, + pBuffer); pWin = pScreen->root; pBuffer->pSourceGC = miDCMakeGC(pWin); @@ -540,7 +527,7 @@ miDCDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) return TRUE; -failure: + failure: miDCDeviceCleanup(pDev, pScreen); @@ -550,23 +537,24 @@ failure: void miDCDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) { - miDCBufferPtr pBuffer; - int i; + miDCBufferPtr pBuffer; + int i; - if (DevHasCursor(pDev)) - { - for (i = 0; i < screenInfo.numScreens; i++) - { + if (DevHasCursor(pDev)) { + for (i = 0; i < screenInfo.numScreens; i++) { pScreen = screenInfo.screens[i]; pBuffer = miGetDCDevice(pDev, pScreen); - if (pBuffer) - { - if (pBuffer->pSourceGC) FreeGC(pBuffer->pSourceGC, (GContext) 0); - if (pBuffer->pMaskGC) FreeGC(pBuffer->pMaskGC, (GContext) 0); - if (pBuffer->pSaveGC) FreeGC(pBuffer->pSaveGC, (GContext) 0); - if (pBuffer->pRestoreGC) FreeGC(pBuffer->pRestoreGC, (GContext) 0); + if (pBuffer) { + if (pBuffer->pSourceGC) + FreeGC(pBuffer->pSourceGC, (GContext) 0); + if (pBuffer->pMaskGC) + FreeGC(pBuffer->pMaskGC, (GContext) 0); + if (pBuffer->pSaveGC) + FreeGC(pBuffer->pSaveGC, (GContext) 0); + if (pBuffer->pRestoreGC) + FreeGC(pBuffer->pRestoreGC, (GContext) 0); #ifdef ARGB_CURSOR /* If a pRootPicture was allocated for a root window, it @@ -574,10 +562,12 @@ miDCDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) * free it again here. */ #endif - if (pBuffer->pSave) (*pScreen->DestroyPixmap)(pBuffer->pSave); + if (pBuffer->pSave) + (*pScreen->DestroyPixmap) (pBuffer->pSave); free(pBuffer); - dixSetScreenPrivate(&pDev->devPrivates, miDCDeviceKey, pScreen, NULL); + dixSetScreenPrivate(&pDev->devPrivates, miDCDeviceKey, pScreen, + NULL); } } } diff --git a/xorg-server/mi/mieq.c b/xorg-server/mi/mieq.c index 6c46eb9fe..e117a8db7 100644 --- a/xorg-server/mi/mieq.c +++ b/xorg-server/mi/mieq.c @@ -36,27 +36,27 @@ in this Software without prior written authorization from The Open Group. #include <dix-config.h> #endif -# include <X11/X.h> -# include <X11/Xmd.h> -# include <X11/Xproto.h> -# include "misc.h" -# include "windowstr.h" -# include "pixmapstr.h" -# include "inputstr.h" -# include "inpututils.h" -# include "mi.h" -# include "mipointer.h" -# include "scrnintstr.h" -# include <X11/extensions/XI.h> -# include <X11/extensions/XIproto.h> -# include <X11/extensions/geproto.h> -# include "extinit.h" -# include "exglobals.h" -# include "eventstr.h" +#include <X11/X.h> +#include <X11/Xmd.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "inputstr.h" +#include "inpututils.h" +#include "mi.h" +#include "mipointer.h" +#include "scrnintstr.h" +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include <X11/extensions/geproto.h> +#include "extinit.h" +#include "exglobals.h" +#include "eventstr.h" #ifdef DPMSExtension -# include "dpmsproc.h" -# include <X11/extensions/dpmsconst.h> +#include "dpmsproc.h" +#include <X11/extensions/dpmsconst.h> #endif /* Maximum size should be initial size multiplied by a power of 2 */ @@ -70,19 +70,19 @@ in this Software without prior written authorization from The Open Group. #define DequeueScreen(dev) dev->spriteInfo->sprite->pDequeueScreen typedef struct _Event { - InternalEvent* events; - ScreenPtr pScreen; - DeviceIntPtr pDev; /* device this event _originated_ from */ + InternalEvent *events; + ScreenPtr pScreen; + DeviceIntPtr pDev; /* device this event _originated_ from */ } EventRec, *EventPtr; typedef struct _EventQueue { - HWEventQueueType head, tail; /* long for SetInputCheck */ - CARD32 lastEventTime; /* to avoid time running backwards */ - int lastMotion; /* device ID if last event motion? */ - EventRec *events; /* our queue as an array */ - size_t nevents; /* the number of buckets in our queue */ - size_t dropped; /* counter for number of consecutive dropped events */ - mieqHandler handlers[128]; /* custom event handler */ + HWEventQueueType head, tail; /* long for SetInputCheck */ + CARD32 lastEventTime; /* to avoid time running backwards */ + int lastMotion; /* device ID if last event motion? */ + EventRec *events; /* our queue as an array */ + size_t nevents; /* the number of buckets in our queue */ + size_t dropped; /* counter for number of consecutive dropped events */ + mieqHandler handlers[128]; /* custom event handler */ } EventQueueRec, *EventQueuePtr; static EventQueueRec miEventQueue; @@ -95,11 +95,13 @@ extern BOOL serverRunning; extern pthread_mutex_t serverRunningMutex; extern pthread_cond_t serverRunningCond; -static inline void wait_for_server_init(void) { +static inline void +wait_for_server_init(void) +{ /* If the server hasn't finished initializing, wait for it... */ - if(!serverRunning) { + if (!serverRunning) { pthread_mutex_lock(&serverRunningMutex); - while(!serverRunning) + while (!serverRunning) pthread_cond_wait(&serverRunningCond, &serverRunningMutex); pthread_mutex_unlock(&serverRunningMutex); } @@ -107,8 +109,10 @@ static inline void wait_for_server_init(void) { #endif static size_t -mieqNumEnqueued(EventQueuePtr eventQueue) { +mieqNumEnqueued(EventQueuePtr eventQueue) +{ size_t n_enqueued = 0; + if (eventQueue->nevents) { /* % is not well-defined with negative numbers... sigh */ n_enqueued = eventQueue->tail - eventQueue->head + eventQueue->nevents; @@ -120,7 +124,8 @@ mieqNumEnqueued(EventQueuePtr eventQueue) { /* Pre-condition: Called with miEventQueueMutex held */ static Bool -mieqGrowQueue(EventQueuePtr eventQueue, size_t new_nevents) { +mieqGrowQueue(EventQueuePtr eventQueue, size_t new_nevents) +{ size_t i, n_enqueued, first_hunk; EventRec *new_events; @@ -151,14 +156,15 @@ mieqGrowQueue(EventQueuePtr eventQueue, size_t new_nevents) { &eventQueue->events[eventQueue->head], first_hunk * sizeof(EventRec)); memcpy(&new_events[first_hunk], - eventQueue->events, - eventQueue->head * sizeof(EventRec)); + eventQueue->events, eventQueue->head * sizeof(EventRec)); /* Initialize the new portion */ for (i = eventQueue->nevents; i < new_nevents; i++) { - InternalEvent* evlist = InitEventList(1); + InternalEvent *evlist = InitEventList(1); + if (!evlist) { size_t j; + for (j = 0; j < i; j++) FreeEventList(new_events[j].events, 1); free(new_events); @@ -183,10 +189,10 @@ Bool mieqInit(void) { memset(&miEventQueue, 0, sizeof(miEventQueue)); - miEventQueue.lastEventTime = GetTimeInMillis (); + miEventQueue.lastEventTime = GetTimeInMillis(); - if(!mieqGrowQueue(&miEventQueue, QUEUE_INITIAL_SIZE)) - FatalError("Could not allocate event queue.\n"); + if (!mieqGrowQueue(&miEventQueue, QUEUE_INITIAL_SIZE)) + FatalError("Could not allocate event queue.\n"); SetInputCheck(&miEventQueue.head, &miEventQueue.tail); return TRUE; @@ -196,12 +202,12 @@ void mieqFini(void) { int i; - for (i = 0; i < miEventQueue.nevents; i++) - { - if (miEventQueue.events[i].events != NULL) { - FreeEventList(miEventQueue.events[i].events, 1); - miEventQueue.events[i].events = NULL; - } + + for (i = 0; i < miEventQueue.nevents; i++) { + if (miEventQueue.events[i].events != NULL) { + FreeEventList(miEventQueue.events[i].events, 1); + miEventQueue.events[i].events = NULL; + } } free(miEventQueue.events); } @@ -210,19 +216,20 @@ mieqFini(void) * queue space. */ static Bool -mieqReservedCandidate(InternalEvent *e) { - switch(e->any.type) { - case ET_KeyRelease: - case ET_ButtonRelease: +mieqReservedCandidate(InternalEvent *e) +{ + switch (e->any.type) { + case ET_KeyRelease: + case ET_ButtonRelease: #if XFreeXDGA - case ET_DGAEvent: + case ET_DGAEvent: #endif - case ET_RawKeyRelease: - case ET_RawButtonRelease: - case ET_XQuartz: - return TRUE; - default: - return FALSE; + case ET_RawKeyRelease: + case ET_RawButtonRelease: + case ET_XQuartz: + return TRUE; + default: + return FALSE; } } @@ -236,12 +243,12 @@ mieqReservedCandidate(InternalEvent *e) { void mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) { - unsigned int oldtail = miEventQueue.tail; - InternalEvent* evt; - int isMotion = 0; - int evlen; - Time time; - size_t n_enqueued; + unsigned int oldtail = miEventQueue.tail; + InternalEvent *evt; + int isMotion = 0; + int evlen; + Time time; + size_t n_enqueued; #ifdef XQUARTZ wait_for_server_init(); @@ -259,23 +266,33 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) if (isMotion && isMotion == miEventQueue.lastMotion && oldtail != miEventQueue.head) { oldtail = (oldtail - 1) % miEventQueue.nevents; - } else if ((n_enqueued + 1 == miEventQueue.nevents) || - ((n_enqueued + 1 >= miEventQueue.nevents - QUEUE_RESERVED_SIZE) && !mieqReservedCandidate(e))) { + } + else if ((n_enqueued + 1 == miEventQueue.nevents) || + ((n_enqueued + 1 >= miEventQueue.nevents - QUEUE_RESERVED_SIZE) && + !mieqReservedCandidate(e))) { /* Toss events which come in late. Usually this means your server's * stuck in an infinite loop somewhere, but SIGIO is still getting * handled. */ miEventQueue.dropped++; if (miEventQueue.dropped == 1) { - ErrorF("[mi] EQ overflowing. Additional events will be discarded until existing events are processed.\n"); + ErrorF + ("[mi] EQ overflowing. Additional events will be discarded until existing events are processed.\n"); xorg_backtrace(); - ErrorF("[mi] These backtraces from mieqEnqueue may point to a culprit higher up the stack.\n"); + ErrorF + ("[mi] These backtraces from mieqEnqueue may point to a culprit higher up the stack.\n"); ErrorF("[mi] mieq is *NOT* the cause. It is a victim.\n"); - } else if (miEventQueue.dropped % QUEUE_DROP_BACKTRACE_FREQUENCY == 0 && - miEventQueue.dropped / QUEUE_DROP_BACKTRACE_FREQUENCY <= QUEUE_DROP_BACKTRACE_MAX) { - ErrorF("[mi] EQ overflow continuing. %lu events have been dropped.\n", miEventQueue.dropped); - if (miEventQueue.dropped / QUEUE_DROP_BACKTRACE_FREQUENCY == QUEUE_DROP_BACKTRACE_MAX) { - ErrorF("[mi] No further overflow reports will be reported until the clog is cleared.\n"); + } + else if (miEventQueue.dropped % QUEUE_DROP_BACKTRACE_FREQUENCY == 0 && + miEventQueue.dropped / QUEUE_DROP_BACKTRACE_FREQUENCY <= + QUEUE_DROP_BACKTRACE_MAX) { + ErrorF + ("[mi] EQ overflow continuing. %lu events have been dropped.\n", + miEventQueue.dropped); + if (miEventQueue.dropped / QUEUE_DROP_BACKTRACE_FREQUENCY == + QUEUE_DROP_BACKTRACE_MAX) { + ErrorF + ("[mi] No further overflow reports will be reported until the clog is cleared.\n"); } xorg_backtrace(); } @@ -357,61 +374,60 @@ mieqSetHandler(int event, mieqHandler handler) * Change the device id of the given event to the given device's id. */ static void -ChangeDeviceID(DeviceIntPtr dev, InternalEvent* event) +ChangeDeviceID(DeviceIntPtr dev, InternalEvent *event) { - switch(event->any.type) - { - case ET_Motion: - case ET_KeyPress: - case ET_KeyRelease: - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_ProximityIn: - case ET_ProximityOut: - case ET_Hierarchy: - case ET_DeviceChanged: - case ET_TouchBegin: - case ET_TouchUpdate: - case ET_TouchEnd: - event->device_event.deviceid = dev->id; - break; - case ET_TouchOwnership: - event->touch_ownership_event.deviceid = dev->id; - break; + switch (event->any.type) { + case ET_Motion: + case ET_KeyPress: + case ET_KeyRelease: + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_ProximityIn: + case ET_ProximityOut: + case ET_Hierarchy: + case ET_DeviceChanged: + case ET_TouchBegin: + case ET_TouchUpdate: + case ET_TouchEnd: + event->device_event.deviceid = dev->id; + break; + case ET_TouchOwnership: + event->touch_ownership_event.deviceid = dev->id; + break; #if XFreeXDGA - case ET_DGAEvent: - break; + case ET_DGAEvent: + break; #endif - case ET_RawKeyPress: - case ET_RawKeyRelease: - case ET_RawButtonPress: - case ET_RawButtonRelease: - case ET_RawMotion: - case ET_RawTouchBegin: - case ET_RawTouchEnd: - case ET_RawTouchUpdate: - event->raw_event.deviceid = dev->id; - break; - default: - ErrorF("[mi] Unknown event type (%d), cannot change id.\n", - event->any.type); + case ET_RawKeyPress: + case ET_RawKeyRelease: + case ET_RawButtonPress: + case ET_RawButtonRelease: + case ET_RawMotion: + case ET_RawTouchBegin: + case ET_RawTouchEnd: + case ET_RawTouchUpdate: + event->raw_event.deviceid = dev->id; + break; + default: + ErrorF("[mi] Unknown event type (%d), cannot change id.\n", + event->any.type); } } static void FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev, - InternalEvent* original, InternalEvent *master) + InternalEvent *original, InternalEvent *master) { verify_internal_event(original); verify_internal_event(master); /* Ensure chained button mappings, i.e. that the detail field is the * value of the mapped button on the SD, not the physical button */ if (original->any.type == ET_ButtonPress || - original->any.type == ET_ButtonRelease) - { + original->any.type == ET_ButtonRelease) { int btn = original->device_event.detail.button; + if (!sdev->button) - return; /* Should never happen */ + return; /* Should never happen */ master->device_event.detail.button = sdev->button->map[btn]; } @@ -426,12 +442,12 @@ FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev, */ DeviceIntPtr CopyGetMasterEvent(DeviceIntPtr sdev, - InternalEvent* original, InternalEvent *copy) + InternalEvent *original, InternalEvent *copy) { DeviceIntPtr mdev; int len = original->any.length; int type = original->any.type; - int mtype; /* which master type? */ + int mtype; /* which master type? */ verify_internal_event(original); @@ -444,22 +460,21 @@ CopyGetMasterEvent(DeviceIntPtr sdev, type = original->dga_event.subtype; #endif - switch(type) - { - case ET_KeyPress: - case ET_KeyRelease: - mtype = MASTER_KEYBOARD; - break; - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_Motion: - case ET_ProximityIn: - case ET_ProximityOut: - mtype = MASTER_POINTER; - break; - default: - mtype = MASTER_ATTACHED; - break; + switch (type) { + case ET_KeyPress: + case ET_KeyRelease: + mtype = MASTER_KEYBOARD; + break; + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_Motion: + case ET_ProximityIn: + case ET_ProximityOut: + mtype = MASTER_POINTER; + break; + default: + mtype = MASTER_ATTACHED; + break; } mdev = GetMaster(sdev, mtype); @@ -470,17 +485,16 @@ CopyGetMasterEvent(DeviceIntPtr sdev, return mdev; } - static void mieqMoveToNewScreen(DeviceIntPtr dev, ScreenPtr screen, DeviceEvent *event) { - if (dev && screen && screen != DequeueScreen(dev)) - { + if (dev && screen && screen != DequeueScreen(dev)) { int x = 0, y = 0; + DequeueScreen(dev) = screen; x = event->root_x; y = event->root_y; - NewCurrentScreen (dev, DequeueScreen(dev), x, y); + NewCurrentScreen(dev, DequeueScreen(dev), x, y); } } @@ -490,13 +504,11 @@ mieqMoveToNewScreen(DeviceIntPtr dev, ScreenPtr screen, DeviceEvent *event) * usual event processing cycle. */ void -mieqProcessDeviceEvent(DeviceIntPtr dev, - InternalEvent *event, - ScreenPtr screen) +mieqProcessDeviceEvent(DeviceIntPtr dev, InternalEvent *event, ScreenPtr screen) { mieqHandler handler; DeviceIntPtr master; - InternalEvent mevent; /* master event */ + InternalEvent mevent; /* master event */ verify_internal_event(event); @@ -506,22 +518,22 @@ mieqProcessDeviceEvent(DeviceIntPtr dev, switch (event->any.type) { /* Catch events that include valuator information and check if they * are changing the screen */ - case ET_Motion: - case ET_KeyPress: - case ET_KeyRelease: - case ET_ButtonPress: - case ET_ButtonRelease: - if (!handler) - mieqMoveToNewScreen(dev, screen, &event->device_event); - break; - case ET_TouchBegin: - case ET_TouchUpdate: - case ET_TouchEnd: - if (!handler && (event->device_event.flags & TOUCH_POINTER_EMULATED)) - mieqMoveToNewScreen(dev, screen, &event->device_event); - break; - default: - break; + case ET_Motion: + case ET_KeyPress: + case ET_KeyRelease: + case ET_ButtonPress: + case ET_ButtonRelease: + if (!handler) + mieqMoveToNewScreen(dev, screen, &event->device_event); + break; + case ET_TouchBegin: + case ET_TouchUpdate: + case ET_TouchEnd: + if (!handler && (event->device_event.flags & TOUCH_POINTER_EMULATED)) + mieqMoveToNewScreen(dev, screen, &event->device_event); + break; + default: + break; } master = CopyGetMasterEvent(dev, event, &mevent); @@ -530,16 +542,17 @@ mieqProcessDeviceEvent(DeviceIntPtr dev, /* If someone's registered a custom event handler, let them * steal it. */ - if (handler) - { - int screenNum = dev && DequeueScreen(dev) ? DequeueScreen(dev)->myNum : (screen ? screen->myNum : 0); + if (handler) { + int screenNum = dev && + DequeueScreen(dev) ? DequeueScreen(dev)->myNum : (screen ? screen-> + myNum : 0); handler(screenNum, event, dev); /* Check for the SD's master in case the device got detached * during event processing */ if (master && !IsFloating(dev)) handler(screenNum, &mevent, master); - } else - { + } + else { /* process slave first, then master */ dev->public.processInputProc(event, dev); @@ -557,8 +570,7 @@ mieqProcessInputEvents(void) EventRec *e = NULL; ScreenPtr screen; static InternalEvent event; - DeviceIntPtr dev = NULL, - master = NULL; + DeviceIntPtr dev = NULL, master = NULL; size_t n_enqueued; #ifdef XQUARTZ @@ -569,15 +581,18 @@ mieqProcessInputEvents(void) n_enqueued = mieqNumEnqueued(&miEventQueue); if (n_enqueued >= (miEventQueue.nevents - (2 * QUEUE_RESERVED_SIZE)) && miEventQueue.nevents < QUEUE_MAXIMUM_SIZE) { - ErrorF("[mi] Increasing EQ size to %lu to prevent dropped events.\n", miEventQueue.nevents << 1); + ErrorF("[mi] Increasing EQ size to %lu to prevent dropped events.\n", + miEventQueue.nevents << 1); if (!mieqGrowQueue(&miEventQueue, miEventQueue.nevents << 1)) { ErrorF("[mi] Increasing the size of EQ failed.\n"); } } if (miEventQueue.dropped) { - ErrorF("[mi] EQ processing has resumed after %lu dropped events.\n", miEventQueue.dropped); - ErrorF("[mi] This may be caused my a misbehaving driver monopolizing the server's resources.\n"); + ErrorF("[mi] EQ processing has resumed after %lu dropped events.\n", + miEventQueue.dropped); + ErrorF + ("[mi] This may be caused my a misbehaving driver monopolizing the server's resources.\n"); miEventQueue.dropped = 0; } @@ -585,8 +600,8 @@ mieqProcessInputEvents(void) e = &miEventQueue.events[miEventQueue.head]; event = *e->events; - dev = e->pDev; - screen = e->pScreen; + dev = e->pDev; + screen = e->pScreen; miEventQueue.head = (miEventQueue.head + 1) % miEventQueue.nevents; @@ -597,7 +612,7 @@ mieqProcessInputEvents(void) master = (dev) ? GetMaster(dev, MASTER_ATTACHED) : NULL; if (screenIsSaved == SCREEN_SAVER_ON) - dixSaveScreens (serverClient, SCREEN_SAVER_OFF, ScreenSaverReset); + dixSaveScreens(serverClient, SCREEN_SAVER_OFF, ScreenSaverReset); #ifdef DPMSExtension else if (DPMSPowerLevel != DPMSModeOn) SetScreenSaverTimer(); @@ -620,4 +635,3 @@ mieqProcessInputEvents(void) pthread_mutex_unlock(&miEventQueueMutex); #endif } - diff --git a/xorg-server/mi/miexpose.c b/xorg-server/mi/miexpose.c index 0f1ebe59c..dbb29ca4a 100644 --- a/xorg-server/mi/miexpose.c +++ b/xorg-server/mi/miexpose.c @@ -22,7 +22,6 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved @@ -72,7 +71,6 @@ Equipment Corporation. ******************************************************************/ - #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> #endif @@ -106,7 +104,7 @@ the region package can call this. */ #ifndef RECTLIMIT -#define RECTLIMIT 25 /* pick a number, any number > 8 */ +#define RECTLIMIT 25 /* pick a number, any number > 8 */ #endif /* miHandleExposures @@ -128,131 +126,118 @@ exposing is done by the backing store's GraphicsExpose function, of course. RegionPtr miHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, - GCPtr pGC, int srcx, int srcy, int width, int height, - int dstx, int dsty, unsigned long plane) + GCPtr pGC, int srcx, int srcy, int width, int height, + int dstx, int dsty, unsigned long plane) { - RegionPtr prgnSrcClip; /* drawable-relative source clip */ + RegionPtr prgnSrcClip; /* drawable-relative source clip */ RegionRec rgnSrcRec; - RegionPtr prgnDstClip; /* drawable-relative dest clip */ + RegionPtr prgnDstClip; /* drawable-relative dest clip */ RegionRec rgnDstRec; - BoxRec srcBox; /* unclipped source */ - RegionRec rgnExposed; /* exposed region, calculated source- - relative, made dst relative to - intersect with visible parts of - dest and send events to client, - and then screen relative to paint - the window background - */ + BoxRec srcBox; /* unclipped source */ + RegionRec rgnExposed; /* exposed region, calculated source- + relative, made dst relative to + intersect with visible parts of + dest and send events to client, + and then screen relative to paint + the window background + */ WindowPtr pSrcWin; BoxRec expBox; Bool extents; /* avoid work if we can */ if (!pGC->graphicsExposures && - (pDstDrawable->type == DRAWABLE_PIXMAP) && - ((pSrcDrawable->type == DRAWABLE_PIXMAP) || - (((WindowPtr)pSrcDrawable)->backStorage == NULL))) - return NULL; - + (pDstDrawable->type == DRAWABLE_PIXMAP) && + ((pSrcDrawable->type == DRAWABLE_PIXMAP) || + (((WindowPtr) pSrcDrawable)->backStorage == NULL))) + return NULL; + srcBox.x1 = srcx; srcBox.y1 = srcy; - srcBox.x2 = srcx+width; - srcBox.y2 = srcy+height; - - if (pSrcDrawable->type != DRAWABLE_PIXMAP) - { - BoxRec TsrcBox; - - TsrcBox.x1 = srcx + pSrcDrawable->x; - TsrcBox.y1 = srcy + pSrcDrawable->y; - TsrcBox.x2 = TsrcBox.x1 + width; - TsrcBox.y2 = TsrcBox.y1 + height; - pSrcWin = (WindowPtr) pSrcDrawable; - if (pGC->subWindowMode == IncludeInferiors) - { - prgnSrcClip = NotClippedByChildren (pSrcWin); - if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN) - { - RegionDestroy(prgnSrcClip); - return NULL; - } - } - else - { - if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN) - return NULL; - prgnSrcClip = &rgnSrcRec; - RegionNull(prgnSrcClip); - RegionCopy(prgnSrcClip, &pSrcWin->clipList); - } - RegionTranslate(prgnSrcClip, - -pSrcDrawable->x, -pSrcDrawable->y); + srcBox.x2 = srcx + width; + srcBox.y2 = srcy + height; + + if (pSrcDrawable->type != DRAWABLE_PIXMAP) { + BoxRec TsrcBox; + + TsrcBox.x1 = srcx + pSrcDrawable->x; + TsrcBox.y1 = srcy + pSrcDrawable->y; + TsrcBox.x2 = TsrcBox.x1 + width; + TsrcBox.y2 = TsrcBox.y1 + height; + pSrcWin = (WindowPtr) pSrcDrawable; + if (pGC->subWindowMode == IncludeInferiors) { + prgnSrcClip = NotClippedByChildren(pSrcWin); + if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN) { + RegionDestroy(prgnSrcClip); + return NULL; + } + } + else { + if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN) + return NULL; + prgnSrcClip = &rgnSrcRec; + RegionNull(prgnSrcClip); + RegionCopy(prgnSrcClip, &pSrcWin->clipList); + } + RegionTranslate(prgnSrcClip, -pSrcDrawable->x, -pSrcDrawable->y); } - else - { - BoxRec box; - - if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) && - (srcBox.x2 <= pSrcDrawable->width) && - (srcBox.y2 <= pSrcDrawable->height)) - return NULL; - - box.x1 = 0; - box.y1 = 0; - box.x2 = pSrcDrawable->width; - box.y2 = pSrcDrawable->height; - prgnSrcClip = &rgnSrcRec; - RegionInit(prgnSrcClip, &box, 1); - pSrcWin = NULL; + else { + BoxRec box; + + if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) && + (srcBox.x2 <= pSrcDrawable->width) && + (srcBox.y2 <= pSrcDrawable->height)) + return NULL; + + box.x1 = 0; + box.y1 = 0; + box.x2 = pSrcDrawable->width; + box.y2 = pSrcDrawable->height; + prgnSrcClip = &rgnSrcRec; + RegionInit(prgnSrcClip, &box, 1); + pSrcWin = NULL; } - if (pDstDrawable == pSrcDrawable) - { - prgnDstClip = prgnSrcClip; + if (pDstDrawable == pSrcDrawable) { + prgnDstClip = prgnSrcClip; } - else if (pDstDrawable->type != DRAWABLE_PIXMAP) - { - if (pGC->subWindowMode == IncludeInferiors) - { - prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable); - } - else - { - prgnDstClip = &rgnDstRec; - RegionNull(prgnDstClip); - RegionCopy(prgnDstClip, - &((WindowPtr)pDstDrawable)->clipList); - } - RegionTranslate(prgnDstClip, - -pDstDrawable->x, -pDstDrawable->y); + else if (pDstDrawable->type != DRAWABLE_PIXMAP) { + if (pGC->subWindowMode == IncludeInferiors) { + prgnDstClip = NotClippedByChildren((WindowPtr) pDstDrawable); + } + else { + prgnDstClip = &rgnDstRec; + RegionNull(prgnDstClip); + RegionCopy(prgnDstClip, &((WindowPtr) pDstDrawable)->clipList); + } + RegionTranslate(prgnDstClip, -pDstDrawable->x, -pDstDrawable->y); } - else - { - BoxRec box; - - box.x1 = 0; - box.y1 = 0; - box.x2 = pDstDrawable->width; - box.y2 = pDstDrawable->height; - prgnDstClip = &rgnDstRec; - RegionInit(prgnDstClip, &box, 1); + else { + BoxRec box; + + box.x1 = 0; + box.y1 = 0; + box.x2 = pDstDrawable->width; + box.y2 = pDstDrawable->height; + prgnDstClip = &rgnDstRec; + RegionInit(prgnDstClip, &box, 1); } /* drawable-relative source region */ RegionInit(&rgnExposed, &srcBox, 1); - /* now get the hidden parts of the source box*/ + /* now get the hidden parts of the source box */ RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip); /* move them over the destination */ - RegionTranslate(&rgnExposed, dstx-srcx, dsty-srcy); + RegionTranslate(&rgnExposed, dstx - srcx, dsty - srcy); /* intersect with visible areas of dest */ RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip); /* intersect with client clip region. */ if (pGC->clientClipType == CT_REGION) - RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip); + RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip); /* * If we have LOTS of rectangles, we decide to take the extents @@ -262,135 +247,121 @@ miHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, * for windows. */ extents = pGC->graphicsExposures && - (RegionNumRects(&rgnExposed) > RECTLIMIT) && - (pDstDrawable->type != DRAWABLE_PIXMAP); - if (pSrcWin) - { - RegionPtr region; - if (!(region = wClipShape (pSrcWin))) - region = wBoundingShape (pSrcWin); - /* - * If you try to CopyArea the extents of a shaped window, compacting the - * exposed region will undo all our work! - */ - if (extents && pSrcWin && region && - (RegionContainsRect(region, &srcBox) != rgnIN)) - extents = FALSE; + (RegionNumRects(&rgnExposed) > RECTLIMIT) && + (pDstDrawable->type != DRAWABLE_PIXMAP); + if (pSrcWin) { + RegionPtr region; + + if (!(region = wClipShape(pSrcWin))) + region = wBoundingShape(pSrcWin); + /* + * If you try to CopyArea the extents of a shaped window, compacting the + * exposed region will undo all our work! + */ + if (extents && pSrcWin && region && + (RegionContainsRect(region, &srcBox) != rgnIN)) + extents = FALSE; } - if (extents) - { - expBox = *RegionExtents(&rgnExposed); - RegionReset(&rgnExposed, &expBox); + if (extents) { + expBox = *RegionExtents(&rgnExposed); + RegionReset(&rgnExposed, &expBox); } if ((pDstDrawable->type != DRAWABLE_PIXMAP) && - (((WindowPtr)pDstDrawable)->backgroundState != None)) - { - WindowPtr pWin = (WindowPtr)pDstDrawable; - - /* make the exposed area screen-relative */ - RegionTranslate(&rgnExposed, - pDstDrawable->x, pDstDrawable->y); - - if (extents) - { - /* miPaintWindow doesn't clip, so we have to */ - RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList); - } - miPaintWindow((WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND); - - if (extents) - { - RegionReset(&rgnExposed, &expBox); - } - else - RegionTranslate(&rgnExposed, - -pDstDrawable->x, -pDstDrawable->y); + (((WindowPtr) pDstDrawable)->backgroundState != None)) { + WindowPtr pWin = (WindowPtr) pDstDrawable; + + /* make the exposed area screen-relative */ + RegionTranslate(&rgnExposed, pDstDrawable->x, pDstDrawable->y); + + if (extents) { + /* miPaintWindow doesn't clip, so we have to */ + RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList); + } + miPaintWindow((WindowPtr) pDstDrawable, &rgnExposed, PW_BACKGROUND); + + if (extents) { + RegionReset(&rgnExposed, &expBox); + } + else + RegionTranslate(&rgnExposed, -pDstDrawable->x, -pDstDrawable->y); } - if (prgnDstClip == &rgnDstRec) - { - RegionUninit(prgnDstClip); + if (prgnDstClip == &rgnDstRec) { + RegionUninit(prgnDstClip); } - else if (prgnDstClip != prgnSrcClip) - { - RegionDestroy(prgnDstClip); + else if (prgnDstClip != prgnSrcClip) { + RegionDestroy(prgnDstClip); } - if (prgnSrcClip == &rgnSrcRec) - { - RegionUninit(prgnSrcClip); + if (prgnSrcClip == &rgnSrcRec) { + RegionUninit(prgnSrcClip); } - else - { - RegionDestroy(prgnSrcClip); + else { + RegionDestroy(prgnSrcClip); } - if (pGC->graphicsExposures) - { - /* don't look */ - RegionPtr exposed = RegionCreate(NullBox, 0); - *exposed = rgnExposed; - return exposed; + if (pGC->graphicsExposures) { + /* don't look */ + RegionPtr exposed = RegionCreate(NullBox, 0); + + *exposed = rgnExposed; + return exposed; } - else - { - RegionUninit(&rgnExposed); - return NULL; + else { + RegionUninit(&rgnExposed); + return NULL; } } /* send GraphicsExpose events, or a NoExpose event, based on the region */ void -miSendGraphicsExpose (ClientPtr client, RegionPtr pRgn, XID drawable, - int major, int minor) +miSendGraphicsExpose(ClientPtr client, RegionPtr pRgn, XID drawable, + int major, int minor) { - if (pRgn && !RegionNil(pRgn)) - { + if (pRgn && !RegionNil(pRgn)) { xEvent *pEvent; - xEvent *pe; - BoxPtr pBox; - int i; - int numRects; - - numRects = RegionNumRects(pRgn); - pBox = RegionRects(pRgn); - if(!(pEvent = malloc(numRects * sizeof(xEvent)))) - return; - pe = pEvent; - - for (i=1; i<=numRects; i++, pe++, pBox++) - { - pe->u.u.type = GraphicsExpose; - pe->u.graphicsExposure.drawable = drawable; - pe->u.graphicsExposure.x = pBox->x1; - pe->u.graphicsExposure.y = pBox->y1; - pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; - pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; - pe->u.graphicsExposure.count = numRects - i; - pe->u.graphicsExposure.majorEvent = major; - pe->u.graphicsExposure.minorEvent = minor; - } - /* GraphicsExpose is a "critical event", which TryClientEvents - * handles specially. */ - TryClientEvents(client, NULL, pEvent, numRects, - (Mask)0, NoEventMask, NullGrab); - free(pEvent); + xEvent *pe; + BoxPtr pBox; + int i; + int numRects; + + numRects = RegionNumRects(pRgn); + pBox = RegionRects(pRgn); + if (!(pEvent = malloc(numRects * sizeof(xEvent)))) + return; + pe = pEvent; + + for (i = 1; i <= numRects; i++, pe++, pBox++) { + pe->u.u.type = GraphicsExpose; + pe->u.graphicsExposure.drawable = drawable; + pe->u.graphicsExposure.x = pBox->x1; + pe->u.graphicsExposure.y = pBox->y1; + pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; + pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; + pe->u.graphicsExposure.count = numRects - i; + pe->u.graphicsExposure.majorEvent = major; + pe->u.graphicsExposure.minorEvent = minor; + } + /* GraphicsExpose is a "critical event", which TryClientEvents + * handles specially. */ + TryClientEvents(client, NULL, pEvent, numRects, + (Mask) 0, NoEventMask, NullGrab); + free(pEvent); } - else - { + else { xEvent event; - memset(&event, 0, sizeof(xEvent)); - event.u.u.type = NoExpose; - event.u.noExposure.drawable = drawable; - event.u.noExposure.majorEvent = major; - event.u.noExposure.minorEvent = minor; - WriteEventsToClient(client, 1, &event); + + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = NoExpose; + event.u.noExposure.drawable = drawable; + event.u.noExposure.majorEvent = major; + event.u.noExposure.minorEvent = minor; + WriteEventsToClient(client, 1, &event); } } - void -miSendExposures( WindowPtr pWin, RegionPtr pRgn, int dx, int dy) +miSendExposures(WindowPtr pWin, RegionPtr pRgn, int dx, int dy) { BoxPtr pBox; int numRects; @@ -399,48 +370,49 @@ miSendExposures( WindowPtr pWin, RegionPtr pRgn, int dx, int dy) pBox = RegionRects(pRgn); numRects = RegionNumRects(pRgn); - if(!(pEvent = calloc(1, numRects * sizeof(xEvent)))) - return; - - for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++) - { - pe->u.u.type = Expose; - pe->u.expose.window = pWin->drawable.id; - pe->u.expose.x = pBox->x1 - dx; - pe->u.expose.y = pBox->y1 - dy; - pe->u.expose.width = pBox->x2 - pBox->x1; - pe->u.expose.height = pBox->y2 - pBox->y1; - pe->u.expose.count = i; + if (!(pEvent = calloc(1, numRects * sizeof(xEvent)))) + return; + + for (i = numRects, pe = pEvent; --i >= 0; pe++, pBox++) { + pe->u.u.type = Expose; + pe->u.expose.window = pWin->drawable.id; + pe->u.expose.x = pBox->x1 - dx; + pe->u.expose.y = pBox->y1 - dy; + pe->u.expose.width = pBox->x2 - pBox->x1; + pe->u.expose.height = pBox->y2 - pBox->y1; + pe->u.expose.count = i; } #ifdef PANORAMIX - if(!noPanoramiXExtension) { - int scrnum = pWin->drawable.pScreen->myNum; - int x = 0, y = 0; - XID realWin = 0; - - if(!pWin->parent) { - x = screenInfo.screens[scrnum]->x; - y = screenInfo.screens[scrnum]->y; - pWin = screenInfo.screens[0]->root; - realWin = pWin->drawable.id; - } else if (scrnum) { - PanoramiXRes *win; - win = PanoramiXFindIDByScrnum(XRT_WINDOW, - pWin->drawable.id, scrnum); - if(!win) { - free(pEvent); - return; - } - realWin = win->info[0].id; - dixLookupWindow(&pWin, realWin, serverClient, DixSendAccess); - } - if(x || y || scrnum) - for (i = 0; i < numRects; i++) { - pEvent[i].u.expose.window = realWin; - pEvent[i].u.expose.x += x; - pEvent[i].u.expose.y += y; - } + if (!noPanoramiXExtension) { + int scrnum = pWin->drawable.pScreen->myNum; + int x = 0, y = 0; + XID realWin = 0; + + if (!pWin->parent) { + x = screenInfo.screens[scrnum]->x; + y = screenInfo.screens[scrnum]->y; + pWin = screenInfo.screens[0]->root; + realWin = pWin->drawable.id; + } + else if (scrnum) { + PanoramiXRes *win; + + win = PanoramiXFindIDByScrnum(XRT_WINDOW, + pWin->drawable.id, scrnum); + if (!win) { + free(pEvent); + return; + } + realWin = win->info[0].id; + dixLookupWindow(&pWin, realWin, serverClient, DixSendAccess); + } + if (x || y || scrnum) + for (i = 0; i < numRects; i++) { + pEvent[i].u.expose.window = realWin; + pEvent[i].u.expose.x += x; + pEvent[i].u.expose.y += y; + } } #endif @@ -450,69 +422,66 @@ miSendExposures( WindowPtr pWin, RegionPtr pRgn, int dx, int dy) } void -miWindowExposures( WindowPtr pWin, RegionPtr prgn, RegionPtr other_exposed) +miWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr other_exposed) { - RegionPtr exposures = prgn; + RegionPtr exposures = prgn; + if ((prgn && !RegionNil(prgn)) || - (exposures && !RegionNil(exposures)) || other_exposed) - { - RegionRec expRec; - int clientInterested; - - /* - * Restore from backing-store FIRST. - */ - clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask; - if (other_exposed) - { - if (exposures) - { - RegionUnion(other_exposed, - exposures, - other_exposed); - if (exposures != prgn) - RegionDestroy(exposures); - } - exposures = other_exposed; - } - if (clientInterested && exposures && (RegionNumRects(exposures) > RECTLIMIT)) - { - /* - * If we have LOTS of rectangles, we decide to take the extents - * and force an exposure on that. This should require much less - * work overall, on both client and server. This is cheating, but - * isn't prohibited by the protocol ("spontaneous combustion" :-). - */ - BoxRec box; - - box = *RegionExtents(exposures); - if (exposures == prgn) { - exposures = &expRec; - RegionInit(exposures, &box, 1); - RegionReset(prgn, &box); - } else { - RegionReset(exposures, &box); - RegionUnion(prgn, prgn, exposures); - } - /* miPaintWindow doesn't clip, so we have to */ - RegionIntersect(prgn, prgn, &pWin->clipList); - } - if (prgn && !RegionNil(prgn)) - miPaintWindow(pWin, prgn, PW_BACKGROUND); - if (clientInterested && exposures && !RegionNil(exposures)) - miSendExposures(pWin, exposures, - pWin->drawable.x, pWin->drawable.y); - if (exposures == &expRec) - { - RegionUninit(exposures); - } - else if (exposures && exposures != prgn && exposures != other_exposed) - RegionDestroy(exposures); - if (prgn) - RegionEmpty(prgn); + (exposures && !RegionNil(exposures)) || other_exposed) { + RegionRec expRec; + int clientInterested; + + /* + * Restore from backing-store FIRST. + */ + clientInterested = + (pWin->eventMask | wOtherEventMasks(pWin)) & ExposureMask; + if (other_exposed) { + if (exposures) { + RegionUnion(other_exposed, exposures, other_exposed); + if (exposures != prgn) + RegionDestroy(exposures); + } + exposures = other_exposed; + } + if (clientInterested && exposures && + (RegionNumRects(exposures) > RECTLIMIT)) { + /* + * If we have LOTS of rectangles, we decide to take the extents + * and force an exposure on that. This should require much less + * work overall, on both client and server. This is cheating, but + * isn't prohibited by the protocol ("spontaneous combustion" :-). + */ + BoxRec box; + + box = *RegionExtents(exposures); + if (exposures == prgn) { + exposures = &expRec; + RegionInit(exposures, &box, 1); + RegionReset(prgn, &box); + } + else { + RegionReset(exposures, &box); + RegionUnion(prgn, prgn, exposures); + } + /* miPaintWindow doesn't clip, so we have to */ + RegionIntersect(prgn, prgn, &pWin->clipList); + } + if (prgn && !RegionNil(prgn)) + miPaintWindow(pWin, prgn, PW_BACKGROUND); + if (clientInterested && exposures && !RegionNil(exposures)) + miSendExposures(pWin, exposures, + pWin->drawable.x, pWin->drawable.y); + if (exposures == &expRec) { + RegionUninit(exposures); + } + else if (exposures && exposures != prgn && exposures != other_exposed) + RegionDestroy(exposures); + if (prgn) + RegionEmpty(prgn); } else if (exposures && exposures != prgn) - RegionDestroy(exposures); + RegionDestroy(exposures); } #ifdef ROOTLESS @@ -521,97 +490,97 @@ void RootlessSetPixmapOfAncestors(WindowPtr pWin); void RootlessStartDrawing(WindowPtr pWin); void RootlessDamageRegion(WindowPtr pWin, RegionPtr prgn); Bool IsFramedWindow(WindowPtr pWin); -#endif +#endif void miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) { - ScreenPtr pScreen = pWin->drawable.pScreen; + ScreenPtr pScreen = pWin->drawable.pScreen; ChangeGCVal gcval[6]; - BITS32 gcmask; - GCPtr pGC; - int i; - BoxPtr pbox; - xRectangle *prect; - int numRects; + BITS32 gcmask; + GCPtr pGC; + int i; + BoxPtr pbox; + xRectangle *prect; + int numRects; + /* * Distance from screen to destination drawable, use this * to adjust rendering coordinates which come in in screen space */ - int draw_x_off, draw_y_off; + int draw_x_off, draw_y_off; + /* * Tile offset for drawing; these need to align the tile * to the appropriate window origin */ - int tile_x_off, tile_y_off; - PixUnion fill; - Bool solid = TRUE; - DrawablePtr drawable = &pWin->drawable; + int tile_x_off, tile_y_off; + PixUnion fill; + Bool solid = TRUE; + DrawablePtr drawable = &pWin->drawable; #ifdef ROOTLESS - if(!drawable || drawable->type == UNDRAWABLE_WINDOW) - return; + if (!drawable || drawable->type == UNDRAWABLE_WINDOW) + return; - if(IsFramedWindow(pWin)) { + if (IsFramedWindow(pWin)) { RootlessStartDrawing(pWin); RootlessDamageRegion(pWin, prgn); - - if(pWin->backgroundState == ParentRelative) { - if((what == PW_BACKGROUND) || - (what == PW_BORDER && !pWin->borderIsPixel)) + + if (pWin->backgroundState == ParentRelative) { + if ((what == PW_BACKGROUND) || + (what == PW_BORDER && !pWin->borderIsPixel)) RootlessSetPixmapOfAncestors(pWin); } } #endif - - if (what == PW_BACKGROUND) - { - while (pWin->backgroundState == ParentRelative) - pWin = pWin->parent; - - draw_x_off = drawable->x; - draw_y_off = drawable->y; - - tile_x_off = pWin->drawable.x - draw_x_off; - tile_y_off = pWin->drawable.y - draw_y_off; - fill = pWin->background; + + if (what == PW_BACKGROUND) { + while (pWin->backgroundState == ParentRelative) + pWin = pWin->parent; + + draw_x_off = drawable->x; + draw_y_off = drawable->y; + + tile_x_off = pWin->drawable.x - draw_x_off; + tile_y_off = pWin->drawable.y - draw_y_off; + fill = pWin->background; #ifdef COMPOSITE - if (pWin->inhibitBGPaint) - return; + if (pWin->inhibitBGPaint) + return; #endif - switch (pWin->backgroundState) { - case None: - return; - case BackgroundPixmap: - solid = FALSE; - break; - } + switch (pWin->backgroundState) { + case None: + return; + case BackgroundPixmap: + solid = FALSE; + break; + } } - else - { - PixmapPtr pixmap; - - tile_x_off = drawable->x; - tile_y_off = drawable->y; - - /* servers without pixmaps draw their own borders */ - if (!pScreen->GetWindowPixmap) - return; - pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); - drawable = &pixmap->drawable; + else { + PixmapPtr pixmap; + + tile_x_off = drawable->x; + tile_y_off = drawable->y; + + /* servers without pixmaps draw their own borders */ + if (!pScreen->GetWindowPixmap) + return; + pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); + drawable = &pixmap->drawable; #ifdef COMPOSITE - draw_x_off = pixmap->screen_x; - draw_y_off = pixmap->screen_y; - tile_x_off -= draw_x_off; - tile_y_off -= draw_y_off; + draw_x_off = pixmap->screen_x; + draw_y_off = pixmap->screen_y; + tile_x_off -= draw_x_off; + tile_y_off -= draw_y_off; #else - draw_x_off = 0; - draw_y_off = 0; + draw_x_off = 0; + draw_y_off = 0; #endif - fill = pWin->border; - solid = pWin->borderIsPixel; + fill = pWin->border; + solid = pWin->borderIsPixel; } - + gcval[0].val = GXcopy; gcmask = GCFunction; @@ -622,62 +591,60 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) */ #define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0) #endif - - if (solid) - { + + if (solid) { #ifdef ROOTLESS_SAFEALPHA - gcval[1].val = fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel); + gcval[1].val = + fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel); #else - gcval[1].val = fill.pixel; + gcval[1].val = fill.pixel; #endif - gcval[2].val = FillSolid; - gcmask |= GCForeground | GCFillStyle; + gcval[2].val = FillSolid; + gcmask |= GCForeground | GCFillStyle; } - else - { - int c=1; + else { + int c = 1; + #ifdef ROOTLESS_SAFEALPHA - gcval[c++].val = ((CARD32)-1) & ~RootlessAlphaMask(pWin->drawable.bitsPerPixel); - gcmask |= GCPlaneMask; + gcval[c++].val = + ((CARD32) -1) & ~RootlessAlphaMask(pWin->drawable.bitsPerPixel); + gcmask |= GCPlaneMask; #endif - gcval[c++].val = FillTiled; - gcval[c++].ptr = (pointer)fill.pixmap; - gcval[c++].val = tile_x_off; - gcval[c++].val = tile_y_off; - gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; + gcval[c++].val = FillTiled; + gcval[c++].ptr = (pointer) fill.pixmap; + gcval[c++].val = tile_x_off; + gcval[c++].val = tile_y_off; + gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; } prect = malloc(RegionNumRects(prgn) * sizeof(xRectangle)); if (!prect) - return; + return; pGC = GetScratchGC(drawable->depth, drawable->pScreen); - if (!pGC) - { - free(prect); - return; + if (!pGC) { + free(prect); + return; } - - ChangeGC (NullClient, pGC, gcmask, gcval); - ValidateGC (drawable, pGC); + + ChangeGC(NullClient, pGC, gcmask, gcval); + ValidateGC(drawable, pGC); numRects = RegionNumRects(prgn); pbox = RegionRects(prgn); - for (i= numRects; --i >= 0; pbox++, prect++) - { - prect->x = pbox->x1 - draw_x_off; - prect->y = pbox->y1 - draw_y_off; - prect->width = pbox->x2 - pbox->x1; - prect->height = pbox->y2 - pbox->y1; + for (i = numRects; --i >= 0; pbox++, prect++) { + prect->x = pbox->x1 - draw_x_off; + prect->y = pbox->y1 - draw_y_off; + prect->width = pbox->x2 - pbox->x1; + prect->height = pbox->y2 - pbox->y1; } prect -= numRects; - (*pGC->ops->PolyFillRect)(drawable, pGC, numRects, prect); + (*pGC->ops->PolyFillRect) (drawable, pGC, numRects, prect); free(prect); FreeScratchGC(pGC); } - /* MICLEARDRAWABLE -- sets the entire drawable to the background color of * the GC. Useful when we have a scratch drawable and need to initialize * it. */ @@ -695,7 +662,7 @@ miClearDrawable(DrawablePtr pDraw, GCPtr pGC) rect.height = pDraw->height; ChangeGC(NullClient, pGC, GCForeground, &bg); ValidateGC(pDraw, pGC); - (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect); + (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &rect); ChangeGC(NullClient, pGC, GCForeground, &fg); ValidateGC(pDraw, pGC); } diff --git a/xorg-server/mi/mifillarc.c b/xorg-server/mi/mifillarc.c index dd0a7b91d..337343dd1 100644 --- a/xorg-server/mi/mifillarc.c +++ b/xorg-server/mi/mifillarc.c @@ -1,798 +1,712 @@ -/************************************************************
-
-Copyright 1989, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-Author: Bob Scheifler, MIT X Consortium
-
-********************************************************/
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <math.h>
-#include <X11/X.h>
-#include <X11/Xprotostr.h>
-#include "regionstr.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "mifpoly.h"
-#include "mi.h"
-#include "mifillarc.h"
-
-#define QUADRANT (90 * 64)
-#define HALFCIRCLE (180 * 64)
-#define QUADRANT3 (270 * 64)
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#define Dsin(d) sin((double)d*(M_PI/11520.0))
-#define Dcos(d) cos((double)d*(M_PI/11520.0))
-
-void
-miFillArcSetup(xArc *arc, miFillArcRec *info)
-{
- info->y = arc->height >> 1;
- info->dy = arc->height & 1;
- info->yorg = arc->y + info->y;
- info->dx = arc->width & 1;
- info->xorg = arc->x + (arc->width >> 1) + info->dx;
- info->dx = 1 - info->dx;
- if (arc->width == arc->height)
- {
- /* (2x - 2xorg)^2 = d^2 - (2y - 2yorg)^2 */
- /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
- info->ym = 8;
- info->xm = 8;
- info->yk = info->y << 3;
- if (!info->dx)
- {
- info->xk = 0;
- info->e = -1;
- }
- else
- {
- info->y++;
- info->yk += 4;
- info->xk = -4;
- info->e = - (info->y << 3);
- }
- }
- else
- {
- /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
- /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
- info->ym = (arc->width * arc->width) << 3;
- info->xm = (arc->height * arc->height) << 3;
- info->yk = info->y * info->ym;
- if (!info->dy)
- info->yk -= info->ym >> 1;
- if (!info->dx)
- {
- info->xk = 0;
- info->e = - (info->xm >> 3);
- }
- else
- {
- info->y++;
- info->yk += info->ym;
- info->xk = -(info->xm >> 1);
- info->e = info->xk - info->yk;
- }
- }
-}
-
-static void
-miFillArcDSetup(xArc *arc, miFillArcDRec *info)
-{
- /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
- /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
- info->y = arc->height >> 1;
- info->dy = arc->height & 1;
- info->yorg = arc->y + info->y;
- info->dx = arc->width & 1;
- info->xorg = arc->x + (arc->width >> 1) + info->dx;
- info->dx = 1 - info->dx;
- info->ym = ((double)arc->width) * (arc->width * 8);
- info->xm = ((double)arc->height) * (arc->height * 8);
- info->yk = info->y * info->ym;
- if (!info->dy)
- info->yk -= info->ym / 2.0;
- if (!info->dx)
- {
- info->xk = 0;
- info->e = - (info->xm / 8.0);
- }
- else
- {
- info->y++;
- info->yk += info->ym;
- info->xk = -info->xm / 2.0;
- info->e = info->xk - info->yk;
- }
-}
-
-static void
-miGetArcEdge(
- xArc *arc,
- miSliceEdgePtr edge,
- int k,
- Bool top,
- Bool left )
-{
- int xady, y;
-
- y = arc->height >> 1;
- if (!(arc->width & 1))
- y++;
- if (!top)
- {
- y = -y;
- if (arc->height & 1)
- y--;
- }
- xady = k + y * edge->dx;
- if (xady <= 0)
- edge->x = - ((-xady) / edge->dy + 1);
- else
- edge->x = (xady - 1) / edge->dy;
- edge->e = xady - edge->x * edge->dy;
- if ((top && (edge->dx < 0)) || (!top && (edge->dx > 0)))
- edge->e = edge->dy - edge->e + 1;
- if (left)
- edge->x++;
- edge->x += arc->x + (arc->width >> 1);
- if (edge->dx > 0)
- {
- edge->deltax = 1;
- edge->stepx = edge->dx / edge->dy;
- edge->dx = edge->dx % edge->dy;
- }
- else
- {
- edge->deltax = -1;
- edge->stepx = - ((-edge->dx) / edge->dy);
- edge->dx = (-edge->dx) % edge->dy;
- }
- if (!top)
- {
- edge->deltax = -edge->deltax;
- edge->stepx = -edge->stepx;
- }
-}
-
-static void
-miEllipseAngleToSlope (int angle, int width, int height, int *dxp, int *dyp,
- double *d_dxp, double *d_dyp)
-{
- int dx, dy;
- double d_dx, d_dy, scale;
- Bool negative_dx, negative_dy;
-
- switch (angle) {
- case 0:
- *dxp = -1;
- *dyp = 0;
- if (d_dxp) {
- *d_dxp = width / 2.0;
- *d_dyp = 0;
- }
- break;
- case QUADRANT:
- *dxp = 0;
- *dyp = 1;
- if (d_dxp) {
- *d_dxp = 0;
- *d_dyp = - height / 2.0;
- }
- break;
- case HALFCIRCLE:
- *dxp = 1;
- *dyp = 0;
- if (d_dxp) {
- *d_dxp = - width / 2.0;
- *d_dyp = 0;
- }
- break;
- case QUADRANT3:
- *dxp = 0;
- *dyp = -1;
- if (d_dxp) {
- *d_dxp = 0;
- *d_dyp = height / 2.0;
- }
- break;
- default:
- d_dx = Dcos(angle) * width;
- d_dy = Dsin(angle) * height;
- if (d_dxp) {
- *d_dxp = d_dx / 2.0;
- *d_dyp = - d_dy / 2.0;
- }
- negative_dx = FALSE;
- if (d_dx < 0.0)
- {
- d_dx = -d_dx;
- negative_dx = TRUE;
- }
- negative_dy = FALSE;
- if (d_dy < 0.0)
- {
- d_dy = -d_dy;
- negative_dy = TRUE;
- }
- scale = d_dx;
- if (d_dy > d_dx)
- scale = d_dy;
- dx = floor ((d_dx * 32768) / scale + 0.5);
- if (negative_dx)
- dx = -dx;
- *dxp = dx;
- dy = floor ((d_dy * 32768) / scale + 0.5);
- if (negative_dy)
- dy = -dy;
- *dyp = dy;
- break;
- }
-}
-
-static void
-miGetPieEdge(
- xArc *arc,
- int angle,
- miSliceEdgePtr edge,
- Bool top,
- Bool left )
-{
- int k;
- int dx, dy;
-
- miEllipseAngleToSlope (angle, arc->width, arc->height, &dx, &dy, 0, 0);
-
- if (dy == 0)
- {
- edge->x = left ? -65536 : 65536;
- edge->stepx = 0;
- edge->e = 0;
- edge->dx = -1;
- return;
- }
- if (dx == 0)
- {
- edge->x = arc->x + (arc->width >> 1);
- if (left && (arc->width & 1))
- edge->x++;
- else if (!left && !(arc->width & 1))
- edge->x--;
- edge->stepx = 0;
- edge->e = 0;
- edge->dx = -1;
- return;
- }
- if (dy < 0) {
- dx = -dx;
- dy = -dy;
- }
- k = (arc->height & 1) ? dx : 0;
- if (arc->width & 1)
- k += dy;
- edge->dx = dx << 1;
- edge->dy = dy << 1;
- miGetArcEdge(arc, edge, k, top, left);
-}
-
-void
-miFillArcSliceSetup(xArc *arc, miArcSliceRec *slice, GCPtr pGC)
-{
- int angle1, angle2;
-
- angle1 = arc->angle1;
- if (arc->angle2 < 0)
- {
- angle2 = angle1;
- angle1 += arc->angle2;
- }
- else
- angle2 = angle1 + arc->angle2;
- while (angle1 < 0)
- angle1 += FULLCIRCLE;
- while (angle1 >= FULLCIRCLE)
- angle1 -= FULLCIRCLE;
- while (angle2 < 0)
- angle2 += FULLCIRCLE;
- while (angle2 >= FULLCIRCLE)
- angle2 -= FULLCIRCLE;
- slice->min_top_y = 0;
- slice->max_top_y = arc->height >> 1;
- slice->min_bot_y = 1 - (arc->height & 1);
- slice->max_bot_y = slice->max_top_y - 1;
- slice->flip_top = FALSE;
- slice->flip_bot = FALSE;
- if (pGC->arcMode == ArcPieSlice)
- {
- slice->edge1_top = (angle1 < HALFCIRCLE);
- slice->edge2_top = (angle2 <= HALFCIRCLE);
- if ((angle2 == 0) || (angle1 == HALFCIRCLE))
- {
- if (angle2 ? slice->edge2_top : slice->edge1_top)
- slice->min_top_y = slice->min_bot_y;
- else
- slice->min_top_y = arc->height;
- slice->min_bot_y = 0;
- }
- else if ((angle1 == 0) || (angle2 == HALFCIRCLE))
- {
- slice->min_top_y = slice->min_bot_y;
- if (angle1 ? slice->edge1_top : slice->edge2_top)
- slice->min_bot_y = arc->height;
- else
- slice->min_bot_y = 0;
- }
- else if (slice->edge1_top == slice->edge2_top)
- {
- if (angle2 < angle1)
- {
- slice->flip_top = slice->edge1_top;
- slice->flip_bot = !slice->edge1_top;
- }
- else if (slice->edge1_top)
- {
- slice->min_top_y = 1;
- slice->min_bot_y = arc->height;
- }
- else
- {
- slice->min_bot_y = 0;
- slice->min_top_y = arc->height;
- }
- }
- miGetPieEdge(arc, angle1, &slice->edge1,
- slice->edge1_top, !slice->edge1_top);
- miGetPieEdge(arc, angle2, &slice->edge2,
- slice->edge2_top, slice->edge2_top);
- }
- else
- {
- double w2, h2, x1, y1, x2, y2, dx, dy, scale;
- int signdx, signdy, y, k;
- Bool isInt1 = TRUE, isInt2 = TRUE;
-
- w2 = (double)arc->width / 2.0;
- h2 = (double)arc->height / 2.0;
- if ((angle1 == 0) || (angle1 == HALFCIRCLE))
- {
- x1 = angle1 ? -w2 : w2;
- y1 = 0.0;
- }
- else if ((angle1 == QUADRANT) || (angle1 == QUADRANT3))
- {
- x1 = 0.0;
- y1 = (angle1 == QUADRANT) ? h2 : -h2;
- }
- else
- {
- isInt1 = FALSE;
- x1 = Dcos(angle1) * w2;
- y1 = Dsin(angle1) * h2;
- }
- if ((angle2 == 0) || (angle2 == HALFCIRCLE))
- {
- x2 = angle2 ? -w2 : w2;
- y2 = 0.0;
- }
- else if ((angle2 == QUADRANT) || (angle2 == QUADRANT3))
- {
- x2 = 0.0;
- y2 = (angle2 == QUADRANT) ? h2 : -h2;
- }
- else
- {
- isInt2 = FALSE;
- x2 = Dcos(angle2) * w2;
- y2 = Dsin(angle2) * h2;
- }
- dx = x2 - x1;
- dy = y2 - y1;
- if (arc->height & 1)
- {
- y1 -= 0.5;
- y2 -= 0.5;
- }
- if (arc->width & 1)
- {
- x1 += 0.5;
- x2 += 0.5;
- }
- if (dy < 0.0)
- {
- dy = -dy;
- signdy = -1;
- }
- else
- signdy = 1;
- if (dx < 0.0)
- {
- dx = -dx;
- signdx = -1;
- }
- else
- signdx = 1;
- if (isInt1 && isInt2)
- {
- slice->edge1.dx = dx * 2;
- slice->edge1.dy = dy * 2;
- }
- else
- {
- scale = (dx > dy) ? dx : dy;
- slice->edge1.dx = floor((dx * 32768) / scale + .5);
- slice->edge1.dy = floor((dy * 32768) / scale + .5);
- }
- if (!slice->edge1.dy)
- {
- if (signdx < 0)
- {
- y = floor(y1 + 1.0);
- if (y >= 0)
- {
- slice->min_top_y = y;
- slice->min_bot_y = arc->height;
- }
- else
- {
- slice->max_bot_y = -y - (arc->height & 1);
- }
- }
- else
- {
- y = floor(y1);
- if (y >= 0)
- slice->max_top_y = y;
- else
- {
- slice->min_top_y = arc->height;
- slice->min_bot_y = -y - (arc->height & 1);
- }
- }
- slice->edge1_top = TRUE;
- slice->edge1.x = 65536;
- slice->edge1.stepx = 0;
- slice->edge1.e = 0;
- slice->edge1.dx = -1;
- slice->edge2 = slice->edge1;
- slice->edge2_top = FALSE;
- }
- else if (!slice->edge1.dx)
- {
- if (signdy < 0)
- x1 -= 1.0;
- slice->edge1.x = ceil(x1);
- slice->edge1_top = signdy < 0;
- slice->edge1.x += arc->x + (arc->width >> 1);
- slice->edge1.stepx = 0;
- slice->edge1.e = 0;
- slice->edge1.dx = -1;
- slice->edge2_top = !slice->edge1_top;
- slice->edge2 = slice->edge1;
- }
- else
- {
- if (signdx < 0)
- slice->edge1.dx = -slice->edge1.dx;
- if (signdy < 0)
- slice->edge1.dx = -slice->edge1.dx;
- k = ceil(((x1 + x2) * slice->edge1.dy - (y1 + y2) * slice->edge1.dx) / 2.0);
- slice->edge2.dx = slice->edge1.dx;
- slice->edge2.dy = slice->edge1.dy;
- slice->edge1_top = signdy < 0;
- slice->edge2_top = !slice->edge1_top;
- miGetArcEdge(arc, &slice->edge1, k,
- slice->edge1_top, !slice->edge1_top);
- miGetArcEdge(arc, &slice->edge2, k,
- slice->edge2_top, slice->edge2_top);
- }
- }
-}
-
-#define ADDSPANS() \
- pts->x = xorg - x; \
- pts->y = yorg - y; \
- *wids = slw; \
- pts++; \
- wids++; \
- if (miFillArcLower(slw)) \
- { \
- pts->x = xorg - x; \
- pts->y = yorg + y + dy; \
- pts++; \
- *wids++ = slw; \
- }
-
-static void
-miFillEllipseI(
- DrawablePtr pDraw,
- GCPtr pGC,
- xArc *arc )
-{
- int x, y, e;
- int yk, xk, ym, xm, dx, dy, xorg, yorg;
- int slw;
- miFillArcRec info;
- DDXPointPtr points;
- DDXPointPtr pts;
- int *widths;
- int *wids;
-
- points = malloc(sizeof(DDXPointRec) * arc->height);
- if (!points)
- return;
- widths = malloc(sizeof(int) * arc->height);
- if (!widths)
- {
- free(points);
- return;
- }
- miFillArcSetup(arc, &info);
- MIFILLARCSETUP();
- if (pGC->miTranslate)
- {
- xorg += pDraw->x;
- yorg += pDraw->y;
- }
- pts = points;
- wids = widths;
- while (y > 0)
- {
- MIFILLARCSTEP(slw);
- ADDSPANS();
- }
- (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
- free(widths);
- free(points);
-}
-
-static void
-miFillEllipseD(
- DrawablePtr pDraw,
- GCPtr pGC,
- xArc *arc )
-{
- int x, y;
- int xorg, yorg, dx, dy, slw;
- double e, yk, xk, ym, xm;
- miFillArcDRec info;
- DDXPointPtr points;
- DDXPointPtr pts;
- int *widths;
- int *wids;
-
- points = malloc(sizeof(DDXPointRec) * arc->height);
- if (!points)
- return;
- widths = malloc(sizeof(int) * arc->height);
- if (!widths)
- {
- free(points);
- return;
- }
- miFillArcDSetup(arc, &info);
- MIFILLARCSETUP();
- if (pGC->miTranslate)
- {
- xorg += pDraw->x;
- yorg += pDraw->y;
- }
- pts = points;
- wids = widths;
- while (y > 0)
- {
- MIFILLARCSTEP(slw);
- ADDSPANS();
- }
- (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
- free(widths);
- free(points);
-}
-
-#define ADDSPAN(l,r) \
- if (r >= l) \
- { \
- pts->x = l; \
- pts->y = ya; \
- pts++; \
- *wids++ = r - l + 1; \
- }
-
-#define ADDSLICESPANS(flip) \
- if (!flip) \
- { \
- ADDSPAN(xl, xr); \
- } \
- else \
- { \
- xc = xorg - x; \
- ADDSPAN(xc, xr); \
- xc += slw - 1; \
- ADDSPAN(xl, xc); \
- }
-
-static void
-miFillArcSliceI(
- DrawablePtr pDraw,
- GCPtr pGC,
- xArc *arc )
-{
- int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
- int x, y, e;
- miFillArcRec info;
- miArcSliceRec slice;
- int ya, xl, xr, xc;
- DDXPointPtr points;
- DDXPointPtr pts;
- int *widths;
- int *wids;
-
- miFillArcSetup(arc, &info);
- miFillArcSliceSetup(arc, &slice, pGC);
- MIFILLARCSETUP();
- slw = arc->height;
- if (slice.flip_top || slice.flip_bot)
- slw += (arc->height >> 1) + 1;
- points = malloc(sizeof(DDXPointRec) * slw);
- if (!points)
- return;
- widths = malloc(sizeof(int) * slw);
- if (!widths)
- {
- free(points);
- return;
- }
- if (pGC->miTranslate)
- {
- xorg += pDraw->x;
- yorg += pDraw->y;
- slice.edge1.x += pDraw->x;
- slice.edge2.x += pDraw->x;
- }
- pts = points;
- wids = widths;
- while (y > 0)
- {
- MIFILLARCSTEP(slw);
- MIARCSLICESTEP(slice.edge1);
- MIARCSLICESTEP(slice.edge2);
- if (miFillSliceUpper(slice))
- {
- ya = yorg - y;
- MIARCSLICEUPPER(xl, xr, slice, slw);
- ADDSLICESPANS(slice.flip_top);
- }
- if (miFillSliceLower(slice))
- {
- ya = yorg + y + dy;
- MIARCSLICELOWER(xl, xr, slice, slw);
- ADDSLICESPANS(slice.flip_bot);
- }
- }
- (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
- free(widths);
- free(points);
-}
-
-static void
-miFillArcSliceD(
- DrawablePtr pDraw,
- GCPtr pGC,
- xArc *arc )
-{
- int x, y;
- int dx, dy, xorg, yorg, slw;
- double e, yk, xk, ym, xm;
- miFillArcDRec info;
- miArcSliceRec slice;
- int ya, xl, xr, xc;
- DDXPointPtr points;
- DDXPointPtr pts;
- int *widths;
- int *wids;
-
- miFillArcDSetup(arc, &info);
- miFillArcSliceSetup(arc, &slice, pGC);
- MIFILLARCSETUP();
- slw = arc->height;
- if (slice.flip_top || slice.flip_bot)
- slw += (arc->height >> 1) + 1;
- points = malloc(sizeof(DDXPointRec) * slw);
- if (!points)
- return;
- widths = malloc(sizeof(int) * slw);
- if (!widths)
- {
- free(points);
- return;
- }
- if (pGC->miTranslate)
- {
- xorg += pDraw->x;
- yorg += pDraw->y;
- slice.edge1.x += pDraw->x;
- slice.edge2.x += pDraw->x;
- }
- pts = points;
- wids = widths;
- while (y > 0)
- {
- MIFILLARCSTEP(slw);
- MIARCSLICESTEP(slice.edge1);
- MIARCSLICESTEP(slice.edge2);
- if (miFillSliceUpper(slice))
- {
- ya = yorg - y;
- MIARCSLICEUPPER(xl, xr, slice, slw);
- ADDSLICESPANS(slice.flip_top);
- }
- if (miFillSliceLower(slice))
- {
- ya = yorg + y + dy;
- MIARCSLICELOWER(xl, xr, slice, slw);
- ADDSLICESPANS(slice.flip_bot);
- }
- }
- (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
- free(widths);
- free(points);
-}
-
-/* MIPOLYFILLARC -- The public entry for the PolyFillArc request.
- * Since we don't have to worry about overlapping segments, we can just
- * fill each arc as it comes.
- */
-void
-miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs)
-{
- int i;
- xArc *arc;
-
- for(i = narcs, arc = parcs; --i >= 0; arc++)
- {
- if (miFillArcEmpty(arc))
- continue;
- if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE))
- {
- if (miCanFillArc(arc))
- miFillEllipseI(pDraw, pGC, arc);
- else
- miFillEllipseD(pDraw, pGC, arc);
- }
- else
- {
- if (miCanFillArc(arc))
- miFillArcSliceI(pDraw, pGC, arc);
- else
- miFillArcSliceD(pDraw, pGC, arc);
- }
- }
-}
+/************************************************************ + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Author: Bob Scheifler, MIT X Consortium + +********************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <math.h> +#include <X11/X.h> +#include <X11/Xprotostr.h> +#include "regionstr.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "mifpoly.h" +#include "mi.h" +#include "mifillarc.h" + +#define QUADRANT (90 * 64) +#define HALFCIRCLE (180 * 64) +#define QUADRANT3 (270 * 64) + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define Dsin(d) sin((double)d*(M_PI/11520.0)) +#define Dcos(d) cos((double)d*(M_PI/11520.0)) + +void +miFillArcSetup(xArc * arc, miFillArcRec * info) +{ + info->y = arc->height >> 1; + info->dy = arc->height & 1; + info->yorg = arc->y + info->y; + info->dx = arc->width & 1; + info->xorg = arc->x + (arc->width >> 1) + info->dx; + info->dx = 1 - info->dx; + if (arc->width == arc->height) { + /* (2x - 2xorg)^2 = d^2 - (2y - 2yorg)^2 */ + /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */ + info->ym = 8; + info->xm = 8; + info->yk = info->y << 3; + if (!info->dx) { + info->xk = 0; + info->e = -1; + } + else { + info->y++; + info->yk += 4; + info->xk = -4; + info->e = -(info->y << 3); + } + } + else { + /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */ + /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */ + info->ym = (arc->width * arc->width) << 3; + info->xm = (arc->height * arc->height) << 3; + info->yk = info->y * info->ym; + if (!info->dy) + info->yk -= info->ym >> 1; + if (!info->dx) { + info->xk = 0; + info->e = -(info->xm >> 3); + } + else { + info->y++; + info->yk += info->ym; + info->xk = -(info->xm >> 1); + info->e = info->xk - info->yk; + } + } +} + +static void +miFillArcDSetup(xArc * arc, miFillArcDRec * info) +{ + /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */ + /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */ + info->y = arc->height >> 1; + info->dy = arc->height & 1; + info->yorg = arc->y + info->y; + info->dx = arc->width & 1; + info->xorg = arc->x + (arc->width >> 1) + info->dx; + info->dx = 1 - info->dx; + info->ym = ((double) arc->width) * (arc->width * 8); + info->xm = ((double) arc->height) * (arc->height * 8); + info->yk = info->y * info->ym; + if (!info->dy) + info->yk -= info->ym / 2.0; + if (!info->dx) { + info->xk = 0; + info->e = -(info->xm / 8.0); + } + else { + info->y++; + info->yk += info->ym; + info->xk = -info->xm / 2.0; + info->e = info->xk - info->yk; + } +} + +static void +miGetArcEdge(xArc * arc, miSliceEdgePtr edge, int k, Bool top, Bool left) +{ + int xady, y; + + y = arc->height >> 1; + if (!(arc->width & 1)) + y++; + if (!top) { + y = -y; + if (arc->height & 1) + y--; + } + xady = k + y * edge->dx; + if (xady <= 0) + edge->x = -((-xady) / edge->dy + 1); + else + edge->x = (xady - 1) / edge->dy; + edge->e = xady - edge->x * edge->dy; + if ((top && (edge->dx < 0)) || (!top && (edge->dx > 0))) + edge->e = edge->dy - edge->e + 1; + if (left) + edge->x++; + edge->x += arc->x + (arc->width >> 1); + if (edge->dx > 0) { + edge->deltax = 1; + edge->stepx = edge->dx / edge->dy; + edge->dx = edge->dx % edge->dy; + } + else { + edge->deltax = -1; + edge->stepx = -((-edge->dx) / edge->dy); + edge->dx = (-edge->dx) % edge->dy; + } + if (!top) { + edge->deltax = -edge->deltax; + edge->stepx = -edge->stepx; + } +} + +static void +miEllipseAngleToSlope(int angle, int width, int height, int *dxp, int *dyp, + double *d_dxp, double *d_dyp) +{ + int dx, dy; + double d_dx, d_dy, scale; + Bool negative_dx, negative_dy; + + switch (angle) { + case 0: + *dxp = -1; + *dyp = 0; + if (d_dxp) { + *d_dxp = width / 2.0; + *d_dyp = 0; + } + break; + case QUADRANT: + *dxp = 0; + *dyp = 1; + if (d_dxp) { + *d_dxp = 0; + *d_dyp = -height / 2.0; + } + break; + case HALFCIRCLE: + *dxp = 1; + *dyp = 0; + if (d_dxp) { + *d_dxp = -width / 2.0; + *d_dyp = 0; + } + break; + case QUADRANT3: + *dxp = 0; + *dyp = -1; + if (d_dxp) { + *d_dxp = 0; + *d_dyp = height / 2.0; + } + break; + default: + d_dx = Dcos(angle) * width; + d_dy = Dsin(angle) * height; + if (d_dxp) { + *d_dxp = d_dx / 2.0; + *d_dyp = -d_dy / 2.0; + } + negative_dx = FALSE; + if (d_dx < 0.0) { + d_dx = -d_dx; + negative_dx = TRUE; + } + negative_dy = FALSE; + if (d_dy < 0.0) { + d_dy = -d_dy; + negative_dy = TRUE; + } + scale = d_dx; + if (d_dy > d_dx) + scale = d_dy; + dx = floor((d_dx * 32768) / scale + 0.5); + if (negative_dx) + dx = -dx; + *dxp = dx; + dy = floor((d_dy * 32768) / scale + 0.5); + if (negative_dy) + dy = -dy; + *dyp = dy; + break; + } +} + +static void +miGetPieEdge(xArc * arc, int angle, miSliceEdgePtr edge, Bool top, Bool left) +{ + int k; + int dx, dy; + + miEllipseAngleToSlope(angle, arc->width, arc->height, &dx, &dy, 0, 0); + + if (dy == 0) { + edge->x = left ? -65536 : 65536; + edge->stepx = 0; + edge->e = 0; + edge->dx = -1; + return; + } + if (dx == 0) { + edge->x = arc->x + (arc->width >> 1); + if (left && (arc->width & 1)) + edge->x++; + else if (!left && !(arc->width & 1)) + edge->x--; + edge->stepx = 0; + edge->e = 0; + edge->dx = -1; + return; + } + if (dy < 0) { + dx = -dx; + dy = -dy; + } + k = (arc->height & 1) ? dx : 0; + if (arc->width & 1) + k += dy; + edge->dx = dx << 1; + edge->dy = dy << 1; + miGetArcEdge(arc, edge, k, top, left); +} + +void +miFillArcSliceSetup(xArc * arc, miArcSliceRec * slice, GCPtr pGC) +{ + int angle1, angle2; + + angle1 = arc->angle1; + if (arc->angle2 < 0) { + angle2 = angle1; + angle1 += arc->angle2; + } + else + angle2 = angle1 + arc->angle2; + while (angle1 < 0) + angle1 += FULLCIRCLE; + while (angle1 >= FULLCIRCLE) + angle1 -= FULLCIRCLE; + while (angle2 < 0) + angle2 += FULLCIRCLE; + while (angle2 >= FULLCIRCLE) + angle2 -= FULLCIRCLE; + slice->min_top_y = 0; + slice->max_top_y = arc->height >> 1; + slice->min_bot_y = 1 - (arc->height & 1); + slice->max_bot_y = slice->max_top_y - 1; + slice->flip_top = FALSE; + slice->flip_bot = FALSE; + if (pGC->arcMode == ArcPieSlice) { + slice->edge1_top = (angle1 < HALFCIRCLE); + slice->edge2_top = (angle2 <= HALFCIRCLE); + if ((angle2 == 0) || (angle1 == HALFCIRCLE)) { + if (angle2 ? slice->edge2_top : slice->edge1_top) + slice->min_top_y = slice->min_bot_y; + else + slice->min_top_y = arc->height; + slice->min_bot_y = 0; + } + else if ((angle1 == 0) || (angle2 == HALFCIRCLE)) { + slice->min_top_y = slice->min_bot_y; + if (angle1 ? slice->edge1_top : slice->edge2_top) + slice->min_bot_y = arc->height; + else + slice->min_bot_y = 0; + } + else if (slice->edge1_top == slice->edge2_top) { + if (angle2 < angle1) { + slice->flip_top = slice->edge1_top; + slice->flip_bot = !slice->edge1_top; + } + else if (slice->edge1_top) { + slice->min_top_y = 1; + slice->min_bot_y = arc->height; + } + else { + slice->min_bot_y = 0; + slice->min_top_y = arc->height; + } + } + miGetPieEdge(arc, angle1, &slice->edge1, + slice->edge1_top, !slice->edge1_top); + miGetPieEdge(arc, angle2, &slice->edge2, + slice->edge2_top, slice->edge2_top); + } + else { + double w2, h2, x1, y1, x2, y2, dx, dy, scale; + int signdx, signdy, y, k; + Bool isInt1 = TRUE, isInt2 = TRUE; + + w2 = (double) arc->width / 2.0; + h2 = (double) arc->height / 2.0; + if ((angle1 == 0) || (angle1 == HALFCIRCLE)) { + x1 = angle1 ? -w2 : w2; + y1 = 0.0; + } + else if ((angle1 == QUADRANT) || (angle1 == QUADRANT3)) { + x1 = 0.0; + y1 = (angle1 == QUADRANT) ? h2 : -h2; + } + else { + isInt1 = FALSE; + x1 = Dcos(angle1) * w2; + y1 = Dsin(angle1) * h2; + } + if ((angle2 == 0) || (angle2 == HALFCIRCLE)) { + x2 = angle2 ? -w2 : w2; + y2 = 0.0; + } + else if ((angle2 == QUADRANT) || (angle2 == QUADRANT3)) { + x2 = 0.0; + y2 = (angle2 == QUADRANT) ? h2 : -h2; + } + else { + isInt2 = FALSE; + x2 = Dcos(angle2) * w2; + y2 = Dsin(angle2) * h2; + } + dx = x2 - x1; + dy = y2 - y1; + if (arc->height & 1) { + y1 -= 0.5; + y2 -= 0.5; + } + if (arc->width & 1) { + x1 += 0.5; + x2 += 0.5; + } + if (dy < 0.0) { + dy = -dy; + signdy = -1; + } + else + signdy = 1; + if (dx < 0.0) { + dx = -dx; + signdx = -1; + } + else + signdx = 1; + if (isInt1 && isInt2) { + slice->edge1.dx = dx * 2; + slice->edge1.dy = dy * 2; + } + else { + scale = (dx > dy) ? dx : dy; + slice->edge1.dx = floor((dx * 32768) / scale + .5); + slice->edge1.dy = floor((dy * 32768) / scale + .5); + } + if (!slice->edge1.dy) { + if (signdx < 0) { + y = floor(y1 + 1.0); + if (y >= 0) { + slice->min_top_y = y; + slice->min_bot_y = arc->height; + } + else { + slice->max_bot_y = -y - (arc->height & 1); + } + } + else { + y = floor(y1); + if (y >= 0) + slice->max_top_y = y; + else { + slice->min_top_y = arc->height; + slice->min_bot_y = -y - (arc->height & 1); + } + } + slice->edge1_top = TRUE; + slice->edge1.x = 65536; + slice->edge1.stepx = 0; + slice->edge1.e = 0; + slice->edge1.dx = -1; + slice->edge2 = slice->edge1; + slice->edge2_top = FALSE; + } + else if (!slice->edge1.dx) { + if (signdy < 0) + x1 -= 1.0; + slice->edge1.x = ceil(x1); + slice->edge1_top = signdy < 0; + slice->edge1.x += arc->x + (arc->width >> 1); + slice->edge1.stepx = 0; + slice->edge1.e = 0; + slice->edge1.dx = -1; + slice->edge2_top = !slice->edge1_top; + slice->edge2 = slice->edge1; + } + else { + if (signdx < 0) + slice->edge1.dx = -slice->edge1.dx; + if (signdy < 0) + slice->edge1.dx = -slice->edge1.dx; + k = ceil(((x1 + x2) * slice->edge1.dy - + (y1 + y2) * slice->edge1.dx) / 2.0); + slice->edge2.dx = slice->edge1.dx; + slice->edge2.dy = slice->edge1.dy; + slice->edge1_top = signdy < 0; + slice->edge2_top = !slice->edge1_top; + miGetArcEdge(arc, &slice->edge1, k, + slice->edge1_top, !slice->edge1_top); + miGetArcEdge(arc, &slice->edge2, k, + slice->edge2_top, slice->edge2_top); + } + } +} + +#define ADDSPANS() \ + pts->x = xorg - x; \ + pts->y = yorg - y; \ + *wids = slw; \ + pts++; \ + wids++; \ + if (miFillArcLower(slw)) \ + { \ + pts->x = xorg - x; \ + pts->y = yorg + y + dy; \ + pts++; \ + *wids++ = slw; \ + } + +static void +miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc) +{ + int x, y, e; + int yk, xk, ym, xm, dx, dy, xorg, yorg; + int slw; + miFillArcRec info; + DDXPointPtr points; + DDXPointPtr pts; + int *widths; + int *wids; + + points = malloc(sizeof(DDXPointRec) * arc->height); + if (!points) + return; + widths = malloc(sizeof(int) * arc->height); + if (!widths) { + free(points); + return; + } + miFillArcSetup(arc, &info); + MIFILLARCSETUP(); + if (pGC->miTranslate) { + xorg += pDraw->x; + yorg += pDraw->y; + } + pts = points; + wids = widths; + while (y > 0) { + MIFILLARCSTEP(slw); + ADDSPANS(); + } + (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE); + free(widths); + free(points); +} + +static void +miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) +{ + int x, y; + int xorg, yorg, dx, dy, slw; + double e, yk, xk, ym, xm; + miFillArcDRec info; + DDXPointPtr points; + DDXPointPtr pts; + int *widths; + int *wids; + + points = malloc(sizeof(DDXPointRec) * arc->height); + if (!points) + return; + widths = malloc(sizeof(int) * arc->height); + if (!widths) { + free(points); + return; + } + miFillArcDSetup(arc, &info); + MIFILLARCSETUP(); + if (pGC->miTranslate) { + xorg += pDraw->x; + yorg += pDraw->y; + } + pts = points; + wids = widths; + while (y > 0) { + MIFILLARCSTEP(slw); + ADDSPANS(); + } + (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE); + free(widths); + free(points); +} + +#define ADDSPAN(l,r) \ + if (r >= l) \ + { \ + pts->x = l; \ + pts->y = ya; \ + pts++; \ + *wids++ = r - l + 1; \ + } + +#define ADDSLICESPANS(flip) \ + if (!flip) \ + { \ + ADDSPAN(xl, xr); \ + } \ + else \ + { \ + xc = xorg - x; \ + ADDSPAN(xc, xr); \ + xc += slw - 1; \ + ADDSPAN(xl, xc); \ + } + +static void +miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc) +{ + int yk, xk, ym, xm, dx, dy, xorg, yorg, slw; + int x, y, e; + miFillArcRec info; + miArcSliceRec slice; + int ya, xl, xr, xc; + DDXPointPtr points; + DDXPointPtr pts; + int *widths; + int *wids; + + miFillArcSetup(arc, &info); + miFillArcSliceSetup(arc, &slice, pGC); + MIFILLARCSETUP(); + slw = arc->height; + if (slice.flip_top || slice.flip_bot) + slw += (arc->height >> 1) + 1; + points = malloc(sizeof(DDXPointRec) * slw); + if (!points) + return; + widths = malloc(sizeof(int) * slw); + if (!widths) { + free(points); + return; + } + if (pGC->miTranslate) { + xorg += pDraw->x; + yorg += pDraw->y; + slice.edge1.x += pDraw->x; + slice.edge2.x += pDraw->x; + } + pts = points; + wids = widths; + while (y > 0) { + MIFILLARCSTEP(slw); + MIARCSLICESTEP(slice.edge1); + MIARCSLICESTEP(slice.edge2); + if (miFillSliceUpper(slice)) { + ya = yorg - y; + MIARCSLICEUPPER(xl, xr, slice, slw); + ADDSLICESPANS(slice.flip_top); + } + if (miFillSliceLower(slice)) { + ya = yorg + y + dy; + MIARCSLICELOWER(xl, xr, slice, slw); + ADDSLICESPANS(slice.flip_bot); + } + } + (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE); + free(widths); + free(points); +} + +static void +miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) +{ + int x, y; + int dx, dy, xorg, yorg, slw; + double e, yk, xk, ym, xm; + miFillArcDRec info; + miArcSliceRec slice; + int ya, xl, xr, xc; + DDXPointPtr points; + DDXPointPtr pts; + int *widths; + int *wids; + + miFillArcDSetup(arc, &info); + miFillArcSliceSetup(arc, &slice, pGC); + MIFILLARCSETUP(); + slw = arc->height; + if (slice.flip_top || slice.flip_bot) + slw += (arc->height >> 1) + 1; + points = malloc(sizeof(DDXPointRec) * slw); + if (!points) + return; + widths = malloc(sizeof(int) * slw); + if (!widths) { + free(points); + return; + } + if (pGC->miTranslate) { + xorg += pDraw->x; + yorg += pDraw->y; + slice.edge1.x += pDraw->x; + slice.edge2.x += pDraw->x; + } + pts = points; + wids = widths; + while (y > 0) { + MIFILLARCSTEP(slw); + MIARCSLICESTEP(slice.edge1); + MIARCSLICESTEP(slice.edge2); + if (miFillSliceUpper(slice)) { + ya = yorg - y; + MIARCSLICEUPPER(xl, xr, slice, slw); + ADDSLICESPANS(slice.flip_top); + } + if (miFillSliceLower(slice)) { + ya = yorg + y + dy; + MIARCSLICELOWER(xl, xr, slice, slw); + ADDSLICESPANS(slice.flip_bot); + } + } + (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE); + free(widths); + free(points); +} + +/* MIPOLYFILLARC -- The public entry for the PolyFillArc request. + * Since we don't have to worry about overlapping segments, we can just + * fill each arc as it comes. + */ +void +miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs) +{ + int i; + xArc *arc; + + for (i = narcs, arc = parcs; --i >= 0; arc++) { + if (miFillArcEmpty(arc)) + continue; + if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE)) { + if (miCanFillArc(arc)) + miFillEllipseI(pDraw, pGC, arc); + else + miFillEllipseD(pDraw, pGC, arc); + } + else { + if (miCanFillArc(arc)) + miFillArcSliceI(pDraw, pGC, arc); + else + miFillArcSliceD(pDraw, pGC, arc); + } + } +} diff --git a/xorg-server/mi/mifillarc.h b/xorg-server/mi/mifillarc.h index 11587540f..1478d1850 100644 --- a/xorg-server/mi/mifillarc.h +++ b/xorg-server/mi/mifillarc.h @@ -24,7 +24,6 @@ in this Software without prior written authorization from The Open Group. ********************************************************/ - #ifndef __MIFILLARC_H__ #define __MIFILLARC_H__ @@ -87,12 +86,12 @@ typedef struct _miFillArcD { #define miFillArcLower(slw) (((y + dy) != 0) && ((slw > 1) || (e != xk))) typedef struct _miSliceEdge { - int x; - int stepx; - int deltax; - int e; - int dy; - int dx; + int x; + int stepx; + int deltax; + int e; + int dy; + int dx; } miSliceEdgeRec, *miSliceEdgePtr; typedef struct _miArcSlice { @@ -176,15 +175,13 @@ typedef struct _miArcSlice { #define miFillInArcLower(slw) (((iny + dy) != 0) && \ ((slw > 1) || (ine != inxk))) -extern _X_EXPORT void miFillArcSetup( - xArc * /*arc*/, - miFillArcRec * /*info*/ -); +extern _X_EXPORT void miFillArcSetup(xArc * /*arc */ , + miFillArcRec * /*info */ + ); -extern _X_EXPORT void miFillArcSliceSetup( - xArc * /*arc*/, - miArcSliceRec * /*slice*/, - GCPtr /*pGC*/ -); +extern _X_EXPORT void miFillArcSliceSetup(xArc * /*arc */ , + miArcSliceRec * /*slice */ , + GCPtr /*pGC */ + ); -#endif /* __MIFILLARC_H__ */ +#endif /* __MIFILLARC_H__ */ diff --git a/xorg-server/mi/mifillrct.c b/xorg-server/mi/mifillrct.c index f2ca4c432..79c4057d7 100644 --- a/xorg-server/mi/mifillrct.c +++ b/xorg-server/mi/mifillrct.c @@ -1,143 +1,132 @@ -/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xprotostr.h>
-#include "gcstruct.h"
-#include "windowstr.h"
-#include "pixmap.h"
-#include "mi.h"
-#include "misc.h"
-
-/* mi rectangles
- written by newman, with debts to all and sundry
-*/
-
-/* MIPOLYFILLRECT -- public entry for PolyFillRect request
- * very straight forward: translate rectangles if necessary
- * then call FillSpans to fill each rectangle. We let FillSpans worry about
- * clipping to the destination
- */
-void
-miPolyFillRect(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int nrectFill, /* number of rectangles to fill */
- xRectangle *prectInit /* Pointer to first rectangle to fill */
- )
-{
- int i;
- int height;
- int width;
- xRectangle *prect;
- int xorg;
- int yorg;
- int maxheight;
- DDXPointPtr pptFirst;
- DDXPointPtr ppt;
- int *pwFirst;
- int *pw;
-
- if (pGC->miTranslate)
- {
- xorg = pDrawable->x;
- yorg = pDrawable->y;
- prect = prectInit;
- maxheight = 0;
- for (i = 0; i<nrectFill; i++, prect++)
- {
- prect->x += xorg;
- prect->y += yorg;
- maxheight = max(maxheight, prect->height);
- }
- }
- else
- {
- prect = prectInit;
- maxheight = 0;
- for (i = 0; i<nrectFill; i++, prect++)
- maxheight = max(maxheight, prect->height);
- }
-
- pptFirst = malloc(maxheight * sizeof(DDXPointRec));
- pwFirst = malloc(maxheight * sizeof(int));
- if(!pptFirst || !pwFirst)
- {
- free(pwFirst);
- free(pptFirst);
- return;
- }
-
- prect = prectInit;
- while(nrectFill--)
- {
- ppt = pptFirst;
- pw = pwFirst;
- height = prect->height;
- width = prect->width;
- xorg = prect->x;
- yorg = prect->y;
- while(height--)
- {
- *pw++ = width;
- ppt->x = xorg;
- ppt->y = yorg;
- ppt++;
- yorg++;
- }
- (* pGC->ops->FillSpans)(pDrawable, pGC,
- prect->height, pptFirst, pwFirst,
- 1);
- prect++;
- }
- free(pwFirst);
- free(pptFirst);
-}
+/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xprotostr.h> +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmap.h" +#include "mi.h" +#include "misc.h" + +/* mi rectangles + written by newman, with debts to all and sundry +*/ + +/* MIPOLYFILLRECT -- public entry for PolyFillRect request + * very straight forward: translate rectangles if necessary + * then call FillSpans to fill each rectangle. We let FillSpans worry about + * clipping to the destination + */ +void +miPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, /* number of rectangles to fill */ + xRectangle *prectInit /* Pointer to first rectangle to fill */ + ) +{ + int i; + int height; + int width; + xRectangle *prect; + int xorg; + int yorg; + int maxheight; + DDXPointPtr pptFirst; + DDXPointPtr ppt; + int *pwFirst; + int *pw; + + if (pGC->miTranslate) { + xorg = pDrawable->x; + yorg = pDrawable->y; + prect = prectInit; + maxheight = 0; + for (i = 0; i < nrectFill; i++, prect++) { + prect->x += xorg; + prect->y += yorg; + maxheight = max(maxheight, prect->height); + } + } + else { + prect = prectInit; + maxheight = 0; + for (i = 0; i < nrectFill; i++, prect++) + maxheight = max(maxheight, prect->height); + } + + pptFirst = malloc(maxheight * sizeof(DDXPointRec)); + pwFirst = malloc(maxheight * sizeof(int)); + if (!pptFirst || !pwFirst) { + free(pwFirst); + free(pptFirst); + return; + } + + prect = prectInit; + while (nrectFill--) { + ppt = pptFirst; + pw = pwFirst; + height = prect->height; + width = prect->width; + xorg = prect->x; + yorg = prect->y; + while (height--) { + *pw++ = width; + ppt->x = xorg; + ppt->y = yorg; + ppt++; + yorg++; + } + (*pGC->ops->FillSpans) (pDrawable, pGC, + prect->height, pptFirst, pwFirst, 1); + prect++; + } + free(pwFirst); + free(pptFirst); +} diff --git a/xorg-server/mi/mifpoly.h b/xorg-server/mi/mifpoly.h index cc779c946..f853fb46b 100644 --- a/xorg-server/mi/mifpoly.h +++ b/xorg-server/mi/mifpoly.h @@ -22,7 +22,6 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved @@ -65,38 +64,39 @@ SOFTWARE. #define FirstEnd 1 #define SecondEnd 2 -#define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - for 11o miter cutoff */ -#define D2SECANT 5.21671526231167 /* 1/2*sin(11/2) - max extension per width */ +#define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - for 11o miter cutoff */ +#define D2SECANT 5.21671526231167 /* 1/2*sin(11/2) - max extension per width */ -static _X_INLINE int ICEIL(double x) +static _X_INLINE int +ICEIL(double x) { int _cTmp = x; - return ((x == _cTmp) || (x < 0.0)) ? _cTmp : _cTmp+1; + + return ((x == _cTmp) || (x < 0.0)) ? _cTmp : _cTmp + 1; } /* Point with sub-pixel positioning. In this case we use doubles, but * see mifpolycon.c for other suggestions */ typedef struct _SppPoint { - double x, y; + double x, y; } SppPointRec, *SppPointPtr; typedef struct _SppArc { - double x, y, width, height; - double angle1, angle2; + double x, y, width, height; + double angle1, angle2; } SppArcRec, *SppArcPtr; /* mifpolycon.c */ -extern _X_EXPORT void miFillSppPoly( - DrawablePtr /*dst*/, - GCPtr /*pgc*/, - int /*count*/, - SppPointPtr /*ptsIn*/, - int /*xTrans*/, - int /*yTrans*/, - double /*xFtrans*/, - double /*yFtrans*/ -); - -#endif /* __MIFPOLY_H__ */ +extern _X_EXPORT void miFillSppPoly(DrawablePtr /*dst */ , + GCPtr /*pgc */ , + int /*count */ , + SppPointPtr /*ptsIn */ , + int /*xTrans */ , + int /*yTrans */ , + double /*xFtrans */ , + double /*yFtrans */ + ); + +#endif /* __MIFPOLY_H__ */ diff --git a/xorg-server/mi/mifpolycon.c b/xorg-server/mi/mifpolycon.c index 9d776201c..b1337315b 100644 --- a/xorg-server/mi/mifpolycon.c +++ b/xorg-server/mi/mifpolycon.c @@ -1,280 +1,249 @@ -/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <math.h>
-#include <X11/X.h>
-#include "gcstruct.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "mifpoly.h"
-
-static int GetFPolyYBounds(SppPointPtr pts, int n, double yFtrans,
- int *by, int *ty);
-
-/*
- * Written by Todd Newman; April. 1987.
- *
- * Fill a convex polygon. If the given polygon
- * is not convex, then the result is undefined.
- * The algorithm is to order the edges from smallest
- * y to largest by partitioning the array into a left
- * edge list and a right edge list. The algorithm used
- * to traverse each edge is digital differencing analyzer
- * line algorithm with y as the major axis. There's some funny linear
- * interpolation involved because of the subpixel postioning.
- */
-void
-miFillSppPoly(
- DrawablePtr dst,
- GCPtr pgc,
- int count, /* number of points */
- SppPointPtr ptsIn, /* the points */
- int xTrans, int yTrans, /* Translate each point by this */
- double xFtrans,
- double yFtrans /* translate before conversion
- by this amount. This provides
- a mechanism to match rounding
- errors with any shape that must
- meet the polygon exactly.
- */
- )
-{
- double xl = 0.0, xr = 0.0, /* x vals of left and right edges */
- ml = 0.0, /* left edge slope */
- mr = 0.0, /* right edge slope */
- dy, /* delta y */
- i; /* loop counter */
- int y, /* current scanline */
- j,
- imin, /* index of vertex with smallest y */
- ymin, /* y-extents of polygon */
- ymax,
- *width,
- *FirstWidth, /* output buffer */
- *Marked; /* set if this vertex has been used */
- int left, right, /* indices to first endpoints */
- nextleft,
- nextright; /* indices to second endpoints */
- DDXPointPtr ptsOut,
- FirstPoint; /* output buffer */
-
- if (pgc->miTranslate)
- {
- xTrans += dst->x;
- yTrans += dst->y;
- }
-
- imin = GetFPolyYBounds(ptsIn, count, yFtrans, &ymin, &ymax);
-
- y = ymax - ymin + 1;
- if ((count < 3) || (y <= 0))
- return;
- ptsOut = FirstPoint = malloc(sizeof(DDXPointRec) * y);
- width = FirstWidth = malloc(sizeof(int) * y);
- Marked = malloc(sizeof(int) * count);
-
- if(!ptsOut || !width || !Marked)
- {
- free(Marked);
- free(width);
- free(ptsOut);
- return;
- }
-
- for(j = 0; j < count; j++)
- Marked[j] = 0;
- nextleft = nextright = imin;
- Marked[imin] = -1;
- y = ICEIL(ptsIn[nextleft].y + yFtrans);
-
- /*
- * loop through all edges of the polygon
- */
- do
- {
- /* add a left edge if we need to */
- if ((y > (ptsIn[nextleft].y + yFtrans) ||
- ISEQUAL(y, ptsIn[nextleft].y + yFtrans)) &&
- Marked[nextleft] != 1)
- {
- Marked[nextleft]++;
- left = nextleft++;
-
- /* find the next edge, considering the end conditions */
- if (nextleft >= count)
- nextleft = 0;
-
- /* now compute the starting point and slope */
- dy = ptsIn[nextleft].y - ptsIn[left].y;
- if (dy != 0.0)
- {
- ml = (ptsIn[nextleft].x - ptsIn[left].x) / dy;
- dy = y - (ptsIn[left].y + yFtrans);
- xl = (ptsIn[left].x + xFtrans) + ml * max(dy, 0);
- }
- }
-
- /* add a right edge if we need to */
- if ((y > ptsIn[nextright].y + yFtrans) ||
- (ISEQUAL(y, ptsIn[nextright].y + yFtrans)
- && Marked[nextright] != 1))
- {
- Marked[nextright]++;
- right = nextright--;
-
- /* find the next edge, considering the end conditions */
- if (nextright < 0)
- nextright = count - 1;
-
- /* now compute the starting point and slope */
- dy = ptsIn[nextright].y - ptsIn[right].y;
- if (dy != 0.0)
- {
- mr = (ptsIn[nextright].x - ptsIn[right].x) / dy;
- dy = y - (ptsIn[right].y + yFtrans);
- xr = (ptsIn[right].x + xFtrans) + mr * max(dy, 0);
- }
- }
-
-
- /*
- * generate scans to fill while we still have
- * a right edge as well as a left edge.
- */
- i = (min(ptsIn[nextleft].y, ptsIn[nextright].y) + yFtrans) - y;
-
- if (i < EPSILON)
- {
- if(Marked[nextleft] && Marked[nextright])
- {
- /* Arrgh, we're trapped! (no more points)
- * Out, we've got to get out of here before this decadence saps
- * our will completely! */
- break;
- }
- continue;
- }
- else
- {
- j = (int) i;
- if(!j)
- j++;
- }
- while (j > 0)
- {
- int cxl, cxr;
-
- ptsOut->y = (y) + yTrans;
-
- cxl = ICEIL(xl);
- cxr = ICEIL(xr);
- /* reverse the edges if necessary */
- if (xl < xr)
- {
- *(width++) = cxr - cxl;
- (ptsOut++)->x = cxl + xTrans;
- }
- else
- {
- *(width++) = cxl - cxr;
- (ptsOut++)->x = cxr + xTrans;
- }
- y++;
-
- /* increment down the edges */
- xl += ml;
- xr += mr;
- j--;
- }
- } while (y <= ymax);
-
- /* Finally, fill the spans we've collected */
- (*pgc->ops->FillSpans)(dst, pgc,
- ptsOut-FirstPoint, FirstPoint, FirstWidth, 1);
- free(Marked);
- free(FirstWidth);
- free(FirstPoint);
-}
-
-
-/* Find the index of the point with the smallest y.also return the
- * smallest and largest y */
-static
-int
-GetFPolyYBounds(
- SppPointPtr pts,
- int n,
- double yFtrans,
- int *by,
- int *ty)
-{
- SppPointPtr ptMin;
- double ymin, ymax;
- SppPointPtr ptsStart = pts;
-
- ptMin = pts;
- ymin = ymax = (pts++)->y;
-
- while (--n > 0) {
- if (pts->y < ymin)
- {
- ptMin = pts;
- ymin = pts->y;
- }
- if(pts->y > ymax)
- ymax = pts->y;
-
- pts++;
- }
-
- *by = ICEIL(ymin + yFtrans);
- *ty = ICEIL(ymax + yFtrans - 1);
- return ptMin-ptsStart;
-}
+/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <math.h> +#include <X11/X.h> +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "mifpoly.h" + +static int GetFPolyYBounds(SppPointPtr pts, int n, double yFtrans, + int *by, int *ty); + +/* + * Written by Todd Newman; April. 1987. + * + * Fill a convex polygon. If the given polygon + * is not convex, then the result is undefined. + * The algorithm is to order the edges from smallest + * y to largest by partitioning the array into a left + * edge list and a right edge list. The algorithm used + * to traverse each edge is digital differencing analyzer + * line algorithm with y as the major axis. There's some funny linear + * interpolation involved because of the subpixel postioning. + */ +void +miFillSppPoly(DrawablePtr dst, GCPtr pgc, int count, /* number of points */ + SppPointPtr ptsIn, /* the points */ + int xTrans, int yTrans, /* Translate each point by this */ + double xFtrans, double yFtrans /* translate before conversion + by this amount. This provides + a mechanism to match rounding + errors with any shape that must + meet the polygon exactly. + */ + ) +{ + double xl = 0.0, xr = 0.0, /* x vals of left and right edges */ + ml = 0.0, /* left edge slope */ + mr = 0.0, /* right edge slope */ + dy, /* delta y */ + i; /* loop counter */ + int y, /* current scanline */ + j, imin, /* index of vertex with smallest y */ + ymin, /* y-extents of polygon */ + ymax, *width, *FirstWidth, /* output buffer */ + *Marked; /* set if this vertex has been used */ + int left, right, /* indices to first endpoints */ + nextleft, nextright; /* indices to second endpoints */ + DDXPointPtr ptsOut, FirstPoint; /* output buffer */ + + if (pgc->miTranslate) { + xTrans += dst->x; + yTrans += dst->y; + } + + imin = GetFPolyYBounds(ptsIn, count, yFtrans, &ymin, &ymax); + + y = ymax - ymin + 1; + if ((count < 3) || (y <= 0)) + return; + ptsOut = FirstPoint = malloc(sizeof(DDXPointRec) * y); + width = FirstWidth = malloc(sizeof(int) * y); + Marked = malloc(sizeof(int) * count); + + if (!ptsOut || !width || !Marked) { + free(Marked); + free(width); + free(ptsOut); + return; + } + + for (j = 0; j < count; j++) + Marked[j] = 0; + nextleft = nextright = imin; + Marked[imin] = -1; + y = ICEIL(ptsIn[nextleft].y + yFtrans); + + /* + * loop through all edges of the polygon + */ + do { + /* add a left edge if we need to */ + if ((y > (ptsIn[nextleft].y + yFtrans) || + ISEQUAL(y, ptsIn[nextleft].y + yFtrans)) && + Marked[nextleft] != 1) { + Marked[nextleft]++; + left = nextleft++; + + /* find the next edge, considering the end conditions */ + if (nextleft >= count) + nextleft = 0; + + /* now compute the starting point and slope */ + dy = ptsIn[nextleft].y - ptsIn[left].y; + if (dy != 0.0) { + ml = (ptsIn[nextleft].x - ptsIn[left].x) / dy; + dy = y - (ptsIn[left].y + yFtrans); + xl = (ptsIn[left].x + xFtrans) + ml * max(dy, 0); + } + } + + /* add a right edge if we need to */ + if ((y > ptsIn[nextright].y + yFtrans) || + (ISEQUAL(y, ptsIn[nextright].y + yFtrans) + && Marked[nextright] != 1)) { + Marked[nextright]++; + right = nextright--; + + /* find the next edge, considering the end conditions */ + if (nextright < 0) + nextright = count - 1; + + /* now compute the starting point and slope */ + dy = ptsIn[nextright].y - ptsIn[right].y; + if (dy != 0.0) { + mr = (ptsIn[nextright].x - ptsIn[right].x) / dy; + dy = y - (ptsIn[right].y + yFtrans); + xr = (ptsIn[right].x + xFtrans) + mr * max(dy, 0); + } + } + + /* + * generate scans to fill while we still have + * a right edge as well as a left edge. + */ + i = (min(ptsIn[nextleft].y, ptsIn[nextright].y) + yFtrans) - y; + + if (i < EPSILON) { + if (Marked[nextleft] && Marked[nextright]) { + /* Arrgh, we're trapped! (no more points) + * Out, we've got to get out of here before this decadence saps + * our will completely! */ + break; + } + continue; + } + else { + j = (int) i; + if (!j) + j++; + } + while (j > 0) { + int cxl, cxr; + + ptsOut->y = (y) + yTrans; + + cxl = ICEIL(xl); + cxr = ICEIL(xr); + /* reverse the edges if necessary */ + if (xl < xr) { + *(width++) = cxr - cxl; + (ptsOut++)->x = cxl + xTrans; + } + else { + *(width++) = cxl - cxr; + (ptsOut++)->x = cxr + xTrans; + } + y++; + + /* increment down the edges */ + xl += ml; + xr += mr; + j--; + } + } while (y <= ymax); + + /* Finally, fill the spans we've collected */ + (*pgc->ops->FillSpans) (dst, pgc, + ptsOut - FirstPoint, FirstPoint, FirstWidth, 1); + free(Marked); + free(FirstWidth); + free(FirstPoint); +} + +/* Find the index of the point with the smallest y.also return the + * smallest and largest y */ +static + int +GetFPolyYBounds(SppPointPtr pts, int n, double yFtrans, int *by, int *ty) +{ + SppPointPtr ptMin; + double ymin, ymax; + SppPointPtr ptsStart = pts; + + ptMin = pts; + ymin = ymax = (pts++)->y; + + while (--n > 0) { + if (pts->y < ymin) { + ptMin = pts; + ymin = pts->y; + } + if (pts->y > ymax) + ymax = pts->y; + + pts++; + } + + *by = ICEIL(ymin + yFtrans); + *ty = ICEIL(ymax + yFtrans - 1); + return ptMin - ptsStart; +} diff --git a/xorg-server/mi/migc.c b/xorg-server/mi/migc.c index 50abefcea..c9cdd12af 100644 --- a/xorg-server/mi/migc.c +++ b/xorg-server/mi/migc.c @@ -1,249 +1,230 @@ -/*
-
-Copyright 1993, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "migc.h"
-
-/* ARGSUSED */
-void
-miChangeGC(GCPtr pGC, unsigned long mask)
-{
- return;
-}
-
-void
-miDestroyGC(GCPtr pGC)
-{
- if (pGC->pRotatedPixmap)
- (*pGC->pScreen->DestroyPixmap) (pGC->pRotatedPixmap);
- if (pGC->freeCompClip)
- RegionDestroy(pGC->pCompositeClip);
-}
-
-void
-miDestroyClip(GCPtr pGC)
-{
- if (pGC->clientClipType == CT_NONE)
- return;
- else if (pGC->clientClipType == CT_PIXMAP)
- {
- (*pGC->pScreen->DestroyPixmap) ((PixmapPtr) (pGC->clientClip));
- }
- else
- {
- /*
- * we know we'll never have a list of rectangles, since ChangeClip
- * immediately turns them into a region
- */
- RegionDestroy(pGC->clientClip);
- }
- pGC->clientClip = NULL;
- pGC->clientClipType = CT_NONE;
-}
-
-void
-miChangeClip( GCPtr pGC, int type, pointer pvalue, int nrects)
-{
- (*pGC->funcs->DestroyClip) (pGC);
- if (type == CT_PIXMAP)
- {
- /* convert the pixmap to a region */
- pGC->clientClip = (pointer) BitmapToRegion(pGC->pScreen,
- (PixmapPtr) pvalue);
- (*pGC->pScreen->DestroyPixmap) (pvalue);
- }
- else if (type == CT_REGION)
- {
- /* stuff the region in the GC */
- pGC->clientClip = pvalue;
- }
- else if (type != CT_NONE)
- {
- pGC->clientClip = (pointer) RegionFromRects(nrects,
- (xRectangle *) pvalue,
- type);
- free(pvalue);
- }
- pGC->clientClipType = (type != CT_NONE && pGC->clientClip) ? CT_REGION : CT_NONE;
- pGC->stateChanges |= GCClipMask;
-}
-
-void
-miCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
-{
- RegionPtr prgnNew;
-
- switch (pgcSrc->clientClipType)
- {
- case CT_PIXMAP:
- ((PixmapPtr) pgcSrc->clientClip)->refcnt++;
- /* Fall through !! */
- case CT_NONE:
- (*pgcDst->funcs->ChangeClip) (pgcDst, (int) pgcSrc->clientClipType,
- pgcSrc->clientClip, 0);
- break;
- case CT_REGION:
- prgnNew = RegionCreate(NULL, 1);
- RegionCopy(prgnNew, (RegionPtr) (pgcSrc->clientClip));
- (*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, (pointer) prgnNew, 0);
- break;
- }
-}
-
-/* ARGSUSED */
-void
-miCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst)
-{
- return;
-}
-
-void
-miComputeCompositeClip( GCPtr pGC, DrawablePtr pDrawable)
-{
- if (pDrawable->type == DRAWABLE_WINDOW)
- {
- WindowPtr pWin = (WindowPtr) pDrawable;
- RegionPtr pregWin;
- Bool freeTmpClip, freeCompClip;
-
- if (pGC->subWindowMode == IncludeInferiors)
- {
- pregWin = NotClippedByChildren(pWin);
- freeTmpClip = TRUE;
- }
- else
- {
- pregWin = &pWin->clipList;
- freeTmpClip = FALSE;
- }
- freeCompClip = pGC->freeCompClip;
-
- /*
- * if there is no client clip, we can get by with just keeping the
- * pointer we got, and remembering whether or not should destroy (or
- * maybe re-use) it later. this way, we avoid unnecessary copying of
- * regions. (this wins especially if many clients clip by children
- * and have no client clip.)
- */
- if (pGC->clientClipType == CT_NONE)
- {
- if (freeCompClip)
- RegionDestroy(pGC->pCompositeClip);
- pGC->pCompositeClip = pregWin;
- pGC->freeCompClip = freeTmpClip;
- }
- else
- {
- /*
- * we need one 'real' region to put into the composite clip. if
- * pregWin the current composite clip are real, we can get rid of
- * one. if pregWin is real and the current composite clip isn't,
- * use pregWin for the composite clip. if the current composite
- * clip is real and pregWin isn't, use the current composite
- * clip. if neither is real, create a new region.
- */
-
- RegionTranslate(pGC->clientClip,
- pDrawable->x + pGC->clipOrg.x,
- pDrawable->y + pGC->clipOrg.y);
-
- if (freeCompClip)
- {
- RegionIntersect(pGC->pCompositeClip,
- pregWin, pGC->clientClip);
- if (freeTmpClip)
- RegionDestroy(pregWin);
- }
- else if (freeTmpClip)
- {
- RegionIntersect(pregWin, pregWin, pGC->clientClip);
- pGC->pCompositeClip = pregWin;
- }
- else
- {
- pGC->pCompositeClip = RegionCreate(NullBox, 0);
- RegionIntersect(pGC->pCompositeClip,
- pregWin, pGC->clientClip);
- }
- pGC->freeCompClip = TRUE;
- RegionTranslate(pGC->clientClip,
- -(pDrawable->x + pGC->clipOrg.x),
- -(pDrawable->y + pGC->clipOrg.y));
- }
- } /* end of composite clip for a window */
- else
- {
- BoxRec pixbounds;
-
- /* XXX should we translate by drawable.x/y here ? */
- /* If you want pixmaps in offscreen memory, yes */
- pixbounds.x1 = pDrawable->x;
- pixbounds.y1 = pDrawable->y;
- pixbounds.x2 = pDrawable->x + pDrawable->width;
- pixbounds.y2 = pDrawable->y + pDrawable->height;
-
- if (pGC->freeCompClip)
- {
- RegionReset(pGC->pCompositeClip, &pixbounds);
- }
- else
- {
- pGC->freeCompClip = TRUE;
- pGC->pCompositeClip = RegionCreate(&pixbounds, 1);
- }
-
- if (pGC->clientClipType == CT_REGION)
- {
- if(pDrawable->x || pDrawable->y) {
- RegionTranslate(pGC->clientClip,
- pDrawable->x + pGC->clipOrg.x,
- pDrawable->y + pGC->clipOrg.y);
- RegionIntersect(pGC->pCompositeClip,
- pGC->pCompositeClip, pGC->clientClip);
- RegionTranslate(pGC->clientClip,
- -(pDrawable->x + pGC->clipOrg.x),
- -(pDrawable->y + pGC->clipOrg.y));
- } else {
- RegionTranslate(pGC->pCompositeClip,
- -pGC->clipOrg.x, -pGC->clipOrg.y);
- RegionIntersect(pGC->pCompositeClip,
- pGC->pCompositeClip, pGC->clientClip);
- RegionTranslate(pGC->pCompositeClip,
- pGC->clipOrg.x, pGC->clipOrg.y);
- }
- }
- } /* end of composite clip for pixmap */
-} /* end miComputeCompositeClip */
+/* + +Copyright 1993, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "migc.h" + +/* ARGSUSED */ +void +miChangeGC(GCPtr pGC, unsigned long mask) +{ + return; +} + +void +miDestroyGC(GCPtr pGC) +{ + if (pGC->pRotatedPixmap) + (*pGC->pScreen->DestroyPixmap) (pGC->pRotatedPixmap); + if (pGC->freeCompClip) + RegionDestroy(pGC->pCompositeClip); +} + +void +miDestroyClip(GCPtr pGC) +{ + if (pGC->clientClipType == CT_NONE) + return; + else if (pGC->clientClipType == CT_PIXMAP) { + (*pGC->pScreen->DestroyPixmap) ((PixmapPtr) (pGC->clientClip)); + } + else { + /* + * we know we'll never have a list of rectangles, since ChangeClip + * immediately turns them into a region + */ + RegionDestroy(pGC->clientClip); + } + pGC->clientClip = NULL; + pGC->clientClipType = CT_NONE; +} + +void +miChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects) +{ + (*pGC->funcs->DestroyClip) (pGC); + if (type == CT_PIXMAP) { + /* convert the pixmap to a region */ + pGC->clientClip = (pointer) BitmapToRegion(pGC->pScreen, + (PixmapPtr) pvalue); + (*pGC->pScreen->DestroyPixmap) (pvalue); + } + else if (type == CT_REGION) { + /* stuff the region in the GC */ + pGC->clientClip = pvalue; + } + else if (type != CT_NONE) { + pGC->clientClip = (pointer) RegionFromRects(nrects, + (xRectangle *) pvalue, + type); + free(pvalue); + } + pGC->clientClipType = (type != CT_NONE && + pGC->clientClip) ? CT_REGION : CT_NONE; + pGC->stateChanges |= GCClipMask; +} + +void +miCopyClip(GCPtr pgcDst, GCPtr pgcSrc) +{ + RegionPtr prgnNew; + + switch (pgcSrc->clientClipType) { + case CT_PIXMAP: + ((PixmapPtr) pgcSrc->clientClip)->refcnt++; + /* Fall through !! */ + case CT_NONE: + (*pgcDst->funcs->ChangeClip) (pgcDst, (int) pgcSrc->clientClipType, + pgcSrc->clientClip, 0); + break; + case CT_REGION: + prgnNew = RegionCreate(NULL, 1); + RegionCopy(prgnNew, (RegionPtr) (pgcSrc->clientClip)); + (*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, (pointer) prgnNew, 0); + break; + } +} + +/* ARGSUSED */ +void +miCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst) +{ + return; +} + +void +miComputeCompositeClip(GCPtr pGC, DrawablePtr pDrawable) +{ + if (pDrawable->type == DRAWABLE_WINDOW) { + WindowPtr pWin = (WindowPtr) pDrawable; + RegionPtr pregWin; + Bool freeTmpClip, freeCompClip; + + if (pGC->subWindowMode == IncludeInferiors) { + pregWin = NotClippedByChildren(pWin); + freeTmpClip = TRUE; + } + else { + pregWin = &pWin->clipList; + freeTmpClip = FALSE; + } + freeCompClip = pGC->freeCompClip; + + /* + * if there is no client clip, we can get by with just keeping the + * pointer we got, and remembering whether or not should destroy (or + * maybe re-use) it later. this way, we avoid unnecessary copying of + * regions. (this wins especially if many clients clip by children + * and have no client clip.) + */ + if (pGC->clientClipType == CT_NONE) { + if (freeCompClip) + RegionDestroy(pGC->pCompositeClip); + pGC->pCompositeClip = pregWin; + pGC->freeCompClip = freeTmpClip; + } + else { + /* + * we need one 'real' region to put into the composite clip. if + * pregWin the current composite clip are real, we can get rid of + * one. if pregWin is real and the current composite clip isn't, + * use pregWin for the composite clip. if the current composite + * clip is real and pregWin isn't, use the current composite + * clip. if neither is real, create a new region. + */ + + RegionTranslate(pGC->clientClip, + pDrawable->x + pGC->clipOrg.x, + pDrawable->y + pGC->clipOrg.y); + + if (freeCompClip) { + RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip); + if (freeTmpClip) + RegionDestroy(pregWin); + } + else if (freeTmpClip) { + RegionIntersect(pregWin, pregWin, pGC->clientClip); + pGC->pCompositeClip = pregWin; + } + else { + pGC->pCompositeClip = RegionCreate(NullBox, 0); + RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip); + } + pGC->freeCompClip = TRUE; + RegionTranslate(pGC->clientClip, + -(pDrawable->x + pGC->clipOrg.x), + -(pDrawable->y + pGC->clipOrg.y)); + } + } /* end of composite clip for a window */ + else { + BoxRec pixbounds; + + /* XXX should we translate by drawable.x/y here ? */ + /* If you want pixmaps in offscreen memory, yes */ + pixbounds.x1 = pDrawable->x; + pixbounds.y1 = pDrawable->y; + pixbounds.x2 = pDrawable->x + pDrawable->width; + pixbounds.y2 = pDrawable->y + pDrawable->height; + + if (pGC->freeCompClip) { + RegionReset(pGC->pCompositeClip, &pixbounds); + } + else { + pGC->freeCompClip = TRUE; + pGC->pCompositeClip = RegionCreate(&pixbounds, 1); + } + + if (pGC->clientClipType == CT_REGION) { + if (pDrawable->x || pDrawable->y) { + RegionTranslate(pGC->clientClip, + pDrawable->x + pGC->clipOrg.x, + pDrawable->y + pGC->clipOrg.y); + RegionIntersect(pGC->pCompositeClip, + pGC->pCompositeClip, pGC->clientClip); + RegionTranslate(pGC->clientClip, + -(pDrawable->x + pGC->clipOrg.x), + -(pDrawable->y + pGC->clipOrg.y)); + } + else { + RegionTranslate(pGC->pCompositeClip, + -pGC->clipOrg.x, -pGC->clipOrg.y); + RegionIntersect(pGC->pCompositeClip, + pGC->pCompositeClip, pGC->clientClip); + RegionTranslate(pGC->pCompositeClip, + pGC->clipOrg.x, pGC->clipOrg.y); + } + } + } /* end of composite clip for pixmap */ +} /* end miComputeCompositeClip */ diff --git a/xorg-server/mi/migc.h b/xorg-server/mi/migc.h index df5805f4d..8c13b2e53 100644 --- a/xorg-server/mi/migc.h +++ b/xorg-server/mi/migc.h @@ -26,39 +26,31 @@ from The Open Group. */ - -extern _X_EXPORT void miChangeGC( - GCPtr /*pGC*/, - unsigned long /*mask*/ -); - -extern _X_EXPORT void miDestroyGC( - GCPtr /*pGC*/ -); - -extern _X_EXPORT void miDestroyClip( - GCPtr /*pGC*/ -); - -extern _X_EXPORT void miChangeClip( - GCPtr /*pGC*/, - int /*type*/, - pointer /*pvalue*/, - int /*nrects*/ -); - -extern _X_EXPORT void miCopyClip( - GCPtr /*pgcDst*/, - GCPtr /*pgcSrc*/ -); - -extern _X_EXPORT void miCopyGC( - GCPtr /*pGCSrc*/, - unsigned long /*changes*/, - GCPtr /*pGCDst*/ -); - -extern _X_EXPORT void miComputeCompositeClip( - GCPtr /*pGC*/, - DrawablePtr /*pDrawable*/ -); +extern _X_EXPORT void miChangeGC(GCPtr /*pGC */ , + unsigned long /*mask */ + ); + +extern _X_EXPORT void miDestroyGC(GCPtr /*pGC */ + ); + +extern _X_EXPORT void miDestroyClip(GCPtr /*pGC */ + ); + +extern _X_EXPORT void miChangeClip(GCPtr /*pGC */ , + int /*type */ , + pointer /*pvalue */ , + int /*nrects */ + ); + +extern _X_EXPORT void miCopyClip(GCPtr /*pgcDst */ , + GCPtr /*pgcSrc */ + ); + +extern _X_EXPORT void miCopyGC(GCPtr /*pGCSrc */ , + unsigned long /*changes */ , + GCPtr /*pGCDst */ + ); + +extern _X_EXPORT void miComputeCompositeClip(GCPtr /*pGC */ , + DrawablePtr /*pDrawable */ + ); diff --git a/xorg-server/mi/miglblt.c b/xorg-server/mi/miglblt.c index b93ef5efa..1a70911fa 100644 --- a/xorg-server/mi/miglblt.c +++ b/xorg-server/mi/miglblt.c @@ -1,256 +1,232 @@ -/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xmd.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include <X11/fonts/fontstruct.h>
-#include "dixfontstr.h"
-#include "gcstruct.h"
-#include "windowstr.h"
-#include "scrnintstr.h"
-#include "pixmap.h"
-#include "servermd.h"
-#include "mi.h"
-
-/*
- machine-independent glyph blt.
- assumes that glyph bits in snf are written in bytes,
-have same bit order as the server's bitmap format,
-and are byte padded. this corresponds to the snf distributed
-with the sample server.
-
- get a scratch GC.
- in the scratch GC set alu = GXcopy, fg = 1, bg = 0
- allocate a bitmap big enough to hold the largest glyph in the font
- validate the scratch gc with the bitmap
- for each glyph
- carefully put the bits of the glyph in a buffer,
- padded to the server pixmap scanline padding rules
- fake a call to PutImage from the buffer into the bitmap
- use the bitmap in a call to PushPixels
-*/
-
-void
-miPolyGlyphBlt(
- DrawablePtr pDrawable,
- GC *pGC,
- int x,
- int y,
- unsigned int nglyph,
- CharInfoPtr *ppci, /* array of character info */
- pointer pglyphBase /* start of array of glyphs */
- )
-{
- int width, height;
- PixmapPtr pPixmap;
- int nbyLine; /* bytes per line of padded pixmap */
- FontPtr pfont;
- GCPtr pGCtmp;
- int i;
- int j;
- unsigned char *pbits; /* buffer for PutImage */
- unsigned char *pb; /* temp pointer into buffer */
- CharInfoPtr pci; /* currect char info */
- unsigned char *pglyph; /* pointer bits in glyph */
- int gWidth, gHeight; /* width and height of glyph */
- int nbyGlyphWidth; /* bytes per scanline of glyph */
- int nbyPadGlyph; /* server padded line of glyph */
-
- ChangeGCVal gcvals[3];
-
- if (pGC->miTranslate)
- {
- x += pDrawable->x;
- y += pDrawable->y;
- }
-
- pfont = pGC->font;
- width = FONTMAXBOUNDS(pfont,rightSideBearing) -
- FONTMINBOUNDS(pfont,leftSideBearing);
- height = FONTMAXBOUNDS(pfont,ascent) +
- FONTMAXBOUNDS(pfont,descent);
-
- pPixmap = (*pDrawable->pScreen->CreatePixmap)(pDrawable->pScreen,
- width, height, 1,
- CREATE_PIXMAP_USAGE_SCRATCH);
- if (!pPixmap)
- return;
-
- pGCtmp = GetScratchGC(1, pDrawable->pScreen);
- if (!pGCtmp)
- {
- (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
- return;
- }
-
- gcvals[0].val = GXcopy;
- gcvals[1].val = 1;
- gcvals[2].val = 0;
-
- ChangeGC(NullClient, pGCtmp, GCFunction|GCForeground|GCBackground, gcvals);
-
- nbyLine = BitmapBytePad(width);
- pbits = malloc(height*nbyLine);
- if (!pbits)
- {
- (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
- FreeScratchGC(pGCtmp);
- return;
- }
- while(nglyph--)
- {
- pci = *ppci++;
- pglyph = FONTGLYPHBITS(pglyphBase, pci);
- gWidth = GLYPHWIDTHPIXELS(pci);
- gHeight = GLYPHHEIGHTPIXELS(pci);
- if (gWidth && gHeight)
- {
- nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci);
- nbyPadGlyph = BitmapBytePad(gWidth);
-
- if (nbyGlyphWidth == nbyPadGlyph
-#if GLYPHPADBYTES != 4
- && (((int) pglyph) & 3) == 0
-#endif
- )
- {
- pb = pglyph;
- }
- else
- {
- for (i=0, pb = pbits; i<gHeight; i++, pb = pbits+(i*nbyPadGlyph))
- for (j = 0; j < nbyGlyphWidth; j++)
- *pb++ = *pglyph++;
- pb = pbits;
- }
-
- if ((pGCtmp->serialNumber) != (pPixmap->drawable.serialNumber))
- ValidateGC((DrawablePtr)pPixmap, pGCtmp);
- (*pGCtmp->ops->PutImage)((DrawablePtr)pPixmap, pGCtmp,
- pPixmap->drawable.depth,
- 0, 0, gWidth, gHeight,
- 0, XYBitmap, (char *)pb);
-
- (*pGC->ops->PushPixels)(pGC, pPixmap, pDrawable,
- gWidth, gHeight,
- x + pci->metrics.leftSideBearing,
- y - pci->metrics.ascent);
- }
- x += pci->metrics.characterWidth;
- }
- (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
- free(pbits);
- FreeScratchGC(pGCtmp);
-}
-
-
-void
-miImageGlyphBlt(
- DrawablePtr pDrawable,
- GC *pGC,
- int x,
- int y,
- unsigned int nglyph,
- CharInfoPtr *ppci, /* array of character info */
- pointer pglyphBase /* start of array of glyphs */
- )
-{
- ExtentInfoRec info; /* used by QueryGlyphExtents() */
- ChangeGCVal gcvals[3];
- int oldAlu, oldFS;
- unsigned long oldFG;
- xRectangle backrect;
-
- QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info);
-
- if (info.overallWidth >= 0)
- {
- backrect.x = x;
- backrect.width = info.overallWidth;
- }
- else
- {
- backrect.x = x + info.overallWidth;
- backrect.width = -info.overallWidth;
- }
- backrect.y = y - FONTASCENT(pGC->font);
- backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
-
- oldAlu = pGC->alu;
- oldFG = pGC->fgPixel;
- oldFS = pGC->fillStyle;
-
- /* fill in the background */
- gcvals[0].val = GXcopy;
- gcvals[1].val = pGC->bgPixel;
- gcvals[2].val = FillSolid;
- ChangeGC(NullClient, pGC, GCFunction|GCForeground|GCFillStyle, gcvals);
- ValidateGC(pDrawable, pGC);
- (*pGC->ops->PolyFillRect)(pDrawable, pGC, 1, &backrect);
-
- /* put down the glyphs */
- gcvals[0].val = oldFG;
- ChangeGC(NullClient, pGC, GCForeground, gcvals);
- ValidateGC(pDrawable, pGC);
- (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph, ppci,
- pglyphBase);
-
- /* put all the toys away when done playing */
- gcvals[0].val = oldAlu;
- gcvals[1].val = oldFG;
- gcvals[2].val = oldFS;
- ChangeGC(NullClient, pGC, GCFunction|GCForeground|GCFillStyle, gcvals);
- ValidateGC(pDrawable, pGC);
-
-}
+/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xmd.h> +#include <X11/Xproto.h> +#include "misc.h" +#include <X11/fonts/fontstruct.h> +#include "dixfontstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmap.h" +#include "servermd.h" +#include "mi.h" + +/* + machine-independent glyph blt. + assumes that glyph bits in snf are written in bytes, +have same bit order as the server's bitmap format, +and are byte padded. this corresponds to the snf distributed +with the sample server. + + get a scratch GC. + in the scratch GC set alu = GXcopy, fg = 1, bg = 0 + allocate a bitmap big enough to hold the largest glyph in the font + validate the scratch gc with the bitmap + for each glyph + carefully put the bits of the glyph in a buffer, + padded to the server pixmap scanline padding rules + fake a call to PutImage from the buffer into the bitmap + use the bitmap in a call to PushPixels +*/ + +void +miPolyGlyphBlt(DrawablePtr pDrawable, GC * pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, /* array of character info */ + pointer pglyphBase /* start of array of glyphs */ + ) +{ + int width, height; + PixmapPtr pPixmap; + int nbyLine; /* bytes per line of padded pixmap */ + FontPtr pfont; + GCPtr pGCtmp; + int i; + int j; + unsigned char *pbits; /* buffer for PutImage */ + unsigned char *pb; /* temp pointer into buffer */ + CharInfoPtr pci; /* currect char info */ + unsigned char *pglyph; /* pointer bits in glyph */ + int gWidth, gHeight; /* width and height of glyph */ + int nbyGlyphWidth; /* bytes per scanline of glyph */ + int nbyPadGlyph; /* server padded line of glyph */ + + ChangeGCVal gcvals[3]; + + if (pGC->miTranslate) { + x += pDrawable->x; + y += pDrawable->y; + } + + pfont = pGC->font; + width = FONTMAXBOUNDS(pfont, rightSideBearing) - + FONTMINBOUNDS(pfont, leftSideBearing); + height = FONTMAXBOUNDS(pfont, ascent) + FONTMAXBOUNDS(pfont, descent); + + pPixmap = (*pDrawable->pScreen->CreatePixmap) (pDrawable->pScreen, + width, height, 1, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!pPixmap) + return; + + pGCtmp = GetScratchGC(1, pDrawable->pScreen); + if (!pGCtmp) { + (*pDrawable->pScreen->DestroyPixmap) (pPixmap); + return; + } + + gcvals[0].val = GXcopy; + gcvals[1].val = 1; + gcvals[2].val = 0; + + ChangeGC(NullClient, pGCtmp, GCFunction | GCForeground | GCBackground, + gcvals); + + nbyLine = BitmapBytePad(width); + pbits = malloc(height * nbyLine); + if (!pbits) { + (*pDrawable->pScreen->DestroyPixmap) (pPixmap); + FreeScratchGC(pGCtmp); + return; + } + while (nglyph--) { + pci = *ppci++; + pglyph = FONTGLYPHBITS(pglyphBase, pci); + gWidth = GLYPHWIDTHPIXELS(pci); + gHeight = GLYPHHEIGHTPIXELS(pci); + if (gWidth && gHeight) { + nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci); + nbyPadGlyph = BitmapBytePad(gWidth); + + if (nbyGlyphWidth == nbyPadGlyph +#if GLYPHPADBYTES != 4 + && (((int) pglyph) & 3) == 0 +#endif + ) { + pb = pglyph; + } + else { + for (i = 0, pb = pbits; i < gHeight; + i++, pb = pbits + (i * nbyPadGlyph)) + for (j = 0; j < nbyGlyphWidth; j++) + *pb++ = *pglyph++; + pb = pbits; + } + + if ((pGCtmp->serialNumber) != (pPixmap->drawable.serialNumber)) + ValidateGC((DrawablePtr) pPixmap, pGCtmp); + (*pGCtmp->ops->PutImage) ((DrawablePtr) pPixmap, pGCtmp, + pPixmap->drawable.depth, + 0, 0, gWidth, gHeight, + 0, XYBitmap, (char *) pb); + + (*pGC->ops->PushPixels) (pGC, pPixmap, pDrawable, + gWidth, gHeight, + x + pci->metrics.leftSideBearing, + y - pci->metrics.ascent); + } + x += pci->metrics.characterWidth; + } + (*pDrawable->pScreen->DestroyPixmap) (pPixmap); + free(pbits); + FreeScratchGC(pGCtmp); +} + +void +miImageGlyphBlt(DrawablePtr pDrawable, GC * pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, /* array of character info */ + pointer pglyphBase /* start of array of glyphs */ + ) +{ + ExtentInfoRec info; /* used by QueryGlyphExtents() */ + ChangeGCVal gcvals[3]; + int oldAlu, oldFS; + unsigned long oldFG; + xRectangle backrect; + + QueryGlyphExtents(pGC->font, ppci, (unsigned long) nglyph, &info); + + if (info.overallWidth >= 0) { + backrect.x = x; + backrect.width = info.overallWidth; + } + else { + backrect.x = x + info.overallWidth; + backrect.width = -info.overallWidth; + } + backrect.y = y - FONTASCENT(pGC->font); + backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); + + oldAlu = pGC->alu; + oldFG = pGC->fgPixel; + oldFS = pGC->fillStyle; + + /* fill in the background */ + gcvals[0].val = GXcopy; + gcvals[1].val = pGC->bgPixel; + gcvals[2].val = FillSolid; + ChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFillStyle, gcvals); + ValidateGC(pDrawable, pGC); + (*pGC->ops->PolyFillRect) (pDrawable, pGC, 1, &backrect); + + /* put down the glyphs */ + gcvals[0].val = oldFG; + ChangeGC(NullClient, pGC, GCForeground, gcvals); + ValidateGC(pDrawable, pGC); + (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + + /* put all the toys away when done playing */ + gcvals[0].val = oldAlu; + gcvals[1].val = oldFG; + gcvals[2].val = oldFS; + ChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFillStyle, gcvals); + ValidateGC(pDrawable, pGC); + +} diff --git a/xorg-server/mi/miinitext.c b/xorg-server/mi/miinitext.c index 3076e7b28..462bcfff5 100644 --- a/xorg-server/mi/miinitext.c +++ b/xorg-server/mi/miinitext.c @@ -22,7 +22,6 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved @@ -94,7 +93,6 @@ SOFTWARE. #include "micmap.h" #include "globals.h" - extern Bool noTestExtensions; #ifdef COMPOSITE @@ -119,6 +117,7 @@ extern Bool noMITShmExtension; extern Bool noRRExtension; #endif extern Bool noRenderExtension; + #ifdef XCSECURITY extern Bool noSecurityExtension; #endif @@ -156,8 +155,8 @@ extern Bool noGEExtension; #ifndef XFree86LOADER #define INITARGS void -typedef void (*InitExtension)(INITARGS); -#else /* XFree86Loader */ +typedef void (*InitExtension) (INITARGS); +#else /* XFree86Loader */ #include "loaderProcs.h" #endif @@ -196,12 +195,14 @@ extern void PanoramiXExtensionInit(INITARGS); extern void PseudoramiXExtensionInit(INITARGS); #endif extern void XInputExtensionInit(INITARGS); + #ifdef XTEST extern void XTestExtensionInit(INITARGS); #endif extern void BigReqExtensionInit(INITARGS); + #ifdef SCREENSAVER -extern void ScreenSaverExtensionInit (INITARGS); +extern void ScreenSaverExtensionInit(INITARGS); #endif #ifdef XV extern void XvExtensionInit(INITARGS); @@ -210,6 +211,7 @@ extern void XvMCExtensionInit(INITARGS); extern void SyncExtensionInit(INITARGS); extern void XkbExtensionInit(INITARGS); extern void XCMiscExtensionInit(INITARGS); + #ifdef XRECORD extern void RecordExtensionInit(INITARGS); #endif @@ -234,7 +236,7 @@ extern void XFree86DGAExtensionInit(INITARGS); #ifdef GLXEXT typedef struct __GLXprovider __GLXprovider; extern __GLXprovider __glXDRISWRastProvider; -extern void GlxPushProvider(__GLXprovider *impl); +extern void GlxPushProvider(__GLXprovider * impl); extern void GlxExtensionInit(INITARGS); #endif #ifdef XF86DRI @@ -244,6 +246,7 @@ extern void XFree86DRIExtensionInit(INITARGS); extern void DPMSExtensionInit(INITARGS); #endif extern void RenderExtensionInit(INITARGS); + #ifdef RANDR extern void RRExtensionInit(INITARGS); #endif @@ -272,253 +275,279 @@ typedef struct { Bool *disablePtr; } ExtensionToggle; -static ExtensionToggle ExtensionToggleList[] = -{ +static ExtensionToggle ExtensionToggleList[] = { /* sort order is extension name string as shown in xdpyinfo */ - { "Generic Events", &noGEExtension }, + {"Generic Events", &noGEExtension}, #ifdef COMPOSITE - { "Composite", &noCompositeExtension }, + {"Composite", &noCompositeExtension}, #endif #ifdef DAMAGE - { "DAMAGE", &noDamageExtension }, + {"DAMAGE", &noDamageExtension}, #endif #ifdef DBE - { "DOUBLE-BUFFER", &noDbeExtension }, + {"DOUBLE-BUFFER", &noDbeExtension}, #endif #ifdef DPMSExtension - { "DPMS", &noDPMSExtension }, + {"DPMS", &noDPMSExtension}, #endif #ifdef GLXEXT - { "GLX", &noGlxExtension }, + {"GLX", &noGlxExtension}, #endif #ifdef SCREENSAVER - { "MIT-SCREEN-SAVER", &noScreenSaverExtension }, + {"MIT-SCREEN-SAVER", &noScreenSaverExtension}, #endif #ifdef MITSHM - { SHMNAME, &noMITShmExtension }, + {SHMNAME, &noMITShmExtension}, #endif #ifdef RANDR - { "RANDR", &noRRExtension }, + {"RANDR", &noRRExtension}, #endif - { "RENDER", &noRenderExtension }, + {"RENDER", &noRenderExtension}, #ifdef XCSECURITY - { "SECURITY", &noSecurityExtension }, + {"SECURITY", &noSecurityExtension}, #endif #ifdef RES - { "X-Resource", &noResExtension }, + {"X-Resource", &noResExtension}, #endif #ifdef XF86BIGFONT - { "XFree86-Bigfont", &noXFree86BigfontExtension }, + {"XFree86-Bigfont", &noXFree86BigfontExtension}, #endif #ifdef XFreeXDGA - { "XFree86-DGA", &noXFree86DGAExtension }, + {"XFree86-DGA", &noXFree86DGAExtension}, #endif #ifdef XF86DRI - { "XFree86-DRI", &noXFree86DRIExtension }, + {"XFree86-DRI", &noXFree86DRIExtension}, #endif #ifdef XF86VIDMODE - { "XFree86-VidModeExtension", &noXFree86VidModeExtension }, + {"XFree86-VidModeExtension", &noXFree86VidModeExtension}, #endif #ifdef XFIXES - { "XFIXES", &noXFixesExtension }, + {"XFIXES", &noXFixesExtension}, #endif #ifdef PANORAMIX - { "XINERAMA", &noPanoramiXExtension }, + {"XINERAMA", &noPanoramiXExtension}, #endif - { "XInputExtension", NULL }, - { "XKEYBOARD", NULL }, + {"XInputExtension", NULL}, + {"XKEYBOARD", NULL}, #ifdef XSELINUX - { "SELinux", &noSELinuxExtension }, + {"SELinux", &noSELinuxExtension}, #endif - { "XTEST", &noTestExtensions }, + {"XTEST", &noTestExtensions}, #ifdef XV - { "XVideo", &noXvExtension }, + {"XVideo", &noXvExtension}, #endif - { NULL, NULL } + {NULL, NULL} }; -Bool EnableDisableExtension(const char *name, Bool enable) +Bool +EnableDisableExtension(const char *name, Bool enable) { ExtensionToggle *ext = &ExtensionToggleList[0]; for (ext = &ExtensionToggleList[0]; ext->name != NULL; ext++) { - if (strcmp(name, ext->name) == 0) { - if (ext->disablePtr != NULL) { - *ext->disablePtr = !enable; - return TRUE; - } else { - /* Extension is always on, impossible to disable */ - return enable; /* okay if they wanted to enable, - fail if they tried to disable */ - } - } + if (strcmp(name, ext->name) == 0) { + if (ext->disablePtr != NULL) { + *ext->disablePtr = !enable; + return TRUE; + } + else { + /* Extension is always on, impossible to disable */ + return enable; /* okay if they wanted to enable, + fail if they tried to disable */ + } + } } return FALSE; } -void EnableDisableExtensionError(const char *name, Bool enable) +void +EnableDisableExtensionError(const char *name, Bool enable) { ExtensionToggle *ext = &ExtensionToggleList[0]; Bool found = FALSE; for (ext = &ExtensionToggleList[0]; ext->name != NULL; ext++) { - if ((strcmp(name, ext->name) == 0) && (ext->disablePtr == NULL)) { - ErrorF("[mi] Extension \"%s\" can not be disabled\n", name); - found = TRUE; - break; - } + if ((strcmp(name, ext->name) == 0) && (ext->disablePtr == NULL)) { + ErrorF("[mi] Extension \"%s\" can not be disabled\n", name); + found = TRUE; + break; + } } if (found == FALSE) - ErrorF("[mi] Extension \"%s\" is not recognized\n", name); + ErrorF("[mi] Extension \"%s\" is not recognized\n", name); ErrorF("[mi] Only the following extensions can be run-time %s:\n", - enable ? "enabled" : "disabled"); + enable ? "enabled" : "disabled"); for (ext = &ExtensionToggleList[0]; ext->name != NULL; ext++) { - if (ext->disablePtr != NULL) { - ErrorF("[mi] %s\n", ext->name); - } + if (ext->disablePtr != NULL) { + ErrorF("[mi] %s\n", ext->name); + } } } #ifndef XFree86LOADER -/*ARGSUSED*/ -void + /*ARGSUSED*/ void InitExtensions(int argc, char *argv[]) { - if (!noGEExtension) GEExtensionInit(); + if (!noGEExtension) + GEExtensionInit(); #ifdef PANORAMIX - if (!noPanoramiXExtension) PanoramiXExtensionInit(); + if (!noPanoramiXExtension) + PanoramiXExtensionInit(); #endif #ifdef INXQUARTZ - if(!noPseudoramiXExtension) PseudoramiXExtensionInit(); + if (!noPseudoramiXExtension) + PseudoramiXExtensionInit(); #endif ShapeExtensionInit(); #ifdef MITSHM - if (!noMITShmExtension) ShmExtensionInit(); + if (!noMITShmExtension) + ShmExtensionInit(); #endif XInputExtensionInit(); #ifdef XTEST - if (!noTestExtensions) XTestExtensionInit(); + if (!noTestExtensions) + XTestExtensionInit(); #endif BigReqExtensionInit(); #if defined(SCREENSAVER) - if (!noScreenSaverExtension) ScreenSaverExtensionInit (); + if (!noScreenSaverExtension) + ScreenSaverExtensionInit(); #endif #ifdef XV if (!noXvExtension) { - XvExtensionInit(); - XvMCExtensionInit(); + XvExtensionInit(); + XvMCExtensionInit(); } #endif SyncExtensionInit(); XkbExtensionInit(); XCMiscExtensionInit(); #ifdef XRECORD - if (!noTestExtensions) RecordExtensionInit(); + if (!noTestExtensions) + RecordExtensionInit(); #endif #ifdef DBE - if (!noDbeExtension) DbeExtensionInit(); + if (!noDbeExtension) + DbeExtensionInit(); #endif #ifdef XCSECURITY - if (!noSecurityExtension) SecurityExtensionInit(); + if (!noSecurityExtension) + SecurityExtensionInit(); #endif #ifdef XSELINUX - if (!noSELinuxExtension) SELinuxExtensionInit(); + if (!noSELinuxExtension) + SELinuxExtensionInit(); #endif #if defined(DPMSExtension) && !defined(NO_HW_ONLY_EXTS) - if (!noDPMSExtension) DPMSExtensionInit(); + if (!noDPMSExtension) + DPMSExtensionInit(); #endif #ifdef XF86BIGFONT - if (!noXFree86BigfontExtension) XFree86BigfontExtensionInit(); + if (!noXFree86BigfontExtension) + XFree86BigfontExtensionInit(); #endif #if !defined(NO_HW_ONLY_EXTS) #if defined(XF86VIDMODE) - if (!noXFree86VidModeExtension) XFree86VidModeExtensionInit(); + if (!noXFree86VidModeExtension) + XFree86VidModeExtensionInit(); #endif #if defined(XFreeXDGA) - if (!noXFree86DGAExtension) XFree86DGAExtensionInit(); + if (!noXFree86DGAExtension) + XFree86DGAExtensionInit(); #endif #ifdef XF86DRI - if (!noXFree86DRIExtension) XFree86DRIExtensionInit(); + if (!noXFree86DRIExtension) + XFree86DRIExtensionInit(); #endif #endif #ifdef XFIXES /* must be before Render to layer DisplayCursor correctly */ - if (!noXFixesExtension) XFixesExtensionInit(); + if (!noXFixesExtension) + XFixesExtensionInit(); #endif - if (!noRenderExtension) RenderExtensionInit(); + if (!noRenderExtension) + RenderExtensionInit(); #ifdef RANDR - if (!noRRExtension) RRExtensionInit(); + if (!noRRExtension) + RRExtensionInit(); #endif #ifdef RES - if (!noResExtension) ResExtensionInit(); + if (!noResExtension) + ResExtensionInit(); #endif #ifdef DMXEXT - DMXExtensionInit(); /* server-specific extension, cannot be disabled */ + DMXExtensionInit(); /* server-specific extension, cannot be disabled */ #endif #ifdef COMPOSITE - if (!noCompositeExtension) CompositeExtensionInit(); + if (!noCompositeExtension) + CompositeExtensionInit(); #endif #ifdef DAMAGE - if (!noDamageExtension) DamageExtensionInit(); + if (!noDamageExtension) + DamageExtensionInit(); #endif #ifdef GLXEXT if (serverGeneration == 1) { - GlxPushProvider(&__glXDRISWRastProvider); - glxWinPushNativeProvider(); + GlxPushProvider(&__glXDRISWRastProvider); + glxWinPushNativeProvider(); } - if (!noGlxExtension) GlxExtensionInit(); + if (!noGlxExtension) + GlxExtensionInit(); + #endif } -#else /* XFree86LOADER */ +#else /* XFree86LOADER */ /* List of built-in (statically linked) extensions */ static ExtensionModule staticExtensions[] = { - { GEExtensionInit, "Generic Event Extension", &noGEExtension, NULL, NULL}, - { ShapeExtensionInit, "SHAPE", NULL, NULL, NULL }, + {GEExtensionInit, "Generic Event Extension", &noGEExtension, NULL, NULL}, + {ShapeExtensionInit, "SHAPE", NULL, NULL, NULL}, #ifdef MITSHM - { ShmExtensionInit, SHMNAME, &noMITShmExtension, NULL, NULL }, + {ShmExtensionInit, SHMNAME, &noMITShmExtension, NULL, NULL}, #endif - { XInputExtensionInit, "XInputExtension", NULL, NULL, NULL }, + {XInputExtensionInit, "XInputExtension", NULL, NULL, NULL}, #ifdef XTEST - { XTestExtensionInit, XTestExtensionName, &noTestExtensions, NULL, NULL }, + {XTestExtensionInit, XTestExtensionName, &noTestExtensions, NULL, NULL}, #endif - { BigReqExtensionInit, "BIG-REQUESTS", NULL, NULL, NULL }, - { SyncExtensionInit, "SYNC", NULL, NULL, NULL }, - { XkbExtensionInit, XkbName, NULL, NULL, NULL }, - { XCMiscExtensionInit, "XC-MISC", NULL, NULL, NULL }, + {BigReqExtensionInit, "BIG-REQUESTS", NULL, NULL, NULL}, + {SyncExtensionInit, "SYNC", NULL, NULL, NULL}, + {XkbExtensionInit, XkbName, NULL, NULL, NULL}, + {XCMiscExtensionInit, "XC-MISC", NULL, NULL, NULL}, #ifdef XCSECURITY - { SecurityExtensionInit, SECURITY_EXTENSION_NAME, &noSecurityExtension, NULL, NULL }, + {SecurityExtensionInit, SECURITY_EXTENSION_NAME, &noSecurityExtension, NULL, + NULL}, #endif #ifdef PANORAMIX - { PanoramiXExtensionInit, PANORAMIX_PROTOCOL_NAME, &noPanoramiXExtension, NULL, NULL }, + {PanoramiXExtensionInit, PANORAMIX_PROTOCOL_NAME, &noPanoramiXExtension, + NULL, NULL}, #endif #ifdef XFIXES /* must be before Render to layer DisplayCursor correctly */ - { XFixesExtensionInit, "XFIXES", &noXFixesExtension, NULL, NULL }, + {XFixesExtensionInit, "XFIXES", &noXFixesExtension, NULL, NULL}, #endif #ifdef XF86BIGFONT - { XFree86BigfontExtensionInit, XF86BIGFONTNAME, &noXFree86BigfontExtension, NULL, NULL }, + {XFree86BigfontExtensionInit, XF86BIGFONTNAME, &noXFree86BigfontExtension, + NULL, NULL}, #endif - { RenderExtensionInit, "RENDER", &noRenderExtension, NULL, NULL }, + {RenderExtensionInit, "RENDER", &noRenderExtension, NULL, NULL}, #ifdef RANDR - { RRExtensionInit, "RANDR", &noRRExtension, NULL, NULL }, + {RRExtensionInit, "RANDR", &noRRExtension, NULL, NULL}, #endif #ifdef COMPOSITE - { CompositeExtensionInit, "COMPOSITE", &noCompositeExtension, NULL }, + {CompositeExtensionInit, "COMPOSITE", &noCompositeExtension, NULL}, #endif #ifdef DAMAGE - { DamageExtensionInit, "DAMAGE", &noDamageExtension, NULL }, + {DamageExtensionInit, "DAMAGE", &noDamageExtension, NULL}, #endif - { NULL, NULL, NULL, NULL, NULL } + {NULL, NULL, NULL, NULL, NULL} }; - -/*ARGSUSED*/ -void + + /*ARGSUSED*/ void InitExtensions(int argc, char *argv[]) { int i; @@ -526,22 +555,22 @@ InitExtensions(int argc, char *argv[]) static Bool listInitialised = FALSE; if (!listInitialised) { - /* Add built-in extensions to the list. */ - for (i = 0; staticExtensions[i].name; i++) - LoadExtension(&staticExtensions[i], TRUE); + /* Add built-in extensions to the list. */ + for (i = 0; staticExtensions[i].name; i++) + LoadExtension(&staticExtensions[i], TRUE); - /* Sort the extensions according the init dependencies. */ - LoaderSortExtensions(); - listInitialised = TRUE; + /* Sort the extensions according the init dependencies. */ + LoaderSortExtensions(); + listInitialised = TRUE; } for (i = 0; ExtensionModuleList[i].name != NULL; i++) { - ext = &ExtensionModuleList[i]; - if (ext->initFunc != NULL && - (ext->disablePtr == NULL || !*ext->disablePtr)) { - (ext->initFunc)(); - } + ext = &ExtensionModuleList[i]; + if (ext->initFunc != NULL && + (ext->disablePtr == NULL || !*ext->disablePtr)) { + (ext->initFunc) (); + } } } -#endif /* XFree86LOADER */ +#endif /* XFree86LOADER */ diff --git a/xorg-server/mi/miline.h b/xorg-server/mi/miline.h index 0f2fc3374..c1a51c15c 100644 --- a/xorg-server/mi/miline.h +++ b/xorg-server/mi/miline.h @@ -1,173 +1,172 @@ -
-/*
-
-Copyright 1994, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-
-#ifndef MILINE_H
-
-#include "screenint.h"
-#include "privates.h"
-
-/*
- * Public definitions used for configuring basic pixelization aspects
- * of the sample implementation line-drawing routines provided in
- * {mfb,mi,cfb*} at run-time.
- */
-
-#define XDECREASING 4
-#define YDECREASING 2
-#define YMAJOR 1
-
-#define OCTANT1 (1 << (YDECREASING))
-#define OCTANT2 (1 << (YDECREASING|YMAJOR))
-#define OCTANT3 (1 << (XDECREASING|YDECREASING|YMAJOR))
-#define OCTANT4 (1 << (XDECREASING|YDECREASING))
-#define OCTANT5 (1 << (XDECREASING))
-#define OCTANT6 (1 << (XDECREASING|YMAJOR))
-#define OCTANT7 (1 << (YMAJOR))
-#define OCTANT8 (1 << (0))
-
-#define XMAJOROCTANTS (OCTANT1 | OCTANT4 | OCTANT5 | OCTANT8)
-
-#define DEFAULTZEROLINEBIAS (OCTANT2 | OCTANT3 | OCTANT4 | OCTANT5)
-
-/*
- * Devices can configure the rendering of routines in mi, mfb, and cfb*
- * by specifying a thin line bias to be applied to a particular screen
- * using the following function. The bias parameter is an OR'ing of
- * the appropriate OCTANT constants defined above to indicate which
- * octants to bias a line to prefer an axial step when the Bresenham
- * error term is exactly zero. The octants are mapped as follows:
- *
- * \ | /
- * \ 3 | 2 /
- * \ | /
- * 4 \ | / 1
- * \|/
- * -----------
- * /|\
- * 5 / | \ 8
- * / | \
- * / 6 | 7 \
- * / | \
- *
- * For more information, see "Ambiguities in Incremental Line Rastering,"
- * Jack E. Bresenham, IEEE CG&A, May 1987.
- */
-
-extern _X_EXPORT void miSetZeroLineBias(
- ScreenPtr /* pScreen */,
- unsigned int /* bias */
-);
-
-/*
- * Private definitions needed for drawing thin (zero width) lines
- * Used by the mi, mfb, and all cfb* components.
- */
-
-#define X_AXIS 0
-#define Y_AXIS 1
-
-#define OUT_LEFT 0x08
-#define OUT_RIGHT 0x04
-#define OUT_ABOVE 0x02
-#define OUT_BELOW 0x01
-
-#define OUTCODES(_result, _x, _y, _pbox) \
- if ( (_x) < (_pbox)->x1) (_result) |= OUT_LEFT; \
- else if ( (_x) >= (_pbox)->x2) (_result) |= OUT_RIGHT; \
- if ( (_y) < (_pbox)->y1) (_result) |= OUT_ABOVE; \
- else if ( (_y) >= (_pbox)->y2) (_result) |= OUT_BELOW;
-
-#define MIOUTCODES(outcode, x, y, xmin, ymin, xmax, ymax) \
-{\
- if (x < xmin) outcode |= OUT_LEFT;\
- if (x > xmax) outcode |= OUT_RIGHT;\
- if (y < ymin) outcode |= OUT_ABOVE;\
- if (y > ymax) outcode |= OUT_BELOW;\
-}
-
-#define SWAPINT(i, j) \
-{ int _t = i; i = j; j = _t; }
-
-#define SWAPPT(i, j) \
-{ DDXPointRec _t; _t = i; i = j; j = _t; }
-
-#define SWAPINT_PAIR(x1, y1, x2, y2)\
-{ int t = x1; x1 = x2; x2 = t;\
- t = y1; y1 = y2; y2 = t;\
-}
-
-#define miGetZeroLineBias(_pScreen) ((unsigned long) (unsigned long*)\
- dixLookupPrivate(&(_pScreen)->devPrivates, miZeroLineScreenKey))
-
-#define CalcLineDeltas(_x1,_y1,_x2,_y2,_adx,_ady,_sx,_sy,_SX,_SY,_octant) \
- (_octant) = 0; \
- (_sx) = (_SX); \
- if (((_adx) = (_x2) - (_x1)) < 0) { \
- (_adx) = -(_adx); \
- (_sx = -(_sx)); \
- (_octant) |= XDECREASING; \
- } \
- (_sy) = (_SY); \
- if (((_ady) = (_y2) - (_y1)) < 0) { \
- (_ady) = -(_ady); \
- (_sy = -(_sy)); \
- (_octant) |= YDECREASING; \
- }
-
-#define SetYMajorOctant(_octant) ((_octant) |= YMAJOR)
-
-#define FIXUP_ERROR(_e, _octant, _bias) \
- (_e) -= (((_bias) >> (_octant)) & 1)
-
-#define IsXMajorOctant(_octant) (!((_octant) & YMAJOR))
-#define IsYMajorOctant(_octant) ((_octant) & YMAJOR)
-#define IsXDecreasingOctant(_octant) ((_octant) & XDECREASING)
-#define IsYDecreasingOctant(_octant) ((_octant) & YDECREASING)
-
-extern _X_EXPORT DevPrivateKeyRec miZeroLineScreenKeyRec;
-#define miZeroLineScreenKey (&miZeroLineScreenKeyRec)
-
-extern _X_EXPORT int miZeroClipLine(
- int /*xmin*/,
- int /*ymin*/,
- int /*xmax*/,
- int /*ymax*/,
- int * /*new_x1*/,
- int * /*new_y1*/,
- int * /*new_x2*/,
- int * /*new_y2*/,
- unsigned int /*adx*/,
- unsigned int /*ady*/,
- int * /*pt1_clipped*/,
- int * /*pt2_clipped*/,
- int /*octant*/,
- unsigned int /*bias*/,
- int /*oc1*/,
- int /*oc2*/
-);
-
-#endif /* MILINE_H */
+ +/* + +Copyright 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifndef MILINE_H + +#include "screenint.h" +#include "privates.h" + +/* + * Public definitions used for configuring basic pixelization aspects + * of the sample implementation line-drawing routines provided in + * {mfb,mi,cfb*} at run-time. + */ + +#define XDECREASING 4 +#define YDECREASING 2 +#define YMAJOR 1 + +#define OCTANT1 (1 << (YDECREASING)) +#define OCTANT2 (1 << (YDECREASING|YMAJOR)) +#define OCTANT3 (1 << (XDECREASING|YDECREASING|YMAJOR)) +#define OCTANT4 (1 << (XDECREASING|YDECREASING)) +#define OCTANT5 (1 << (XDECREASING)) +#define OCTANT6 (1 << (XDECREASING|YMAJOR)) +#define OCTANT7 (1 << (YMAJOR)) +#define OCTANT8 (1 << (0)) + +#define XMAJOROCTANTS (OCTANT1 | OCTANT4 | OCTANT5 | OCTANT8) + +#define DEFAULTZEROLINEBIAS (OCTANT2 | OCTANT3 | OCTANT4 | OCTANT5) + +/* + * Devices can configure the rendering of routines in mi, mfb, and cfb* + * by specifying a thin line bias to be applied to a particular screen + * using the following function. The bias parameter is an OR'ing of + * the appropriate OCTANT constants defined above to indicate which + * octants to bias a line to prefer an axial step when the Bresenham + * error term is exactly zero. The octants are mapped as follows: + * + * \ | / + * \ 3 | 2 / + * \ | / + * 4 \ | / 1 + * \|/ + * ----------- + * /|\ + * 5 / | \ 8 + * / | \ + * / 6 | 7 \ + * / | \ + * + * For more information, see "Ambiguities in Incremental Line Rastering," + * Jack E. Bresenham, IEEE CG&A, May 1987. + */ + +extern _X_EXPORT void miSetZeroLineBias(ScreenPtr /* pScreen */ , + unsigned int /* bias */ + ); + +/* + * Private definitions needed for drawing thin (zero width) lines + * Used by the mi, mfb, and all cfb* components. + */ + +#define X_AXIS 0 +#define Y_AXIS 1 + +#define OUT_LEFT 0x08 +#define OUT_RIGHT 0x04 +#define OUT_ABOVE 0x02 +#define OUT_BELOW 0x01 + +#define OUTCODES(_result, _x, _y, _pbox) \ + if ( (_x) < (_pbox)->x1) (_result) |= OUT_LEFT; \ + else if ( (_x) >= (_pbox)->x2) (_result) |= OUT_RIGHT; \ + if ( (_y) < (_pbox)->y1) (_result) |= OUT_ABOVE; \ + else if ( (_y) >= (_pbox)->y2) (_result) |= OUT_BELOW; + +#define MIOUTCODES(outcode, x, y, xmin, ymin, xmax, ymax) \ +{\ + if (x < xmin) outcode |= OUT_LEFT;\ + if (x > xmax) outcode |= OUT_RIGHT;\ + if (y < ymin) outcode |= OUT_ABOVE;\ + if (y > ymax) outcode |= OUT_BELOW;\ +} + +#define SWAPINT(i, j) \ +{ int _t = i; i = j; j = _t; } + +#define SWAPPT(i, j) \ +{ DDXPointRec _t; _t = i; i = j; j = _t; } + +#define SWAPINT_PAIR(x1, y1, x2, y2)\ +{ int t = x1; x1 = x2; x2 = t;\ + t = y1; y1 = y2; y2 = t;\ +} + +#define miGetZeroLineBias(_pScreen) ((unsigned long) (unsigned long*)\ + dixLookupPrivate(&(_pScreen)->devPrivates, miZeroLineScreenKey)) + +#define CalcLineDeltas(_x1,_y1,_x2,_y2,_adx,_ady,_sx,_sy,_SX,_SY,_octant) \ + (_octant) = 0; \ + (_sx) = (_SX); \ + if (((_adx) = (_x2) - (_x1)) < 0) { \ + (_adx) = -(_adx); \ + (_sx = -(_sx)); \ + (_octant) |= XDECREASING; \ + } \ + (_sy) = (_SY); \ + if (((_ady) = (_y2) - (_y1)) < 0) { \ + (_ady) = -(_ady); \ + (_sy = -(_sy)); \ + (_octant) |= YDECREASING; \ + } + +#define SetYMajorOctant(_octant) ((_octant) |= YMAJOR) + +#define FIXUP_ERROR(_e, _octant, _bias) \ + (_e) -= (((_bias) >> (_octant)) & 1) + +#define IsXMajorOctant(_octant) (!((_octant) & YMAJOR)) +#define IsYMajorOctant(_octant) ((_octant) & YMAJOR) +#define IsXDecreasingOctant(_octant) ((_octant) & XDECREASING) +#define IsYDecreasingOctant(_octant) ((_octant) & YDECREASING) + +extern _X_EXPORT DevPrivateKeyRec miZeroLineScreenKeyRec; + +#define miZeroLineScreenKey (&miZeroLineScreenKeyRec) + +extern _X_EXPORT int miZeroClipLine(int /*xmin */ , + int /*ymin */ , + int /*xmax */ , + int /*ymax */ , + int * /*new_x1 */ , + int * /*new_y1 */ , + int * /*new_x2 */ , + int * /*new_y2 */ , + unsigned int /*adx */ , + unsigned int /*ady */ , + int * /*pt1_clipped */ , + int * /*pt2_clipped */ , + int /*octant */ , + unsigned int /*bias */ , + int /*oc1 */ , + int /*oc2 */ + ); + +#endif /* MILINE_H */ diff --git a/xorg-server/mi/mioverlay.c b/xorg-server/mi/mioverlay.c index 78f5d787b..a66a71fb5 100644 --- a/xorg-server/mi/mioverlay.c +++ b/xorg-server/mi/mioverlay.c @@ -1,1950 +1,1904 @@ -
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifdef CreateWindow
-#undef CreateWindow
-#endif
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include <X11/extensions/shapeproto.h>
-#include "validate.h"
-#include "windowstr.h"
-#include "mi.h"
-#include "gcstruct.h"
-#include "regionstr.h"
-#include "privates.h"
-#include "mivalidate.h"
-#include "mioverlay.h"
-#include "migc.h"
-
-#include "globals.h"
-
-
-typedef struct {
- RegionRec exposed;
- RegionRec borderExposed;
- RegionPtr borderVisible;
- DDXPointRec oldAbsCorner;
-} miOverlayValDataRec, *miOverlayValDataPtr;
-
-typedef struct _TreeRec {
- WindowPtr pWin;
- struct _TreeRec *parent;
- struct _TreeRec *firstChild;
- struct _TreeRec *lastChild;
- struct _TreeRec *prevSib;
- struct _TreeRec *nextSib;
- RegionRec borderClip;
- RegionRec clipList;
- unsigned visibility;
- miOverlayValDataPtr valdata;
-} miOverlayTreeRec, *miOverlayTreePtr;
-
-typedef struct {
- miOverlayTreePtr tree;
-} miOverlayWindowRec, *miOverlayWindowPtr;
-
-typedef struct {
- CloseScreenProcPtr CloseScreen;
- CreateWindowProcPtr CreateWindow;
- DestroyWindowProcPtr DestroyWindow;
- UnrealizeWindowProcPtr UnrealizeWindow;
- RealizeWindowProcPtr RealizeWindow;
- miOverlayTransFunc MakeTransparent;
- miOverlayInOverlayFunc InOverlay;
- Bool underlayMarked;
- Bool copyUnderlay;
-} miOverlayScreenRec, *miOverlayScreenPtr;
-
-static DevPrivateKeyRec miOverlayWindowKeyRec;
-#define miOverlayWindowKey (&miOverlayWindowKeyRec)
-static DevPrivateKeyRec miOverlayScreenKeyRec;
-#define miOverlayScreenKey (&miOverlayScreenKeyRec)
-
-static void RebuildTree(WindowPtr);
-static Bool HasUnderlayChildren(WindowPtr);
-static void MarkUnderlayWindow(WindowPtr);
-static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr);
-
-static Bool miOverlayCloseScreen(int, ScreenPtr);
-static Bool miOverlayCreateWindow(WindowPtr);
-static Bool miOverlayDestroyWindow(WindowPtr);
-static Bool miOverlayUnrealizeWindow(WindowPtr);
-static Bool miOverlayRealizeWindow(WindowPtr);
-static void miOverlayMarkWindow(WindowPtr);
-static void miOverlayReparentWindow(WindowPtr, WindowPtr);
-static void miOverlayRestackWindow(WindowPtr, WindowPtr);
-static Bool miOverlayMarkOverlappedWindows(WindowPtr, WindowPtr, WindowPtr*);
-static void miOverlayMarkUnrealizedWindow(WindowPtr, WindowPtr, Bool);
-static int miOverlayValidateTree(WindowPtr, WindowPtr, VTKind);
-static void miOverlayHandleExposures(WindowPtr);
-static void miOverlayMoveWindow(WindowPtr, int, int, WindowPtr, VTKind);
-static void miOverlayWindowExposures(WindowPtr, RegionPtr, RegionPtr);
-static void miOverlayResizeWindow(WindowPtr, int, int, unsigned int,
- unsigned int, WindowPtr);
-static void miOverlayClearToBackground(WindowPtr, int, int, int, int, Bool);
-
-static void miOverlaySetShape(WindowPtr, int);
-static void miOverlayChangeBorderWidth(WindowPtr, unsigned int);
-
-#define MIOVERLAY_GET_SCREEN_PRIVATE(pScreen) ((miOverlayScreenPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, miOverlayScreenKey))
-#define MIOVERLAY_GET_WINDOW_PRIVATE(pWin) ((miOverlayWindowPtr) \
- dixLookupPrivate(&(pWin)->devPrivates, miOverlayWindowKey))
-#define MIOVERLAY_GET_WINDOW_TREE(pWin) \
- (MIOVERLAY_GET_WINDOW_PRIVATE(pWin)->tree)
-
-#define IN_UNDERLAY(w) MIOVERLAY_GET_WINDOW_TREE(w)
-#define IN_OVERLAY(w) !MIOVERLAY_GET_WINDOW_TREE(w)
-
-#define MARK_OVERLAY(w) miMarkWindow(w)
-#define MARK_UNDERLAY(w) MarkUnderlayWindow(w)
-
-#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
- HasBorder(w) && \
- (w)->backgroundState == ParentRelative)
-
-Bool
-miInitOverlay(
- ScreenPtr pScreen,
- miOverlayInOverlayFunc inOverlayFunc,
- miOverlayTransFunc transFunc
-){
- miOverlayScreenPtr pScreenPriv;
-
- if(!inOverlayFunc || !transFunc) return FALSE;
-
- if(!dixRegisterPrivateKey(&miOverlayWindowKeyRec, PRIVATE_WINDOW, sizeof(miOverlayWindowRec)))
- return FALSE;
-
- if(!dixRegisterPrivateKey(&miOverlayScreenKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
-
- if(!(pScreenPriv = malloc(sizeof(miOverlayScreenRec))))
- return FALSE;
-
- dixSetPrivate(&pScreen->devPrivates, miOverlayScreenKey, pScreenPriv);
-
- pScreenPriv->InOverlay = inOverlayFunc;
- pScreenPriv->MakeTransparent = transFunc;
- pScreenPriv->underlayMarked = FALSE;
-
-
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreenPriv->CreateWindow = pScreen->CreateWindow;
- pScreenPriv->DestroyWindow = pScreen->DestroyWindow;
- pScreenPriv->UnrealizeWindow = pScreen->UnrealizeWindow;
- pScreenPriv->RealizeWindow = pScreen->RealizeWindow;
-
- pScreen->CloseScreen = miOverlayCloseScreen;
- pScreen->CreateWindow = miOverlayCreateWindow;
- pScreen->DestroyWindow = miOverlayDestroyWindow;
- pScreen->UnrealizeWindow = miOverlayUnrealizeWindow;
- pScreen->RealizeWindow = miOverlayRealizeWindow;
-
- pScreen->ReparentWindow = miOverlayReparentWindow;
- pScreen->RestackWindow = miOverlayRestackWindow;
- pScreen->MarkOverlappedWindows = miOverlayMarkOverlappedWindows;
- pScreen->MarkUnrealizedWindow = miOverlayMarkUnrealizedWindow;
- pScreen->ValidateTree = miOverlayValidateTree;
- pScreen->HandleExposures = miOverlayHandleExposures;
- pScreen->MoveWindow = miOverlayMoveWindow;
- pScreen->WindowExposures = miOverlayWindowExposures;
- pScreen->ResizeWindow = miOverlayResizeWindow;
- pScreen->MarkWindow = miOverlayMarkWindow;
- pScreen->ClearToBackground = miOverlayClearToBackground;
- pScreen->SetShape = miOverlaySetShape;
- pScreen->ChangeBorderWidth = miOverlayChangeBorderWidth;
-
- return TRUE;
-}
-
-
-static Bool
-miOverlayCloseScreen(int i, ScreenPtr pScreen)
-{
- miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
-
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
- pScreen->CreateWindow = pScreenPriv->CreateWindow;
- pScreen->DestroyWindow = pScreenPriv->DestroyWindow;
- pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow;
- pScreen->RealizeWindow = pScreenPriv->RealizeWindow;
-
- free(pScreenPriv);
-
- return (*pScreen->CloseScreen)(i, pScreen);
-}
-
-
-static Bool
-miOverlayCreateWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
- miOverlayWindowPtr pWinPriv = MIOVERLAY_GET_WINDOW_PRIVATE(pWin);
- miOverlayTreePtr pTree = NULL;
- Bool result = TRUE;
-
- pWinPriv->tree = NULL;
-
- if(!pWin->parent || !((*pScreenPriv->InOverlay)(pWin))) {
- if(!(pTree = (miOverlayTreePtr)calloc(1, sizeof(miOverlayTreeRec))))
- return FALSE;
- }
-
- if(pScreenPriv->CreateWindow) {
- pScreen->CreateWindow = pScreenPriv->CreateWindow;
- result = (*pScreen->CreateWindow)(pWin);
- pScreen->CreateWindow = miOverlayCreateWindow;
- }
-
- if (pTree) {
- if(result) {
- pTree->pWin = pWin;
- pTree->visibility = VisibilityNotViewable;
- pWinPriv->tree = pTree;
- if(pWin->parent) {
- RegionNull(&(pTree->borderClip));
- RegionNull(&(pTree->clipList));
- RebuildTree(pWin);
- } else {
- BoxRec fullBox;
- fullBox.x1 = 0;
- fullBox.y1 = 0;
- fullBox.x2 = pScreen->width;
- fullBox.y2 = pScreen->height;
- RegionInit(&(pTree->borderClip), &fullBox, 1);
- RegionInit(&(pTree->clipList), &fullBox, 1);
- }
- } else free(pTree);
- }
-
- return TRUE;
-}
-
-
-static Bool
-miOverlayDestroyWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
- Bool result = TRUE;
-
- if (pTree) {
- if(pTree->prevSib)
- pTree->prevSib->nextSib = pTree->nextSib;
- else if(pTree->parent)
- pTree->parent->firstChild = pTree->nextSib;
-
- if(pTree->nextSib)
- pTree->nextSib->prevSib = pTree->prevSib;
- else if(pTree->parent)
- pTree->parent->lastChild = pTree->prevSib;
-
- RegionUninit(&(pTree->borderClip));
- RegionUninit(&(pTree->clipList));
- free(pTree);
- }
-
- if(pScreenPriv->DestroyWindow) {
- pScreen->DestroyWindow = pScreenPriv->DestroyWindow;
- result = (*pScreen->DestroyWindow)(pWin);
- pScreen->DestroyWindow = miOverlayDestroyWindow;
- }
-
- return result;
-}
-
-static Bool
-miOverlayUnrealizeWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
- Bool result = TRUE;
-
- if(pTree) pTree->visibility = VisibilityNotViewable;
-
- if(pScreenPriv->UnrealizeWindow) {
- pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow;
- result = (*pScreen->UnrealizeWindow)(pWin);
- pScreen->UnrealizeWindow = miOverlayUnrealizeWindow;
- }
-
- return result;
-}
-
-
-static Bool
-miOverlayRealizeWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
- Bool result = TRUE;
-
- if(pScreenPriv->RealizeWindow) {
- pScreen->RealizeWindow = pScreenPriv->RealizeWindow;
- result = (*pScreen->RealizeWindow)(pWin);
- pScreen->RealizeWindow = miOverlayRealizeWindow;
- }
-
- /* we only need to catch the root window realization */
-
- if(result && !pWin->parent && !((*pScreenPriv->InOverlay)(pWin)))
- {
- BoxRec box;
- box.x1 = box.y1 = 0;
- box.x2 = pWin->drawable.width;
- box.y2 = pWin->drawable.height;
- (*pScreenPriv->MakeTransparent)(pScreen, 1, &box);
- }
-
- return result;
-}
-
-
-static void
-miOverlayReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
-{
- if(IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) {
- /* This could probably be more optimal */
- RebuildTree(pWin->drawable.pScreen->root->firstChild);
- }
-}
-
-static void
-miOverlayRestackWindow(WindowPtr pWin, WindowPtr oldNextSib)
-{
- if(IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) {
- /* This could probably be more optimal */
- RebuildTree(pWin);
- }
-}
-
-
-static Bool
-miOverlayMarkOverlappedWindows(
- WindowPtr pWin,
- WindowPtr pFirst,
- WindowPtr *pLayerWin
-){
- WindowPtr pChild, pLast;
- Bool overMarked, underMarked, doUnderlay, markAll;
- miOverlayTreePtr pTree = NULL, tLast, tChild;
- BoxPtr box;
-
- overMarked = underMarked = markAll = FALSE;
-
- if(pLayerWin) *pLayerWin = pWin; /* hah! */
-
- doUnderlay = (IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin));
-
- box = RegionExtents(&pWin->borderSize);
-
- if((pChild = pFirst)) {
- pLast = pChild->parent->lastChild;
- while (1) {
- if (pChild == pWin) markAll = TRUE;
-
- if(doUnderlay && IN_UNDERLAY(pChild))
- pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
-
- if(pChild->viewable) {
- if (RegionBroken(&pChild->winSize))
- SetWinSize (pChild);
- if (RegionBroken(&pChild->borderSize))
- SetBorderSize (pChild);
-
- if (markAll ||
- RegionContainsRect(&pChild->borderSize, box))
- {
- MARK_OVERLAY(pChild);
- overMarked = TRUE;
- if(doUnderlay && IN_UNDERLAY(pChild)) {
- MARK_UNDERLAY(pChild);
- underMarked = TRUE;
- }
- if (pChild->firstChild) {
- pChild = pChild->firstChild;
- continue;
- }
- }
- }
- while (!pChild->nextSib && (pChild != pLast)) {
- pChild = pChild->parent;
- if(doUnderlay && IN_UNDERLAY(pChild))
- pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
- }
-
- if(pChild == pWin) markAll = FALSE;
-
- if (pChild == pLast) break;
-
- pChild = pChild->nextSib;
- }
- if(overMarked)
- MARK_OVERLAY(pWin->parent);
- }
-
- if(doUnderlay && !pTree) {
- if(!(pTree = MIOVERLAY_GET_WINDOW_TREE(pWin))) {
- pChild = pWin->lastChild;
- while(1) {
- if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild)))
- break;
-
- if(pChild->lastChild) {
- pChild = pChild->lastChild;
- continue;
- }
-
- while(!pChild->prevSib) pChild = pChild->parent;
-
- pChild = pChild->prevSib;
- }
- }
- }
-
- if(pTree && pTree->nextSib) {
- tChild = pTree->parent->lastChild;
- tLast = pTree->nextSib;
-
- while(1) {
- if(tChild->pWin->viewable) {
- if (RegionBroken(&tChild->pWin->winSize))
- SetWinSize (tChild->pWin);
- if (RegionBroken(&tChild->pWin->borderSize))
- SetBorderSize (tChild->pWin);
-
- if(RegionContainsRect(&(tChild->pWin->borderSize), box))
- {
- MARK_UNDERLAY(tChild->pWin);
- underMarked = TRUE;
- }
- }
-
- if(tChild->lastChild) {
- tChild = tChild->lastChild;
- continue;
- }
-
- while(!tChild->prevSib && (tChild != tLast))
- tChild = tChild->parent;
-
- if(tChild == tLast) break;
-
- tChild = tChild->prevSib;
- }
- }
-
- if(underMarked) {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- MARK_UNDERLAY(pTree->parent->pWin);
- MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->underlayMarked = TRUE;
- }
-
- return underMarked || overMarked;
-}
-
-
-static void
-miOverlayComputeClips(
- WindowPtr pParent,
- RegionPtr universe,
- VTKind kind,
- RegionPtr exposed
-){
- ScreenPtr pScreen = pParent->drawable.pScreen;
- int oldVis, newVis, dx, dy;
- BoxRec borderSize;
- RegionPtr borderVisible;
- RegionRec childUniverse, childUnion;
- miOverlayTreePtr tParent = MIOVERLAY_GET_WINDOW_TREE(pParent);
- miOverlayTreePtr tChild;
- Bool overlap;
-
- borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
- borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
- dx = (int) pParent->drawable.x + (int) pParent->drawable.width +
- wBorderWidth(pParent);
- if (dx > 32767) dx = 32767;
- borderSize.x2 = dx;
- dy = (int) pParent->drawable.y + (int) pParent->drawable.height +
- wBorderWidth(pParent);
- if (dy > 32767) dy = 32767;
- borderSize.y2 = dy;
-
- oldVis = tParent->visibility;
- switch (RegionContainsRect(universe, &borderSize)) {
- case rgnIN:
- newVis = VisibilityUnobscured;
- break;
- case rgnPART:
- newVis = VisibilityPartiallyObscured;
- {
- RegionPtr pBounding;
-
- if ((pBounding = wBoundingShape (pParent))) {
- switch (miShapedWindowIn (universe, pBounding,
- &borderSize,
- pParent->drawable.x,
- pParent->drawable.y))
- {
- case rgnIN:
- newVis = VisibilityUnobscured;
- break;
- case rgnOUT:
- newVis = VisibilityFullyObscured;
- break;
- }
- }
- }
- break;
- default:
- newVis = VisibilityFullyObscured;
- break;
- }
- tParent->visibility = newVis;
-
- dx = pParent->drawable.x - tParent->valdata->oldAbsCorner.x;
- dy = pParent->drawable.y - tParent->valdata->oldAbsCorner.y;
-
- switch (kind) {
- case VTMap:
- case VTStack:
- case VTUnmap:
- break;
- case VTMove:
- if ((oldVis == newVis) &&
- ((oldVis == VisibilityFullyObscured) ||
- (oldVis == VisibilityUnobscured)))
- {
- tChild = tParent;
- while (1) {
- if (tChild->pWin->viewable) {
- if (tChild->visibility != VisibilityFullyObscured) {
- RegionTranslate(&tChild->borderClip, dx, dy);
- RegionTranslate(&tChild->clipList, dx, dy);
-
- tChild->pWin->drawable.serialNumber =
- NEXT_SERIAL_NUMBER;
- if (pScreen->ClipNotify)
- (* pScreen->ClipNotify) (tChild->pWin, dx, dy);
- }
- if (tChild->valdata) {
- RegionNull(&tChild->valdata->borderExposed);
- if (HasParentRelativeBorder(tChild->pWin)){
- RegionSubtract(&tChild->valdata->borderExposed,
- &tChild->borderClip,
- &tChild->pWin->winSize);
- }
- RegionNull(&tChild->valdata->exposed);
- }
- if (tChild->firstChild) {
- tChild = tChild->firstChild;
- continue;
- }
- }
- while (!tChild->nextSib && (tChild != tParent))
- tChild = tChild->parent;
- if (tChild == tParent)
- break;
- tChild = tChild->nextSib;
- }
- return;
- }
- /* fall through */
- default:
- if (dx || dy) {
- RegionTranslate(&tParent->borderClip, dx, dy);
- RegionTranslate(&tParent->clipList, dx, dy);
- }
- break;
- case VTBroken:
- RegionEmpty(&tParent->borderClip);
- RegionEmpty(&tParent->clipList);
- break;
- }
-
- borderVisible = tParent->valdata->borderVisible;
- RegionNull(&tParent->valdata->borderExposed);
- RegionNull(&tParent->valdata->exposed);
-
- if (HasBorder (pParent)) {
- if (borderVisible) {
- RegionSubtract(exposed, universe, borderVisible);
- RegionDestroy(borderVisible);
- } else
- RegionSubtract(exposed, universe, &tParent->borderClip);
-
- if (HasParentRelativeBorder(pParent) && (dx || dy))
- RegionSubtract(&tParent->valdata->borderExposed,
- universe, &pParent->winSize);
- else
- RegionSubtract(&tParent->valdata->borderExposed,
- exposed, &pParent->winSize);
-
- RegionCopy(&tParent->borderClip, universe);
- RegionIntersect(universe, universe, &pParent->winSize);
- }
- else
- RegionCopy(&tParent->borderClip, universe);
-
- if ((tChild = tParent->firstChild) && pParent->mapped) {
- RegionNull(&childUniverse);
- RegionNull(&childUnion);
-
- for (; tChild; tChild = tChild->nextSib) {
- if (tChild->pWin->viewable)
- RegionAppend(&childUnion, &tChild->pWin->borderSize);
- }
-
- RegionValidate(&childUnion, &overlap);
-
- for (tChild = tParent->firstChild;
- tChild;
- tChild = tChild->nextSib)
- {
- if (tChild->pWin->viewable) {
- if (tChild->valdata) {
- RegionIntersect(&childUniverse, universe,
- &tChild->pWin->borderSize);
- miOverlayComputeClips (tChild->pWin, &childUniverse,
- kind, exposed);
- }
- if (overlap)
- RegionSubtract(universe, universe,
- &tChild->pWin->borderSize);
- }
- }
- if (!overlap)
- RegionSubtract(universe, universe, &childUnion);
- RegionUninit(&childUnion);
- RegionUninit(&childUniverse);
- }
-
- if (oldVis == VisibilityFullyObscured ||
- oldVis == VisibilityNotViewable)
- {
- RegionCopy(&tParent->valdata->exposed, universe);
- }
- else if (newVis != VisibilityFullyObscured &&
- newVis != VisibilityNotViewable)
- {
- RegionSubtract(&tParent->valdata->exposed,
- universe, &tParent->clipList);
- }
-
- /* HACK ALERT - copying contents of regions, instead of regions */
- {
- RegionRec tmp;
-
- tmp = tParent->clipList;
- tParent->clipList = *universe;
- *universe = tmp;
- }
-
- pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
-
- if (pScreen->ClipNotify)
- (* pScreen->ClipNotify) (pParent, dx, dy);
-}
-
-
-static void
-miOverlayMarkWindow(WindowPtr pWin)
-{
- miOverlayTreePtr pTree = NULL;
- WindowPtr pChild, pGrandChild;
-
- miMarkWindow(pWin);
-
- /* look for UnmapValdata among immediate children */
-
- if(!(pChild = pWin->firstChild)) return;
-
- for( ; pChild; pChild = pChild->nextSib) {
- if(pChild->valdata == UnmapValData) {
- if(IN_UNDERLAY(pChild)) {
- pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
- pTree->valdata = (miOverlayValDataPtr)UnmapValData;
- continue;
- } else {
- if(!(pGrandChild = pChild->firstChild))
- continue;
-
- while(1) {
- if(IN_UNDERLAY(pGrandChild)) {
- pTree = MIOVERLAY_GET_WINDOW_TREE(pGrandChild);
- pTree->valdata = (miOverlayValDataPtr)UnmapValData;
- } else if(pGrandChild->firstChild) {
- pGrandChild = pGrandChild->firstChild;
- continue;
- }
-
- while(!pGrandChild->nextSib && (pGrandChild != pChild))
- pGrandChild = pGrandChild->parent;
-
- if(pChild == pGrandChild) break;
-
- pGrandChild = pGrandChild->nextSib;
- }
- }
- }
- }
-
- if(pTree) {
- MARK_UNDERLAY(pTree->parent->pWin);
- MIOVERLAY_GET_SCREEN_PRIVATE(
- pWin->drawable.pScreen)->underlayMarked = TRUE;
- }
-}
-
-static void
-miOverlayMarkUnrealizedWindow(
- WindowPtr pChild,
- WindowPtr pWin,
- Bool fromConfigure
-){
- if ((pChild != pWin) || fromConfigure) {
- miOverlayTreePtr pTree;
-
- RegionEmpty(&pChild->clipList);
- if (pChild->drawable.pScreen->ClipNotify)
- (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
- RegionEmpty(&pChild->borderClip);
- if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
- if(pTree->valdata != (miOverlayValDataPtr)UnmapValData) {
- RegionEmpty(&pTree->clipList);
- RegionEmpty(&pTree->borderClip);
- }
- }
- }
-}
-
-
-static int
-miOverlayValidateTree(
- WindowPtr pParent,
- WindowPtr pChild, /* first child effected */
- VTKind kind
-){
- ScreenPtr pScreen = pParent->drawable.pScreen;
- miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
- RegionRec totalClip, childClip, exposed;
- miOverlayTreePtr tParent, tChild, tWin;
- Bool overlap;
- WindowPtr newParent;
-
- if(!pPriv->underlayMarked)
- goto SKIP_UNDERLAY;
-
- if (!pChild) pChild = pParent->firstChild;
-
- RegionNull(&totalClip);
- RegionNull(&childClip);
- RegionNull(&exposed);
-
- newParent = pParent;
-
- while(IN_OVERLAY(newParent))
- newParent = newParent->parent;
-
- tParent = MIOVERLAY_GET_WINDOW_TREE(newParent);
-
- if(IN_UNDERLAY(pChild))
- tChild = MIOVERLAY_GET_WINDOW_TREE(pChild);
- else
- tChild = tParent->firstChild;
-
- if (RegionBroken(&tParent->clipList) &&
- !RegionBroken(&tParent->borderClip))
- {
- kind = VTBroken;
- RegionCopy(&totalClip, &tParent->borderClip);
- RegionIntersect(&totalClip, &totalClip,
- &tParent->pWin->winSize);
-
- for (tWin = tParent->firstChild; tWin != tChild; tWin = tWin->nextSib) {
- if (tWin->pWin->viewable)
- RegionSubtract(&totalClip, &totalClip,
- &tWin->pWin->borderSize);
- }
- RegionEmpty(&tParent->clipList);
- } else {
- for(tWin = tChild; tWin; tWin = tWin->nextSib) {
- if(tWin->valdata)
- RegionAppend(&totalClip, &tWin->borderClip);
- }
- RegionValidate(&totalClip, &overlap);
- }
-
- if(kind != VTStack)
- RegionUnion(&totalClip, &totalClip, &tParent->clipList);
-
- for(tWin = tChild; tWin; tWin = tWin->nextSib) {
- if(tWin->valdata) {
- if(tWin->pWin->viewable) {
- RegionIntersect(&childClip, &totalClip,
- &tWin->pWin->borderSize);
- miOverlayComputeClips(tWin->pWin, &childClip, kind, &exposed);
- RegionSubtract(&totalClip, &totalClip,
- &tWin->pWin->borderSize);
- } else { /* Means we are unmapping */
- RegionEmpty(&tWin->clipList);
- RegionEmpty(&tWin->borderClip);
- tWin->valdata = NULL;
- }
- }
- }
-
- RegionUninit(&childClip);
-
- if(!((*pPriv->InOverlay)(newParent))) {
- RegionNull(&tParent->valdata->exposed);
- RegionNull(&tParent->valdata->borderExposed);
- }
-
- switch (kind) {
- case VTStack:
- break;
- default:
- if(!((*pPriv->InOverlay)(newParent)))
- RegionSubtract(&tParent->valdata->exposed, &totalClip,
- &tParent->clipList);
- /* fall through */
- case VTMap:
- RegionCopy(&tParent->clipList, &totalClip);
- if(!((*pPriv->InOverlay)(newParent)))
- newParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- break;
- }
-
- RegionUninit(&totalClip);
- RegionUninit(&exposed);
-
-SKIP_UNDERLAY:
-
- miValidateTree(pParent, pChild, kind);
-
- return 1;
-}
-
-
-static void
-miOverlayHandleExposures(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
- WindowPtr pChild;
- ValidatePtr val;
- void (* WindowExposures)(WindowPtr, RegionPtr, RegionPtr);
-
- WindowExposures = pWin->drawable.pScreen->WindowExposures;
- if(pPriv->underlayMarked) {
- miOverlayTreePtr pTree;
- miOverlayValDataPtr mival;
-
- pChild = pWin;
- while(IN_OVERLAY(pChild))
- pChild = pChild->parent;
-
- pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
-
- while (1) {
- if((mival = pTree->valdata)) {
- if(!((*pPriv->InOverlay)(pTree->pWin))) {
- if (RegionNotEmpty(&mival->borderExposed)) {
- miPaintWindow(pTree->pWin, &mival->borderExposed,
- PW_BORDER);
- }
- RegionUninit(&mival->borderExposed);
-
- (*WindowExposures)(pTree->pWin,&mival->exposed,NullRegion);
- RegionUninit(&mival->exposed);
- }
- free(mival);
- pTree->valdata = NULL;
- if (pTree->firstChild) {
- pTree = pTree->firstChild;
- continue;
- }
- }
- while (!pTree->nextSib && (pTree->pWin != pChild))
- pTree = pTree->parent;
- if (pTree->pWin == pChild)
- break;
- pTree = pTree->nextSib;
- }
- pPriv->underlayMarked = FALSE;
- }
-
- pChild = pWin;
- while (1) {
- if ( (val = pChild->valdata) ) {
- if(!((*pPriv->InOverlay)(pChild))) {
- RegionUnion(&val->after.exposed, &val->after.exposed,
- &val->after.borderExposed);
-
- if (RegionNotEmpty(&val->after.exposed)) {
- (*(MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent))(
- pScreen,
- RegionNumRects(&val->after.exposed),
- RegionRects(&val->after.exposed));
- }
- } else {
- if (RegionNotEmpty(&val->after.borderExposed)) {
- miPaintWindow(pChild, &val->after.borderExposed,
- PW_BORDER);
- }
- (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
- }
- RegionUninit(&val->after.borderExposed);
- RegionUninit(&val->after.exposed);
- free(val);
- pChild->valdata = NULL;
- if (pChild->firstChild)
- {
- pChild = pChild->firstChild;
- continue;
- }
- }
- while (!pChild->nextSib && (pChild != pWin))
- pChild = pChild->parent;
- if (pChild == pWin)
- break;
- pChild = pChild->nextSib;
- }
-}
-
-
-static void
-miOverlayMoveWindow(
- WindowPtr pWin,
- int x,
- int y,
- WindowPtr pNextSib,
- VTKind kind
-){
- ScreenPtr pScreen = pWin->drawable.pScreen;
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
- WindowPtr pParent, windowToValidate;
- Bool WasViewable = (Bool)(pWin->viewable);
- short bw;
- RegionRec overReg, underReg;
- DDXPointRec oldpt;
-
- if (!(pParent = pWin->parent))
- return ;
- bw = wBorderWidth (pWin);
-
- oldpt.x = pWin->drawable.x;
- oldpt.y = pWin->drawable.y;
- if (WasViewable) {
- RegionNull(&overReg);
- RegionNull(&underReg);
- if(pTree) {
- RegionCopy(&overReg, &pWin->borderClip);
- RegionCopy(&underReg, &pTree->borderClip);
- } else {
- RegionCopy(&overReg, &pWin->borderClip);
- CollectUnderlayChildrenRegions(pWin, &underReg);
- }
- (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
- }
- pWin->origin.x = x + (int)bw;
- pWin->origin.y = y + (int)bw;
- x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
- y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
-
- SetWinSize (pWin);
- SetBorderSize (pWin);
-
- (*pScreen->PositionWindow)(pWin, x, y);
-
- windowToValidate = MoveWindowInStack(pWin, pNextSib);
-
- ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
-
- if (WasViewable) {
- miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
- (*pScreen->MarkOverlappedWindows) (pWin, windowToValidate, NULL);
-
-
- (*pScreen->ValidateTree)(pWin->parent, NullWindow, kind);
- if(RegionNotEmpty(&underReg)) {
- pPriv->copyUnderlay = TRUE;
- (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, &underReg);
- }
- RegionUninit(&underReg);
- if(RegionNotEmpty(&overReg)) {
- pPriv->copyUnderlay = FALSE;
- (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, &overReg);
- }
- RegionUninit(&overReg);
- (*pScreen->HandleExposures)(pWin->parent);
-
- if (pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pWin->parent, NullWindow, kind);
- }
- if (pWin->realized)
- WindowsRestructured ();
-}
-
-#ifndef RECTLIMIT
-#define RECTLIMIT 25
-#endif
-
-static void
-miOverlayWindowExposures(
- WindowPtr pWin,
- RegionPtr prgn,
- RegionPtr other_exposed
-){
- RegionPtr exposures = prgn;
-
- if ((prgn && !RegionNil(prgn)) ||
- (exposures && !RegionNil(exposures)) || other_exposed)
- {
- RegionRec expRec;
- int clientInterested;
-
- clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) &
- ExposureMask;
- if (other_exposed) {
- if (exposures) {
- RegionUnion(other_exposed, exposures, other_exposed);
- if (exposures != prgn)
- RegionDestroy(exposures);
- }
- exposures = other_exposed;
- }
- if (clientInterested && exposures &&
- (RegionNumRects(exposures) > RECTLIMIT))
- {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
- BoxRec box;
-
- box = *RegionExtents(exposures);
- if (exposures == prgn) {
- exposures = &expRec;
- RegionInit(exposures, &box, 1);
- RegionReset(prgn, &box);
- } else {
- RegionReset(exposures, &box);
- RegionUnion(prgn, prgn, exposures);
- }
- /* This is the only reason why we are replacing mi's version
- of this file */
-
- if(!((*pPriv->InOverlay)(pWin))) {
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
- RegionIntersect(prgn, prgn, &pTree->clipList);
- } else
- RegionIntersect(prgn, prgn, &pWin->clipList);
- }
- if (prgn && !RegionNil(prgn))
- miPaintWindow(pWin, prgn, PW_BACKGROUND);
- if (clientInterested && exposures && !RegionNil(exposures))
- miSendExposures(pWin, exposures,
- pWin->drawable.x, pWin->drawable.y);
- if (exposures == &expRec) {
- RegionUninit(exposures);
- }
- else if (exposures && exposures != prgn && exposures != other_exposed)
- RegionDestroy(exposures);
- if (prgn)
- RegionEmpty(prgn);
- }
- else if (exposures && exposures != prgn)
- RegionDestroy(exposures);
-}
-
-
-typedef struct {
- RegionPtr over;
- RegionPtr under;
-} miOverlayTwoRegions;
-
-static int
-miOverlayRecomputeExposures (
- WindowPtr pWin,
- pointer value
-){
- miOverlayTwoRegions *pValid = (miOverlayTwoRegions*)value;
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
-
- if (pWin->valdata) {
- /*
- * compute exposed regions of this window
- */
- RegionSubtract(&pWin->valdata->after.exposed,
- &pWin->clipList, pValid->over);
- /*
- * compute exposed regions of the border
- */
- RegionSubtract(&pWin->valdata->after.borderExposed,
- &pWin->borderClip, &pWin->winSize);
- RegionSubtract(&pWin->valdata->after.borderExposed,
- &pWin->valdata->after.borderExposed, pValid->over);
- }
-
- if(pTree && pTree->valdata) {
- RegionSubtract(&pTree->valdata->exposed,
- &pTree->clipList, pValid->under);
- RegionSubtract(&pTree->valdata->borderExposed,
- &pTree->borderClip, &pWin->winSize);
- RegionSubtract(&pTree->valdata->borderExposed,
- &pTree->valdata->borderExposed, pValid->under);
- } else if (!pWin->valdata)
- return WT_NOMATCH;
-
- return WT_WALKCHILDREN;
-}
-
-static void
-miOverlayResizeWindow(
- WindowPtr pWin,
- int x, int y,
- unsigned int w, unsigned int h,
- WindowPtr pSib
-){
- ScreenPtr pScreen = pWin->drawable.pScreen;
- WindowPtr pParent;
- miOverlayTreePtr tChild, pTree;
- Bool WasViewable = (Bool)(pWin->viewable);
- unsigned short width = pWin->drawable.width;
- unsigned short height = pWin->drawable.height;
- short oldx = pWin->drawable.x;
- short oldy = pWin->drawable.y;
- int bw = wBorderWidth (pWin);
- short dw, dh;
- DDXPointRec oldpt;
- RegionPtr oldRegion = NULL, oldRegion2 = NULL;
- WindowPtr pFirstChange;
- WindowPtr pChild;
- RegionPtr gravitate[StaticGravity + 1];
- RegionPtr gravitate2[StaticGravity + 1];
- unsigned g;
- int nx, ny; /* destination x,y */
- int newx, newy; /* new inner window position */
- RegionPtr pRegion = NULL;
- RegionPtr destClip, destClip2;
- RegionPtr oldWinClip = NULL, oldWinClip2 = NULL;
- RegionPtr borderVisible = NullRegion;
- RegionPtr borderVisible2 = NullRegion;
- Bool shrunk = FALSE; /* shrunk in an inner dimension */
- Bool moved = FALSE; /* window position changed */
- Bool doUnderlay;
-
- /* if this is a root window, can't be resized */
- if (!(pParent = pWin->parent))
- return ;
-
- pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
- doUnderlay = ((pTree) || HasUnderlayChildren(pWin));
- newx = pParent->drawable.x + x + bw;
- newy = pParent->drawable.y + y + bw;
- if (WasViewable)
- {
- /*
- * save the visible region of the window
- */
- oldRegion = RegionCreate(NullBox, 1);
- RegionCopy(oldRegion, &pWin->winSize);
- if(doUnderlay) {
- oldRegion2 = RegionCreate(NullBox, 1);
- RegionCopy(oldRegion2, &pWin->winSize);
- }
-
- /*
- * categorize child windows into regions to be moved
- */
- for (g = 0; g <= StaticGravity; g++)
- gravitate[g] = gravitate2[g] = NULL;
- for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
- g = pChild->winGravity;
- if (g != UnmapGravity) {
- if (!gravitate[g])
- gravitate[g] = RegionCreate(NullBox, 1);
- RegionUnion(gravitate[g],
- gravitate[g], &pChild->borderClip);
-
- if(doUnderlay) {
- if (!gravitate2[g])
- gravitate2[g] = RegionCreate(NullBox, 0);
-
- if((tChild = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
- RegionUnion(gravitate2[g],
- gravitate2[g], &tChild->borderClip);
- } else
- CollectUnderlayChildrenRegions(pChild, gravitate2[g]);
- }
- } else {
- UnmapWindow(pChild, TRUE);
- }
- }
- (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
-
-
- oldWinClip = oldWinClip2 = NULL;
- if (pWin->bitGravity != ForgetGravity) {
- oldWinClip = RegionCreate(NullBox, 1);
- RegionCopy(oldWinClip, &pWin->clipList);
- if(pTree) {
- oldWinClip2 = RegionCreate(NullBox, 1);
- RegionCopy(oldWinClip2, &pTree->clipList);
- }
- }
- /*
- * if the window is changing size, borderExposed
- * can't be computed correctly without some help.
- */
- if (pWin->drawable.height > h || pWin->drawable.width > w)
- shrunk = TRUE;
-
- if (newx != oldx || newy != oldy)
- moved = TRUE;
-
- if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
- HasBorder (pWin))
- {
- borderVisible = RegionCreate(NullBox, 1);
- if(pTree)
- borderVisible2 = RegionCreate(NullBox, 1);
- /* for tiled borders, we punt and draw the whole thing */
- if (pWin->borderIsPixel || !moved)
- {
- if (shrunk || moved)
- RegionSubtract(borderVisible,
- &pWin->borderClip,
- &pWin->winSize);
- else
- RegionCopy(borderVisible,
- &pWin->borderClip);
- if(pTree) {
- if (shrunk || moved)
- RegionSubtract(borderVisible,
- &pTree->borderClip,
- &pWin->winSize);
- else
- RegionCopy(borderVisible,
- &pTree->borderClip);
- }
- }
- }
- }
- pWin->origin.x = x + bw;
- pWin->origin.y = y + bw;
- pWin->drawable.height = h;
- pWin->drawable.width = w;
-
- x = pWin->drawable.x = newx;
- y = pWin->drawable.y = newy;
-
- SetWinSize (pWin);
- SetBorderSize (pWin);
-
- dw = (int)w - (int)width;
- dh = (int)h - (int)height;
- ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
-
- /* let the hardware adjust background and border pixmaps, if any */
- (*pScreen->PositionWindow)(pWin, x, y);
-
- pFirstChange = MoveWindowInStack(pWin, pSib);
-
- if (WasViewable) {
- pRegion = RegionCreate(NullBox, 1);
-
- (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange, NULL);
-
- pWin->valdata->before.resized = TRUE;
- pWin->valdata->before.borderVisible = borderVisible;
- if(pTree)
- pTree->valdata->borderVisible = borderVisible2;
-
-
- (*pScreen->ValidateTree)(pWin->parent, pFirstChange, VTOther);
- /*
- * the entire window is trashed unless bitGravity
- * recovers portions of it
- */
- RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList);
- if(pTree)
- RegionCopy(&pTree->valdata->exposed, &pTree->clipList);
- }
-
- GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
-
- if (WasViewable) {
- miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
- miOverlayTwoRegions TwoRegions;
-
- /* avoid the border */
- if (HasBorder (pWin)) {
- int offx, offy, dx, dy;
-
- /* kruft to avoid double translates for each gravity */
- offx = 0;
- offy = 0;
- for (g = 0; g <= StaticGravity; g++) {
- if (!gravitate[g] && !gravitate2[g])
- continue;
-
- /* align winSize to gravitate[g].
- * winSize is in new coordinates,
- * gravitate[g] is still in old coordinates */
- GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
-
- dx = (oldx - nx) - offx;
- dy = (oldy - ny) - offy;
- if (dx || dy) {
- RegionTranslate(&pWin->winSize, dx, dy);
- offx += dx;
- offy += dy;
- }
- if(gravitate[g])
- RegionIntersect(gravitate[g], gravitate[g],
- &pWin->winSize);
- if(gravitate2[g])
- RegionIntersect(gravitate2[g], gravitate2[g],
- &pWin->winSize);
- }
- /* get winSize back where it belongs */
- if (offx || offy)
- RegionTranslate(&pWin->winSize, -offx, -offy);
- }
- /*
- * add screen bits to the appropriate bucket
- */
-
- if (oldWinClip2)
- {
- RegionCopy(pRegion, oldWinClip2);
- RegionTranslate(pRegion, nx - oldx, ny - oldy);
- RegionIntersect(oldWinClip2, pRegion, &pTree->clipList);
-
- for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) {
- if (gravitate2[g])
- RegionSubtract(oldWinClip2, oldWinClip2,
- gravitate2[g]);
- }
- RegionTranslate(oldWinClip2, oldx - nx, oldy - ny);
- g = pWin->bitGravity;
- if (!gravitate2[g])
- gravitate2[g] = oldWinClip2;
- else {
- RegionUnion(gravitate2[g],gravitate2[g],oldWinClip2);
- RegionDestroy(oldWinClip2);
- }
- }
-
- if (oldWinClip)
- {
- /*
- * clip to new clipList
- */
- RegionCopy(pRegion, oldWinClip);
- RegionTranslate(pRegion, nx - oldx, ny - oldy);
- RegionIntersect(oldWinClip, pRegion, &pWin->clipList);
- /*
- * don't step on any gravity bits which will be copied after this
- * region. Note -- this assumes that the regions will be copied
- * in gravity order.
- */
- for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) {
- if (gravitate[g])
- RegionSubtract(oldWinClip, oldWinClip,
- gravitate[g]);
- }
- RegionTranslate(oldWinClip, oldx - nx, oldy - ny);
- g = pWin->bitGravity;
- if (!gravitate[g])
- gravitate[g] = oldWinClip;
- else {
- RegionUnion(gravitate[g], gravitate[g], oldWinClip);
- RegionDestroy(oldWinClip);
- }
- }
-
- /*
- * move the bits on the screen
- */
-
- destClip = destClip2 = NULL;
-
- for (g = 0; g <= StaticGravity; g++) {
- if (!gravitate[g] && !gravitate2[g])
- continue;
-
- GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
-
- oldpt.x = oldx + (x - nx);
- oldpt.y = oldy + (y - ny);
-
- /* Note that gravitate[g] is *translated* by CopyWindow */
-
- /* only copy the remaining useful bits */
-
- if(gravitate[g])
- RegionIntersect(gravitate[g],
- gravitate[g], oldRegion);
- if(gravitate2[g])
- RegionIntersect(gravitate2[g],
- gravitate2[g], oldRegion2);
-
- /* clip to not overwrite already copied areas */
-
- if (destClip && gravitate[g]) {
- RegionTranslate(destClip, oldpt.x - x, oldpt.y - y);
- RegionSubtract(gravitate[g], gravitate[g], destClip);
- RegionTranslate(destClip, x - oldpt.x, y - oldpt.y);
- }
- if (destClip2 && gravitate2[g]) {
- RegionTranslate(destClip2, oldpt.x - x, oldpt.y - y);
- RegionSubtract(gravitate2[g],gravitate2[g],destClip2);
- RegionTranslate(destClip2, x - oldpt.x, y - oldpt.y);
- }
-
- /* and move those bits */
-
- if (oldpt.x != x || oldpt.y != y) {
- if(gravitate2[g]) {
- pPriv->copyUnderlay = TRUE;
- (*pScreen->CopyWindow)(pWin, oldpt, gravitate2[g]);
- }
- if(gravitate[g]) {
- pPriv->copyUnderlay = FALSE;
- (*pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
- }
- }
-
- /* remove any overwritten bits from the remaining useful bits */
-
- if(gravitate[g])
- RegionSubtract(oldRegion, oldRegion, gravitate[g]);
- if(gravitate2[g])
- RegionSubtract(oldRegion2, oldRegion2, gravitate2[g]);
-
- /*
- * recompute exposed regions of child windows
- */
-
-
- for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
- if (pChild->winGravity != g)
- continue;
-
- TwoRegions.over = gravitate[g];
- TwoRegions.under = gravitate2[g];
-
- TraverseTree (pChild, miOverlayRecomputeExposures,
- (pointer)(&TwoRegions));
- }
-
- /*
- * remove the successfully copied regions of the
- * window from its exposed region
- */
-
- if (g == pWin->bitGravity) {
- if(gravitate[g])
- RegionSubtract(&pWin->valdata->after.exposed,
- &pWin->valdata->after.exposed, gravitate[g]);
- if(gravitate2[g] && pTree)
- RegionSubtract(&pTree->valdata->exposed,
- &pTree->valdata->exposed, gravitate2[g]);
- }
- if(gravitate[g]) {
- if (!destClip)
- destClip = gravitate[g];
- else {
- RegionUnion(destClip, destClip, gravitate[g]);
- RegionDestroy(gravitate[g]);
- }
- }
- if(gravitate2[g]) {
- if (!destClip2)
- destClip2 = gravitate2[g];
- else {
- RegionUnion(destClip2, destClip2, gravitate2[g]);
- RegionDestroy(gravitate2[g]);
- }
- }
- }
-
- RegionDestroy(pRegion);
- RegionDestroy(oldRegion);
- if(doUnderlay)
- RegionDestroy(oldRegion2);
- if (destClip)
- RegionDestroy(destClip);
- if (destClip2)
- RegionDestroy(destClip2);
- (*pScreen->HandleExposures)(pWin->parent);
- if (pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pWin->parent, pFirstChange, VTOther);
- }
- if (pWin->realized)
- WindowsRestructured ();
-}
-
-
-static void
-miOverlaySetShape(WindowPtr pWin, int kind)
-{
- Bool WasViewable = (Bool)(pWin->viewable);
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- if (kind != ShapeInput) {
- if (WasViewable) {
- (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
-
- if (HasBorder (pWin)) {
- RegionPtr borderVisible;
-
- borderVisible = RegionCreate(NullBox, 1);
- RegionSubtract(borderVisible,
- &pWin->borderClip, &pWin->winSize);
- pWin->valdata->before.borderVisible = borderVisible;
- pWin->valdata->before.resized = TRUE;
- if(IN_UNDERLAY(pWin)) {
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
- RegionPtr borderVisible2;
-
- borderVisible2 = RegionCreate(NULL, 1);
- RegionSubtract(borderVisible2,
- &pTree->borderClip, &pWin->winSize);
- pTree->valdata->borderVisible = borderVisible2;
- }
- }
- }
-
- SetWinSize (pWin);
- SetBorderSize (pWin);
-
- ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
-
- if (WasViewable) {
- (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
-
-
- (*pScreen->ValidateTree)(pWin->parent, NullWindow, VTOther);
- }
-
- if (WasViewable) {
- (*pScreen->HandleExposures)(pWin->parent);
- if (pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pWin->parent, NullWindow, VTOther);
- }
- }
- if (pWin->realized)
- WindowsRestructured ();
- CheckCursorConfinement(pWin);
-}
-
-
-
-static void
-miOverlayChangeBorderWidth(
- WindowPtr pWin,
- unsigned int width
-){
- int oldwidth;
- ScreenPtr pScreen;
- Bool WasViewable = (Bool)(pWin->viewable);
- Bool HadBorder;
-
- oldwidth = wBorderWidth (pWin);
- if (oldwidth == width)
- return;
- HadBorder = HasBorder(pWin);
- pScreen = pWin->drawable.pScreen;
- if (WasViewable && (width < oldwidth))
- (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
-
- pWin->borderWidth = width;
- SetBorderSize (pWin);
-
- if (WasViewable) {
- if (width > oldwidth) {
- (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
-
- if (HadBorder) {
- RegionPtr borderVisible;
- borderVisible = RegionCreate(NULL, 1);
- RegionSubtract(borderVisible,
- &pWin->borderClip, &pWin->winSize);
- pWin->valdata->before.borderVisible = borderVisible;
- if(IN_UNDERLAY(pWin)) {
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
- RegionPtr borderVisible2;
-
- borderVisible2 = RegionCreate(NULL, 1);
- RegionSubtract(borderVisible2,
- &pTree->borderClip, &pWin->winSize);
- pTree->valdata->borderVisible = borderVisible2;
- }
- }
- }
- (*pScreen->ValidateTree)(pWin->parent, pWin, VTOther);
- (*pScreen->HandleExposures)(pWin->parent);
-
- if (pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pWin->parent, pWin, VTOther);
- }
- if (pWin->realized)
- WindowsRestructured ();
-}
-
-/* We need this as an addition since the xf86 common code doesn't
- know about the second tree which is static to this file. */
-
-void
-miOverlaySetRootClip(ScreenPtr pScreen, Bool enable)
-{
- WindowPtr pRoot = pScreen->root;
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pRoot);
-
- MARK_UNDERLAY(pRoot);
-
- if(enable) {
- BoxRec box;
-
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = pScreen->width;
- box.y2 = pScreen->height;
-
- RegionReset(&pTree->borderClip, &box);
- } else
- RegionEmpty(&pTree->borderClip);
-
- RegionBreak(&pTree->clipList);
-}
-
-static void
-miOverlayClearToBackground(
- WindowPtr pWin,
- int x, int y,
- int w, int h,
- Bool generateExposures
-)
-{
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
- BoxRec box;
- RegionRec reg;
- RegionPtr pBSReg = NullRegion;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
- RegionPtr clipList;
- BoxPtr extents;
- int x1, y1, x2, y2;
-
- x1 = pWin->drawable.x + x;
- y1 = pWin->drawable.y + y;
- if (w)
- x2 = x1 + (int) w;
- else
- x2 = x1 + (int) pWin->drawable.width - (int) x;
- if (h)
- y2 = y1 + h;
- else
- y2 = y1 + (int) pWin->drawable.height - (int) y;
-
- clipList = ((*pScreenPriv->InOverlay)(pWin)) ? &pWin->clipList :
- &pTree->clipList;
-
- extents = RegionExtents(clipList);
-
- if (x1 < extents->x1) x1 = extents->x1;
- if (x2 > extents->x2) x2 = extents->x2;
- if (y1 < extents->y1) y1 = extents->y1;
- if (y2 > extents->y2) y2 = extents->y2;
-
- if (x2 <= x1 || y2 <= y1)
- x2 = x1 = y2 = y1 = 0;
-
- box.x1 = x1; box.x2 = x2;
- box.y1 = y1; box.y2 = y2;
-
- RegionInit(®, &box, 1);
-
- RegionIntersect(®, ®, clipList);
- if (generateExposures)
- (*pScreen->WindowExposures)(pWin, ®, pBSReg);
- else if (pWin->backgroundState != None)
- miPaintWindow(pWin, ®, PW_BACKGROUND);
- RegionUninit(®);
- if (pBSReg)
- RegionDestroy(pBSReg);
-}
-
-
-/****************************************************************/
-
-/* not used */
-Bool
-miOverlayGetPrivateClips(
- WindowPtr pWin,
- RegionPtr *borderClip,
- RegionPtr *clipList
-){
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
-
- if(pTree) {
- *borderClip = &(pTree->borderClip);
- *clipList = &(pTree->clipList);
- return TRUE;
- }
-
- *borderClip = *clipList = NULL;
-
- return FALSE;
-}
-
-void
-miOverlaySetTransFunction (
- ScreenPtr pScreen,
- miOverlayTransFunc transFunc
-){
- MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent = transFunc;
-}
-
-Bool
-miOverlayCopyUnderlay(ScreenPtr pScreen)
-{
- return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->copyUnderlay;
-}
-
-void
-miOverlayComputeCompositeClip(GCPtr pGC, WindowPtr pWin)
-{
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
- RegionPtr pregWin;
- Bool freeTmpClip, freeCompClip;
-
- if(!pTree) {
- miComputeCompositeClip(pGC, &pWin->drawable);
- return;
- }
-
- if (pGC->subWindowMode == IncludeInferiors) {
- pregWin = RegionCreate(NullBox, 1);
- freeTmpClip = TRUE;
- if (pWin->parent || (screenIsSaved != SCREEN_SAVER_ON) ||
- !HasSaverWindow (pGC->pScreen))
- {
- RegionIntersect(pregWin,&pTree->borderClip,&pWin->winSize);
- }
- } else {
- pregWin = &pTree->clipList;
- freeTmpClip = FALSE;
- }
- freeCompClip = pGC->freeCompClip;
- if (pGC->clientClipType == CT_NONE) {
- if (freeCompClip)
- RegionDestroy(pGC->pCompositeClip);
- pGC->pCompositeClip = pregWin;
- pGC->freeCompClip = freeTmpClip;
- } else {
- RegionTranslate(pGC->clientClip,
- pWin->drawable.x + pGC->clipOrg.x,
- pWin->drawable.y + pGC->clipOrg.y);
-
- if (freeCompClip) {
- RegionIntersect(pGC->pCompositeClip,
- pregWin, pGC->clientClip);
- if (freeTmpClip)
- RegionDestroy(pregWin);
- } else if (freeTmpClip) {
- RegionIntersect(pregWin, pregWin, pGC->clientClip);
- pGC->pCompositeClip = pregWin;
- } else {
- pGC->pCompositeClip = RegionCreate(NullBox, 0);
- RegionIntersect(pGC->pCompositeClip,
- pregWin, pGC->clientClip);
- }
- pGC->freeCompClip = TRUE;
- RegionTranslate(pGC->clientClip,
- -(pWin->drawable.x + pGC->clipOrg.x),
- -(pWin->drawable.y + pGC->clipOrg.y));
- }
-}
-
-Bool
-miOverlayCollectUnderlayRegions(
- WindowPtr pWin,
- RegionPtr *region
-){
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
-
- if(pTree) {
- *region = &pTree->borderClip;
- return FALSE;
- }
-
- *region = RegionCreate(NullBox, 0);
-
- CollectUnderlayChildrenRegions(pWin, *region);
-
- return TRUE;
-}
-
-
-static miOverlayTreePtr
-DoLeaf(
- WindowPtr pWin,
- miOverlayTreePtr parent,
- miOverlayTreePtr prevSib
-){
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
-
- pTree->parent = parent;
- pTree->firstChild = NULL;
- pTree->lastChild = NULL;
- pTree->prevSib = prevSib;
- pTree->nextSib = NULL;
-
- if(prevSib)
- prevSib->nextSib = pTree;
-
- if(!parent->firstChild)
- parent->firstChild = parent->lastChild = pTree;
- else if(parent->lastChild == prevSib)
- parent->lastChild = pTree;
-
- return pTree;
-}
-
-static void
-RebuildTree(WindowPtr pWin)
-{
- miOverlayTreePtr parent, prevSib, tChild;
- WindowPtr pChild;
-
- prevSib = tChild = NULL;
-
- pWin = pWin->parent;
-
- while(IN_OVERLAY(pWin))
- pWin = pWin->parent;
-
- parent = MIOVERLAY_GET_WINDOW_TREE(pWin);
-
- pChild = pWin->firstChild;
- parent->firstChild = parent->lastChild = NULL;
-
- while(1) {
- if(IN_UNDERLAY(pChild))
- prevSib = tChild = DoLeaf(pChild, parent, prevSib);
-
- if(pChild->firstChild) {
- if(IN_UNDERLAY(pChild)) {
- parent = tChild;
- prevSib = NULL;
- }
- pChild = pChild->firstChild;
- continue;
- }
-
- while(!pChild->nextSib) {
- pChild = pChild->parent;
- if(pChild == pWin) return;
- if(IN_UNDERLAY(pChild)) {
- prevSib = tChild = MIOVERLAY_GET_WINDOW_TREE(pChild);
- parent = tChild->parent;
- }
- }
-
- pChild = pChild->nextSib;
- }
-}
-
-
-static Bool
-HasUnderlayChildren(WindowPtr pWin)
-{
- WindowPtr pChild;
-
- if(!(pChild = pWin->firstChild))
- return FALSE;
-
- while(1) {
- if(IN_UNDERLAY(pChild))
- return TRUE;
-
- if(pChild->firstChild) {
- pChild = pChild->firstChild;
- continue;
- }
-
- while(!pChild->nextSib && (pWin != pChild))
- pChild = pChild->parent;
-
- if(pChild == pWin) break;
-
- pChild = pChild->nextSib;
- }
-
- return FALSE;
-}
-
-
-static Bool
-CollectUnderlayChildrenRegions(WindowPtr pWin, RegionPtr pReg)
-{
- WindowPtr pChild;
- miOverlayTreePtr pTree;
- Bool hasUnderlay;
-
- if(!(pChild = pWin->firstChild))
- return FALSE;
-
- hasUnderlay = FALSE;
-
- while(1) {
- if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
- RegionAppend(pReg, &pTree->borderClip);
- hasUnderlay = TRUE;
- } else
- if(pChild->firstChild) {
- pChild = pChild->firstChild;
- continue;
- }
-
- while(!pChild->nextSib && (pWin != pChild))
- pChild = pChild->parent;
-
- if(pChild == pWin) break;
-
- pChild = pChild->nextSib;
- }
-
- if(hasUnderlay) {
- Bool overlap;
- RegionValidate(pReg, &overlap);
- }
-
- return hasUnderlay;
-}
-
-
-static void
-MarkUnderlayWindow(WindowPtr pWin)
-{
- miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
-
- if(pTree->valdata) return;
- pTree->valdata = (miOverlayValDataPtr)xnfalloc(sizeof(miOverlayValDataRec));
- pTree->valdata->oldAbsCorner.x = pWin->drawable.x;
- pTree->valdata->oldAbsCorner.y = pWin->drawable.y;
- pTree->valdata->borderVisible = NullRegion;
-}
+ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifdef CreateWindow +#undef CreateWindow +#endif + +#include <X11/X.h> +#include "scrnintstr.h" +#include <X11/extensions/shapeproto.h> +#include "validate.h" +#include "windowstr.h" +#include "mi.h" +#include "gcstruct.h" +#include "regionstr.h" +#include "privates.h" +#include "mivalidate.h" +#include "mioverlay.h" +#include "migc.h" + +#include "globals.h" + +typedef struct { + RegionRec exposed; + RegionRec borderExposed; + RegionPtr borderVisible; + DDXPointRec oldAbsCorner; +} miOverlayValDataRec, *miOverlayValDataPtr; + +typedef struct _TreeRec { + WindowPtr pWin; + struct _TreeRec *parent; + struct _TreeRec *firstChild; + struct _TreeRec *lastChild; + struct _TreeRec *prevSib; + struct _TreeRec *nextSib; + RegionRec borderClip; + RegionRec clipList; + unsigned visibility; + miOverlayValDataPtr valdata; +} miOverlayTreeRec, *miOverlayTreePtr; + +typedef struct { + miOverlayTreePtr tree; +} miOverlayWindowRec, *miOverlayWindowPtr; + +typedef struct { + CloseScreenProcPtr CloseScreen; + CreateWindowProcPtr CreateWindow; + DestroyWindowProcPtr DestroyWindow; + UnrealizeWindowProcPtr UnrealizeWindow; + RealizeWindowProcPtr RealizeWindow; + miOverlayTransFunc MakeTransparent; + miOverlayInOverlayFunc InOverlay; + Bool underlayMarked; + Bool copyUnderlay; +} miOverlayScreenRec, *miOverlayScreenPtr; + +static DevPrivateKeyRec miOverlayWindowKeyRec; + +#define miOverlayWindowKey (&miOverlayWindowKeyRec) +static DevPrivateKeyRec miOverlayScreenKeyRec; + +#define miOverlayScreenKey (&miOverlayScreenKeyRec) + +static void RebuildTree(WindowPtr); +static Bool HasUnderlayChildren(WindowPtr); +static void MarkUnderlayWindow(WindowPtr); +static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr); + +static Bool miOverlayCloseScreen(int, ScreenPtr); +static Bool miOverlayCreateWindow(WindowPtr); +static Bool miOverlayDestroyWindow(WindowPtr); +static Bool miOverlayUnrealizeWindow(WindowPtr); +static Bool miOverlayRealizeWindow(WindowPtr); +static void miOverlayMarkWindow(WindowPtr); +static void miOverlayReparentWindow(WindowPtr, WindowPtr); +static void miOverlayRestackWindow(WindowPtr, WindowPtr); +static Bool miOverlayMarkOverlappedWindows(WindowPtr, WindowPtr, WindowPtr *); +static void miOverlayMarkUnrealizedWindow(WindowPtr, WindowPtr, Bool); +static int miOverlayValidateTree(WindowPtr, WindowPtr, VTKind); +static void miOverlayHandleExposures(WindowPtr); +static void miOverlayMoveWindow(WindowPtr, int, int, WindowPtr, VTKind); +static void miOverlayWindowExposures(WindowPtr, RegionPtr, RegionPtr); +static void miOverlayResizeWindow(WindowPtr, int, int, unsigned int, + unsigned int, WindowPtr); +static void miOverlayClearToBackground(WindowPtr, int, int, int, int, Bool); + +static void miOverlaySetShape(WindowPtr, int); +static void miOverlayChangeBorderWidth(WindowPtr, unsigned int); + +#define MIOVERLAY_GET_SCREEN_PRIVATE(pScreen) ((miOverlayScreenPtr) \ + dixLookupPrivate(&(pScreen)->devPrivates, miOverlayScreenKey)) +#define MIOVERLAY_GET_WINDOW_PRIVATE(pWin) ((miOverlayWindowPtr) \ + dixLookupPrivate(&(pWin)->devPrivates, miOverlayWindowKey)) +#define MIOVERLAY_GET_WINDOW_TREE(pWin) \ + (MIOVERLAY_GET_WINDOW_PRIVATE(pWin)->tree) + +#define IN_UNDERLAY(w) MIOVERLAY_GET_WINDOW_TREE(w) +#define IN_OVERLAY(w) !MIOVERLAY_GET_WINDOW_TREE(w) + +#define MARK_OVERLAY(w) miMarkWindow(w) +#define MARK_UNDERLAY(w) MarkUnderlayWindow(w) + +#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \ + HasBorder(w) && \ + (w)->backgroundState == ParentRelative) + +Bool +miInitOverlay(ScreenPtr pScreen, + miOverlayInOverlayFunc inOverlayFunc, + miOverlayTransFunc transFunc) +{ + miOverlayScreenPtr pScreenPriv; + + if (!inOverlayFunc || !transFunc) + return FALSE; + + if (!dixRegisterPrivateKey + (&miOverlayWindowKeyRec, PRIVATE_WINDOW, sizeof(miOverlayWindowRec))) + return FALSE; + + if (!dixRegisterPrivateKey(&miOverlayScreenKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + + if (!(pScreenPriv = malloc(sizeof(miOverlayScreenRec)))) + return FALSE; + + dixSetPrivate(&pScreen->devPrivates, miOverlayScreenKey, pScreenPriv); + + pScreenPriv->InOverlay = inOverlayFunc; + pScreenPriv->MakeTransparent = transFunc; + pScreenPriv->underlayMarked = FALSE; + + pScreenPriv->CloseScreen = pScreen->CloseScreen; + pScreenPriv->CreateWindow = pScreen->CreateWindow; + pScreenPriv->DestroyWindow = pScreen->DestroyWindow; + pScreenPriv->UnrealizeWindow = pScreen->UnrealizeWindow; + pScreenPriv->RealizeWindow = pScreen->RealizeWindow; + + pScreen->CloseScreen = miOverlayCloseScreen; + pScreen->CreateWindow = miOverlayCreateWindow; + pScreen->DestroyWindow = miOverlayDestroyWindow; + pScreen->UnrealizeWindow = miOverlayUnrealizeWindow; + pScreen->RealizeWindow = miOverlayRealizeWindow; + + pScreen->ReparentWindow = miOverlayReparentWindow; + pScreen->RestackWindow = miOverlayRestackWindow; + pScreen->MarkOverlappedWindows = miOverlayMarkOverlappedWindows; + pScreen->MarkUnrealizedWindow = miOverlayMarkUnrealizedWindow; + pScreen->ValidateTree = miOverlayValidateTree; + pScreen->HandleExposures = miOverlayHandleExposures; + pScreen->MoveWindow = miOverlayMoveWindow; + pScreen->WindowExposures = miOverlayWindowExposures; + pScreen->ResizeWindow = miOverlayResizeWindow; + pScreen->MarkWindow = miOverlayMarkWindow; + pScreen->ClearToBackground = miOverlayClearToBackground; + pScreen->SetShape = miOverlaySetShape; + pScreen->ChangeBorderWidth = miOverlayChangeBorderWidth; + + return TRUE; +} + +static Bool +miOverlayCloseScreen(int i, ScreenPtr pScreen) +{ + miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); + + pScreen->CloseScreen = pScreenPriv->CloseScreen; + pScreen->CreateWindow = pScreenPriv->CreateWindow; + pScreen->DestroyWindow = pScreenPriv->DestroyWindow; + pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow; + pScreen->RealizeWindow = pScreenPriv->RealizeWindow; + + free(pScreenPriv); + + return (*pScreen->CloseScreen) (i, pScreen); +} + +static Bool +miOverlayCreateWindow(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); + miOverlayWindowPtr pWinPriv = MIOVERLAY_GET_WINDOW_PRIVATE(pWin); + miOverlayTreePtr pTree = NULL; + Bool result = TRUE; + + pWinPriv->tree = NULL; + + if (!pWin->parent || !((*pScreenPriv->InOverlay) (pWin))) { + if (!(pTree = (miOverlayTreePtr) calloc(1, sizeof(miOverlayTreeRec)))) + return FALSE; + } + + if (pScreenPriv->CreateWindow) { + pScreen->CreateWindow = pScreenPriv->CreateWindow; + result = (*pScreen->CreateWindow) (pWin); + pScreen->CreateWindow = miOverlayCreateWindow; + } + + if (pTree) { + if (result) { + pTree->pWin = pWin; + pTree->visibility = VisibilityNotViewable; + pWinPriv->tree = pTree; + if (pWin->parent) { + RegionNull(&(pTree->borderClip)); + RegionNull(&(pTree->clipList)); + RebuildTree(pWin); + } + else { + BoxRec fullBox; + + fullBox.x1 = 0; + fullBox.y1 = 0; + fullBox.x2 = pScreen->width; + fullBox.y2 = pScreen->height; + RegionInit(&(pTree->borderClip), &fullBox, 1); + RegionInit(&(pTree->clipList), &fullBox, 1); + } + } + else + free(pTree); + } + + return TRUE; +} + +static Bool +miOverlayDestroyWindow(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + Bool result = TRUE; + + if (pTree) { + if (pTree->prevSib) + pTree->prevSib->nextSib = pTree->nextSib; + else if (pTree->parent) + pTree->parent->firstChild = pTree->nextSib; + + if (pTree->nextSib) + pTree->nextSib->prevSib = pTree->prevSib; + else if (pTree->parent) + pTree->parent->lastChild = pTree->prevSib; + + RegionUninit(&(pTree->borderClip)); + RegionUninit(&(pTree->clipList)); + free(pTree); + } + + if (pScreenPriv->DestroyWindow) { + pScreen->DestroyWindow = pScreenPriv->DestroyWindow; + result = (*pScreen->DestroyWindow) (pWin); + pScreen->DestroyWindow = miOverlayDestroyWindow; + } + + return result; +} + +static Bool +miOverlayUnrealizeWindow(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + Bool result = TRUE; + + if (pTree) + pTree->visibility = VisibilityNotViewable; + + if (pScreenPriv->UnrealizeWindow) { + pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow; + result = (*pScreen->UnrealizeWindow) (pWin); + pScreen->UnrealizeWindow = miOverlayUnrealizeWindow; + } + + return result; +} + +static Bool +miOverlayRealizeWindow(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); + Bool result = TRUE; + + if (pScreenPriv->RealizeWindow) { + pScreen->RealizeWindow = pScreenPriv->RealizeWindow; + result = (*pScreen->RealizeWindow) (pWin); + pScreen->RealizeWindow = miOverlayRealizeWindow; + } + + /* we only need to catch the root window realization */ + + if (result && !pWin->parent && !((*pScreenPriv->InOverlay) (pWin))) { + BoxRec box; + + box.x1 = box.y1 = 0; + box.x2 = pWin->drawable.width; + box.y2 = pWin->drawable.height; + (*pScreenPriv->MakeTransparent) (pScreen, 1, &box); + } + + return result; +} + +static void +miOverlayReparentWindow(WindowPtr pWin, WindowPtr pPriorParent) +{ + if (IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) { + /* This could probably be more optimal */ + RebuildTree(pWin->drawable.pScreen->root->firstChild); + } +} + +static void +miOverlayRestackWindow(WindowPtr pWin, WindowPtr oldNextSib) +{ + if (IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) { + /* This could probably be more optimal */ + RebuildTree(pWin); + } +} + +static Bool +miOverlayMarkOverlappedWindows(WindowPtr pWin, + WindowPtr pFirst, WindowPtr *pLayerWin) +{ + WindowPtr pChild, pLast; + Bool overMarked, underMarked, doUnderlay, markAll; + miOverlayTreePtr pTree = NULL, tLast, tChild; + BoxPtr box; + + overMarked = underMarked = markAll = FALSE; + + if (pLayerWin) + *pLayerWin = pWin; /* hah! */ + + doUnderlay = (IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)); + + box = RegionExtents(&pWin->borderSize); + + if ((pChild = pFirst)) { + pLast = pChild->parent->lastChild; + while (1) { + if (pChild == pWin) + markAll = TRUE; + + if (doUnderlay && IN_UNDERLAY(pChild)) + pTree = MIOVERLAY_GET_WINDOW_TREE(pChild); + + if (pChild->viewable) { + if (RegionBroken(&pChild->winSize)) + SetWinSize(pChild); + if (RegionBroken(&pChild->borderSize)) + SetBorderSize(pChild); + + if (markAll || RegionContainsRect(&pChild->borderSize, box)) { + MARK_OVERLAY(pChild); + overMarked = TRUE; + if (doUnderlay && IN_UNDERLAY(pChild)) { + MARK_UNDERLAY(pChild); + underMarked = TRUE; + } + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + } + } + while (!pChild->nextSib && (pChild != pLast)) { + pChild = pChild->parent; + if (doUnderlay && IN_UNDERLAY(pChild)) + pTree = MIOVERLAY_GET_WINDOW_TREE(pChild); + } + + if (pChild == pWin) + markAll = FALSE; + + if (pChild == pLast) + break; + + pChild = pChild->nextSib; + } + if (overMarked) + MARK_OVERLAY(pWin->parent); + } + + if (doUnderlay && !pTree) { + if (!(pTree = MIOVERLAY_GET_WINDOW_TREE(pWin))) { + pChild = pWin->lastChild; + while (1) { + if ((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) + break; + + if (pChild->lastChild) { + pChild = pChild->lastChild; + continue; + } + + while (!pChild->prevSib) + pChild = pChild->parent; + + pChild = pChild->prevSib; + } + } + } + + if (pTree && pTree->nextSib) { + tChild = pTree->parent->lastChild; + tLast = pTree->nextSib; + + while (1) { + if (tChild->pWin->viewable) { + if (RegionBroken(&tChild->pWin->winSize)) + SetWinSize(tChild->pWin); + if (RegionBroken(&tChild->pWin->borderSize)) + SetBorderSize(tChild->pWin); + + if (RegionContainsRect(&(tChild->pWin->borderSize), box)) { + MARK_UNDERLAY(tChild->pWin); + underMarked = TRUE; + } + } + + if (tChild->lastChild) { + tChild = tChild->lastChild; + continue; + } + + while (!tChild->prevSib && (tChild != tLast)) + tChild = tChild->parent; + + if (tChild == tLast) + break; + + tChild = tChild->prevSib; + } + } + + if (underMarked) { + ScreenPtr pScreen = pWin->drawable.pScreen; + + MARK_UNDERLAY(pTree->parent->pWin); + MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->underlayMarked = TRUE; + } + + return underMarked || overMarked; +} + +static void +miOverlayComputeClips(WindowPtr pParent, + RegionPtr universe, VTKind kind, RegionPtr exposed) +{ + ScreenPtr pScreen = pParent->drawable.pScreen; + int oldVis, newVis, dx, dy; + BoxRec borderSize; + RegionPtr borderVisible; + RegionRec childUniverse, childUnion; + miOverlayTreePtr tParent = MIOVERLAY_GET_WINDOW_TREE(pParent); + miOverlayTreePtr tChild; + Bool overlap; + + borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent); + borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent); + dx = (int) pParent->drawable.x + (int) pParent->drawable.width + + wBorderWidth(pParent); + if (dx > 32767) + dx = 32767; + borderSize.x2 = dx; + dy = (int) pParent->drawable.y + (int) pParent->drawable.height + + wBorderWidth(pParent); + if (dy > 32767) + dy = 32767; + borderSize.y2 = dy; + + oldVis = tParent->visibility; + switch (RegionContainsRect(universe, &borderSize)) { + case rgnIN: + newVis = VisibilityUnobscured; + break; + case rgnPART: + newVis = VisibilityPartiallyObscured; + { + RegionPtr pBounding; + + if ((pBounding = wBoundingShape(pParent))) { + switch (miShapedWindowIn(universe, pBounding, + &borderSize, + pParent->drawable.x, + pParent->drawable.y)) { + case rgnIN: + newVis = VisibilityUnobscured; + break; + case rgnOUT: + newVis = VisibilityFullyObscured; + break; + } + } + } + break; + default: + newVis = VisibilityFullyObscured; + break; + } + tParent->visibility = newVis; + + dx = pParent->drawable.x - tParent->valdata->oldAbsCorner.x; + dy = pParent->drawable.y - tParent->valdata->oldAbsCorner.y; + + switch (kind) { + case VTMap: + case VTStack: + case VTUnmap: + break; + case VTMove: + if ((oldVis == newVis) && + ((oldVis == VisibilityFullyObscured) || + (oldVis == VisibilityUnobscured))) { + tChild = tParent; + while (1) { + if (tChild->pWin->viewable) { + if (tChild->visibility != VisibilityFullyObscured) { + RegionTranslate(&tChild->borderClip, dx, dy); + RegionTranslate(&tChild->clipList, dx, dy); + + tChild->pWin->drawable.serialNumber = + NEXT_SERIAL_NUMBER; + if (pScreen->ClipNotify) + (*pScreen->ClipNotify) (tChild->pWin, dx, dy); + } + if (tChild->valdata) { + RegionNull(&tChild->valdata->borderExposed); + if (HasParentRelativeBorder(tChild->pWin)) { + RegionSubtract(&tChild->valdata->borderExposed, + &tChild->borderClip, + &tChild->pWin->winSize); + } + RegionNull(&tChild->valdata->exposed); + } + if (tChild->firstChild) { + tChild = tChild->firstChild; + continue; + } + } + while (!tChild->nextSib && (tChild != tParent)) + tChild = tChild->parent; + if (tChild == tParent) + break; + tChild = tChild->nextSib; + } + return; + } + /* fall through */ + default: + if (dx || dy) { + RegionTranslate(&tParent->borderClip, dx, dy); + RegionTranslate(&tParent->clipList, dx, dy); + } + break; + case VTBroken: + RegionEmpty(&tParent->borderClip); + RegionEmpty(&tParent->clipList); + break; + } + + borderVisible = tParent->valdata->borderVisible; + RegionNull(&tParent->valdata->borderExposed); + RegionNull(&tParent->valdata->exposed); + + if (HasBorder(pParent)) { + if (borderVisible) { + RegionSubtract(exposed, universe, borderVisible); + RegionDestroy(borderVisible); + } + else + RegionSubtract(exposed, universe, &tParent->borderClip); + + if (HasParentRelativeBorder(pParent) && (dx || dy)) + RegionSubtract(&tParent->valdata->borderExposed, + universe, &pParent->winSize); + else + RegionSubtract(&tParent->valdata->borderExposed, + exposed, &pParent->winSize); + + RegionCopy(&tParent->borderClip, universe); + RegionIntersect(universe, universe, &pParent->winSize); + } + else + RegionCopy(&tParent->borderClip, universe); + + if ((tChild = tParent->firstChild) && pParent->mapped) { + RegionNull(&childUniverse); + RegionNull(&childUnion); + + for (; tChild; tChild = tChild->nextSib) { + if (tChild->pWin->viewable) + RegionAppend(&childUnion, &tChild->pWin->borderSize); + } + + RegionValidate(&childUnion, &overlap); + + for (tChild = tParent->firstChild; tChild; tChild = tChild->nextSib) { + if (tChild->pWin->viewable) { + if (tChild->valdata) { + RegionIntersect(&childUniverse, universe, + &tChild->pWin->borderSize); + miOverlayComputeClips(tChild->pWin, &childUniverse, + kind, exposed); + } + if (overlap) + RegionSubtract(universe, universe, + &tChild->pWin->borderSize); + } + } + if (!overlap) + RegionSubtract(universe, universe, &childUnion); + RegionUninit(&childUnion); + RegionUninit(&childUniverse); + } + + if (oldVis == VisibilityFullyObscured || oldVis == VisibilityNotViewable) { + RegionCopy(&tParent->valdata->exposed, universe); + } + else if (newVis != VisibilityFullyObscured && + newVis != VisibilityNotViewable) { + RegionSubtract(&tParent->valdata->exposed, + universe, &tParent->clipList); + } + + /* HACK ALERT - copying contents of regions, instead of regions */ + { + RegionRec tmp; + + tmp = tParent->clipList; + tParent->clipList = *universe; + *universe = tmp; + } + + pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; + + if (pScreen->ClipNotify) + (*pScreen->ClipNotify) (pParent, dx, dy); +} + +static void +miOverlayMarkWindow(WindowPtr pWin) +{ + miOverlayTreePtr pTree = NULL; + WindowPtr pChild, pGrandChild; + + miMarkWindow(pWin); + + /* look for UnmapValdata among immediate children */ + + if (!(pChild = pWin->firstChild)) + return; + + for (; pChild; pChild = pChild->nextSib) { + if (pChild->valdata == UnmapValData) { + if (IN_UNDERLAY(pChild)) { + pTree = MIOVERLAY_GET_WINDOW_TREE(pChild); + pTree->valdata = (miOverlayValDataPtr) UnmapValData; + continue; + } + else { + if (!(pGrandChild = pChild->firstChild)) + continue; + + while (1) { + if (IN_UNDERLAY(pGrandChild)) { + pTree = MIOVERLAY_GET_WINDOW_TREE(pGrandChild); + pTree->valdata = (miOverlayValDataPtr) UnmapValData; + } + else if (pGrandChild->firstChild) { + pGrandChild = pGrandChild->firstChild; + continue; + } + + while (!pGrandChild->nextSib && (pGrandChild != pChild)) + pGrandChild = pGrandChild->parent; + + if (pChild == pGrandChild) + break; + + pGrandChild = pGrandChild->nextSib; + } + } + } + } + + if (pTree) { + MARK_UNDERLAY(pTree->parent->pWin); + MIOVERLAY_GET_SCREEN_PRIVATE(pWin->drawable.pScreen)->underlayMarked = + TRUE; + } +} + +static void +miOverlayMarkUnrealizedWindow(WindowPtr pChild, + WindowPtr pWin, Bool fromConfigure) +{ + if ((pChild != pWin) || fromConfigure) { + miOverlayTreePtr pTree; + + RegionEmpty(&pChild->clipList); + if (pChild->drawable.pScreen->ClipNotify) + (*pChild->drawable.pScreen->ClipNotify) (pChild, 0, 0); + RegionEmpty(&pChild->borderClip); + if ((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) { + if (pTree->valdata != (miOverlayValDataPtr) UnmapValData) { + RegionEmpty(&pTree->clipList); + RegionEmpty(&pTree->borderClip); + } + } + } +} + +static int +miOverlayValidateTree(WindowPtr pParent, WindowPtr pChild, /* first child effected */ + VTKind kind) +{ + ScreenPtr pScreen = pParent->drawable.pScreen; + miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); + RegionRec totalClip, childClip, exposed; + miOverlayTreePtr tParent, tChild, tWin; + Bool overlap; + WindowPtr newParent; + + if (!pPriv->underlayMarked) + goto SKIP_UNDERLAY; + + if (!pChild) + pChild = pParent->firstChild; + + RegionNull(&totalClip); + RegionNull(&childClip); + RegionNull(&exposed); + + newParent = pParent; + + while (IN_OVERLAY(newParent)) + newParent = newParent->parent; + + tParent = MIOVERLAY_GET_WINDOW_TREE(newParent); + + if (IN_UNDERLAY(pChild)) + tChild = MIOVERLAY_GET_WINDOW_TREE(pChild); + else + tChild = tParent->firstChild; + + if (RegionBroken(&tParent->clipList) && !RegionBroken(&tParent->borderClip)) { + kind = VTBroken; + RegionCopy(&totalClip, &tParent->borderClip); + RegionIntersect(&totalClip, &totalClip, &tParent->pWin->winSize); + + for (tWin = tParent->firstChild; tWin != tChild; tWin = tWin->nextSib) { + if (tWin->pWin->viewable) + RegionSubtract(&totalClip, &totalClip, &tWin->pWin->borderSize); + } + RegionEmpty(&tParent->clipList); + } + else { + for (tWin = tChild; tWin; tWin = tWin->nextSib) { + if (tWin->valdata) + RegionAppend(&totalClip, &tWin->borderClip); + } + RegionValidate(&totalClip, &overlap); + } + + if (kind != VTStack) + RegionUnion(&totalClip, &totalClip, &tParent->clipList); + + for (tWin = tChild; tWin; tWin = tWin->nextSib) { + if (tWin->valdata) { + if (tWin->pWin->viewable) { + RegionIntersect(&childClip, &totalClip, + &tWin->pWin->borderSize); + miOverlayComputeClips(tWin->pWin, &childClip, kind, &exposed); + RegionSubtract(&totalClip, &totalClip, &tWin->pWin->borderSize); + } + else { /* Means we are unmapping */ + RegionEmpty(&tWin->clipList); + RegionEmpty(&tWin->borderClip); + tWin->valdata = NULL; + } + } + } + + RegionUninit(&childClip); + + if (!((*pPriv->InOverlay) (newParent))) { + RegionNull(&tParent->valdata->exposed); + RegionNull(&tParent->valdata->borderExposed); + } + + switch (kind) { + case VTStack: + break; + default: + if (!((*pPriv->InOverlay) (newParent))) + RegionSubtract(&tParent->valdata->exposed, &totalClip, + &tParent->clipList); + /* fall through */ + case VTMap: + RegionCopy(&tParent->clipList, &totalClip); + if (!((*pPriv->InOverlay) (newParent))) + newParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; + break; + } + + RegionUninit(&totalClip); + RegionUninit(&exposed); + + SKIP_UNDERLAY: + + miValidateTree(pParent, pChild, kind); + + return 1; +} + +static void +miOverlayHandleExposures(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); + WindowPtr pChild; + ValidatePtr val; + void (*WindowExposures) (WindowPtr, RegionPtr, RegionPtr); + + WindowExposures = pWin->drawable.pScreen->WindowExposures; + if (pPriv->underlayMarked) { + miOverlayTreePtr pTree; + miOverlayValDataPtr mival; + + pChild = pWin; + while (IN_OVERLAY(pChild)) + pChild = pChild->parent; + + pTree = MIOVERLAY_GET_WINDOW_TREE(pChild); + + while (1) { + if ((mival = pTree->valdata)) { + if (!((*pPriv->InOverlay) (pTree->pWin))) { + if (RegionNotEmpty(&mival->borderExposed)) { + miPaintWindow(pTree->pWin, &mival->borderExposed, + PW_BORDER); + } + RegionUninit(&mival->borderExposed); + + (*WindowExposures) (pTree->pWin, &mival->exposed, + NullRegion); + RegionUninit(&mival->exposed); + } + free(mival); + pTree->valdata = NULL; + if (pTree->firstChild) { + pTree = pTree->firstChild; + continue; + } + } + while (!pTree->nextSib && (pTree->pWin != pChild)) + pTree = pTree->parent; + if (pTree->pWin == pChild) + break; + pTree = pTree->nextSib; + } + pPriv->underlayMarked = FALSE; + } + + pChild = pWin; + while (1) { + if ((val = pChild->valdata)) { + if (!((*pPriv->InOverlay) (pChild))) { + RegionUnion(&val->after.exposed, &val->after.exposed, + &val->after.borderExposed); + + if (RegionNotEmpty(&val->after.exposed)) { + (*(MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent)) + (pScreen, RegionNumRects(&val->after.exposed), + RegionRects(&val->after.exposed)); + } + } + else { + if (RegionNotEmpty(&val->after.borderExposed)) { + miPaintWindow(pChild, &val->after.borderExposed, PW_BORDER); + } + (*WindowExposures) (pChild, &val->after.exposed, NullRegion); + } + RegionUninit(&val->after.borderExposed); + RegionUninit(&val->after.exposed); + free(val); + pChild->valdata = NULL; + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + } + while (!pChild->nextSib && (pChild != pWin)) + pChild = pChild->parent; + if (pChild == pWin) + break; + pChild = pChild->nextSib; + } +} + +static void +miOverlayMoveWindow(WindowPtr pWin, + int x, int y, WindowPtr pNextSib, VTKind kind) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + WindowPtr pParent, windowToValidate; + Bool WasViewable = (Bool) (pWin->viewable); + short bw; + RegionRec overReg, underReg; + DDXPointRec oldpt; + + if (!(pParent = pWin->parent)) + return; + bw = wBorderWidth(pWin); + + oldpt.x = pWin->drawable.x; + oldpt.y = pWin->drawable.y; + if (WasViewable) { + RegionNull(&overReg); + RegionNull(&underReg); + if (pTree) { + RegionCopy(&overReg, &pWin->borderClip); + RegionCopy(&underReg, &pTree->borderClip); + } + else { + RegionCopy(&overReg, &pWin->borderClip); + CollectUnderlayChildrenRegions(pWin, &underReg); + } + (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL); + } + pWin->origin.x = x + (int) bw; + pWin->origin.y = y + (int) bw; + x = pWin->drawable.x = pParent->drawable.x + x + (int) bw; + y = pWin->drawable.y = pParent->drawable.y + y + (int) bw; + + SetWinSize(pWin); + SetBorderSize(pWin); + + (*pScreen->PositionWindow) (pWin, x, y); + + windowToValidate = MoveWindowInStack(pWin, pNextSib); + + ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0); + + if (WasViewable) { + miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); + + (*pScreen->MarkOverlappedWindows) (pWin, windowToValidate, NULL); + + (*pScreen->ValidateTree) (pWin->parent, NullWindow, kind); + if (RegionNotEmpty(&underReg)) { + pPriv->copyUnderlay = TRUE; + (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, &underReg); + } + RegionUninit(&underReg); + if (RegionNotEmpty(&overReg)) { + pPriv->copyUnderlay = FALSE; + (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, &overReg); + } + RegionUninit(&overReg); + (*pScreen->HandleExposures) (pWin->parent); + + if (pScreen->PostValidateTree) + (*pScreen->PostValidateTree) (pWin->parent, NullWindow, kind); + } + if (pWin->realized) + WindowsRestructured(); +} + +#ifndef RECTLIMIT +#define RECTLIMIT 25 +#endif + +static void +miOverlayWindowExposures(WindowPtr pWin, + RegionPtr prgn, RegionPtr other_exposed) +{ + RegionPtr exposures = prgn; + + if ((prgn && !RegionNil(prgn)) || + (exposures && !RegionNil(exposures)) || other_exposed) { + RegionRec expRec; + int clientInterested; + + clientInterested = (pWin->eventMask | wOtherEventMasks(pWin)) & + ExposureMask; + if (other_exposed) { + if (exposures) { + RegionUnion(other_exposed, exposures, other_exposed); + if (exposures != prgn) + RegionDestroy(exposures); + } + exposures = other_exposed; + } + if (clientInterested && exposures && + (RegionNumRects(exposures) > RECTLIMIT)) { + ScreenPtr pScreen = pWin->drawable.pScreen; + miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); + BoxRec box; + + box = *RegionExtents(exposures); + if (exposures == prgn) { + exposures = &expRec; + RegionInit(exposures, &box, 1); + RegionReset(prgn, &box); + } + else { + RegionReset(exposures, &box); + RegionUnion(prgn, prgn, exposures); + } + /* This is the only reason why we are replacing mi's version + of this file */ + + if (!((*pPriv->InOverlay) (pWin))) { + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + + RegionIntersect(prgn, prgn, &pTree->clipList); + } + else + RegionIntersect(prgn, prgn, &pWin->clipList); + } + if (prgn && !RegionNil(prgn)) + miPaintWindow(pWin, prgn, PW_BACKGROUND); + if (clientInterested && exposures && !RegionNil(exposures)) + miSendExposures(pWin, exposures, + pWin->drawable.x, pWin->drawable.y); + if (exposures == &expRec) { + RegionUninit(exposures); + } + else if (exposures && exposures != prgn && exposures != other_exposed) + RegionDestroy(exposures); + if (prgn) + RegionEmpty(prgn); + } + else if (exposures && exposures != prgn) + RegionDestroy(exposures); +} + +typedef struct { + RegionPtr over; + RegionPtr under; +} miOverlayTwoRegions; + +static int +miOverlayRecomputeExposures(WindowPtr pWin, pointer value) +{ + miOverlayTwoRegions *pValid = (miOverlayTwoRegions *) value; + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + + if (pWin->valdata) { + /* + * compute exposed regions of this window + */ + RegionSubtract(&pWin->valdata->after.exposed, + &pWin->clipList, pValid->over); + /* + * compute exposed regions of the border + */ + RegionSubtract(&pWin->valdata->after.borderExposed, + &pWin->borderClip, &pWin->winSize); + RegionSubtract(&pWin->valdata->after.borderExposed, + &pWin->valdata->after.borderExposed, pValid->over); + } + + if (pTree && pTree->valdata) { + RegionSubtract(&pTree->valdata->exposed, + &pTree->clipList, pValid->under); + RegionSubtract(&pTree->valdata->borderExposed, + &pTree->borderClip, &pWin->winSize); + RegionSubtract(&pTree->valdata->borderExposed, + &pTree->valdata->borderExposed, pValid->under); + } + else if (!pWin->valdata) + return WT_NOMATCH; + + return WT_WALKCHILDREN; +} + +static void +miOverlayResizeWindow(WindowPtr pWin, + int x, int y, + unsigned int w, unsigned int h, WindowPtr pSib) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + WindowPtr pParent; + miOverlayTreePtr tChild, pTree; + Bool WasViewable = (Bool) (pWin->viewable); + unsigned short width = pWin->drawable.width; + unsigned short height = pWin->drawable.height; + short oldx = pWin->drawable.x; + short oldy = pWin->drawable.y; + int bw = wBorderWidth(pWin); + short dw, dh; + DDXPointRec oldpt; + RegionPtr oldRegion = NULL, oldRegion2 = NULL; + WindowPtr pFirstChange; + WindowPtr pChild; + RegionPtr gravitate[StaticGravity + 1]; + RegionPtr gravitate2[StaticGravity + 1]; + unsigned g; + int nx, ny; /* destination x,y */ + int newx, newy; /* new inner window position */ + RegionPtr pRegion = NULL; + RegionPtr destClip, destClip2; + RegionPtr oldWinClip = NULL, oldWinClip2 = NULL; + RegionPtr borderVisible = NullRegion; + RegionPtr borderVisible2 = NullRegion; + Bool shrunk = FALSE; /* shrunk in an inner dimension */ + Bool moved = FALSE; /* window position changed */ + Bool doUnderlay; + + /* if this is a root window, can't be resized */ + if (!(pParent = pWin->parent)) + return; + + pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + doUnderlay = ((pTree) || HasUnderlayChildren(pWin)); + newx = pParent->drawable.x + x + bw; + newy = pParent->drawable.y + y + bw; + if (WasViewable) { + /* + * save the visible region of the window + */ + oldRegion = RegionCreate(NullBox, 1); + RegionCopy(oldRegion, &pWin->winSize); + if (doUnderlay) { + oldRegion2 = RegionCreate(NullBox, 1); + RegionCopy(oldRegion2, &pWin->winSize); + } + + /* + * categorize child windows into regions to be moved + */ + for (g = 0; g <= StaticGravity; g++) + gravitate[g] = gravitate2[g] = NULL; + for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { + g = pChild->winGravity; + if (g != UnmapGravity) { + if (!gravitate[g]) + gravitate[g] = RegionCreate(NullBox, 1); + RegionUnion(gravitate[g], gravitate[g], &pChild->borderClip); + + if (doUnderlay) { + if (!gravitate2[g]) + gravitate2[g] = RegionCreate(NullBox, 0); + + if ((tChild = MIOVERLAY_GET_WINDOW_TREE(pChild))) { + RegionUnion(gravitate2[g], + gravitate2[g], &tChild->borderClip); + } + else + CollectUnderlayChildrenRegions(pChild, gravitate2[g]); + } + } + else { + UnmapWindow(pChild, TRUE); + } + } + (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL); + + oldWinClip = oldWinClip2 = NULL; + if (pWin->bitGravity != ForgetGravity) { + oldWinClip = RegionCreate(NullBox, 1); + RegionCopy(oldWinClip, &pWin->clipList); + if (pTree) { + oldWinClip2 = RegionCreate(NullBox, 1); + RegionCopy(oldWinClip2, &pTree->clipList); + } + } + /* + * if the window is changing size, borderExposed + * can't be computed correctly without some help. + */ + if (pWin->drawable.height > h || pWin->drawable.width > w) + shrunk = TRUE; + + if (newx != oldx || newy != oldy) + moved = TRUE; + + if ((pWin->drawable.height != h || pWin->drawable.width != w) && + HasBorder(pWin)) { + borderVisible = RegionCreate(NullBox, 1); + if (pTree) + borderVisible2 = RegionCreate(NullBox, 1); + /* for tiled borders, we punt and draw the whole thing */ + if (pWin->borderIsPixel || !moved) { + if (shrunk || moved) + RegionSubtract(borderVisible, + &pWin->borderClip, &pWin->winSize); + else + RegionCopy(borderVisible, &pWin->borderClip); + if (pTree) { + if (shrunk || moved) + RegionSubtract(borderVisible, + &pTree->borderClip, &pWin->winSize); + else + RegionCopy(borderVisible, &pTree->borderClip); + } + } + } + } + pWin->origin.x = x + bw; + pWin->origin.y = y + bw; + pWin->drawable.height = h; + pWin->drawable.width = w; + + x = pWin->drawable.x = newx; + y = pWin->drawable.y = newy; + + SetWinSize(pWin); + SetBorderSize(pWin); + + dw = (int) w - (int) width; + dh = (int) h - (int) height; + ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh); + + /* let the hardware adjust background and border pixmaps, if any */ + (*pScreen->PositionWindow) (pWin, x, y); + + pFirstChange = MoveWindowInStack(pWin, pSib); + + if (WasViewable) { + pRegion = RegionCreate(NullBox, 1); + + (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange, NULL); + + pWin->valdata->before.resized = TRUE; + pWin->valdata->before.borderVisible = borderVisible; + if (pTree) + pTree->valdata->borderVisible = borderVisible2; + + (*pScreen->ValidateTree) (pWin->parent, pFirstChange, VTOther); + /* + * the entire window is trashed unless bitGravity + * recovers portions of it + */ + RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList); + if (pTree) + RegionCopy(&pTree->valdata->exposed, &pTree->clipList); + } + + GravityTranslate(x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny); + + if (WasViewable) { + miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); + miOverlayTwoRegions TwoRegions; + + /* avoid the border */ + if (HasBorder(pWin)) { + int offx, offy, dx, dy; + + /* kruft to avoid double translates for each gravity */ + offx = 0; + offy = 0; + for (g = 0; g <= StaticGravity; g++) { + if (!gravitate[g] && !gravitate2[g]) + continue; + + /* align winSize to gravitate[g]. + * winSize is in new coordinates, + * gravitate[g] is still in old coordinates */ + GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny); + + dx = (oldx - nx) - offx; + dy = (oldy - ny) - offy; + if (dx || dy) { + RegionTranslate(&pWin->winSize, dx, dy); + offx += dx; + offy += dy; + } + if (gravitate[g]) + RegionIntersect(gravitate[g], gravitate[g], &pWin->winSize); + if (gravitate2[g]) + RegionIntersect(gravitate2[g], gravitate2[g], + &pWin->winSize); + } + /* get winSize back where it belongs */ + if (offx || offy) + RegionTranslate(&pWin->winSize, -offx, -offy); + } + /* + * add screen bits to the appropriate bucket + */ + + if (oldWinClip2) { + RegionCopy(pRegion, oldWinClip2); + RegionTranslate(pRegion, nx - oldx, ny - oldy); + RegionIntersect(oldWinClip2, pRegion, &pTree->clipList); + + for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) { + if (gravitate2[g]) + RegionSubtract(oldWinClip2, oldWinClip2, gravitate2[g]); + } + RegionTranslate(oldWinClip2, oldx - nx, oldy - ny); + g = pWin->bitGravity; + if (!gravitate2[g]) + gravitate2[g] = oldWinClip2; + else { + RegionUnion(gravitate2[g], gravitate2[g], oldWinClip2); + RegionDestroy(oldWinClip2); + } + } + + if (oldWinClip) { + /* + * clip to new clipList + */ + RegionCopy(pRegion, oldWinClip); + RegionTranslate(pRegion, nx - oldx, ny - oldy); + RegionIntersect(oldWinClip, pRegion, &pWin->clipList); + /* + * don't step on any gravity bits which will be copied after this + * region. Note -- this assumes that the regions will be copied + * in gravity order. + */ + for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) { + if (gravitate[g]) + RegionSubtract(oldWinClip, oldWinClip, gravitate[g]); + } + RegionTranslate(oldWinClip, oldx - nx, oldy - ny); + g = pWin->bitGravity; + if (!gravitate[g]) + gravitate[g] = oldWinClip; + else { + RegionUnion(gravitate[g], gravitate[g], oldWinClip); + RegionDestroy(oldWinClip); + } + } + + /* + * move the bits on the screen + */ + + destClip = destClip2 = NULL; + + for (g = 0; g <= StaticGravity; g++) { + if (!gravitate[g] && !gravitate2[g]) + continue; + + GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny); + + oldpt.x = oldx + (x - nx); + oldpt.y = oldy + (y - ny); + + /* Note that gravitate[g] is *translated* by CopyWindow */ + + /* only copy the remaining useful bits */ + + if (gravitate[g]) + RegionIntersect(gravitate[g], gravitate[g], oldRegion); + if (gravitate2[g]) + RegionIntersect(gravitate2[g], gravitate2[g], oldRegion2); + + /* clip to not overwrite already copied areas */ + + if (destClip && gravitate[g]) { + RegionTranslate(destClip, oldpt.x - x, oldpt.y - y); + RegionSubtract(gravitate[g], gravitate[g], destClip); + RegionTranslate(destClip, x - oldpt.x, y - oldpt.y); + } + if (destClip2 && gravitate2[g]) { + RegionTranslate(destClip2, oldpt.x - x, oldpt.y - y); + RegionSubtract(gravitate2[g], gravitate2[g], destClip2); + RegionTranslate(destClip2, x - oldpt.x, y - oldpt.y); + } + + /* and move those bits */ + + if (oldpt.x != x || oldpt.y != y) { + if (gravitate2[g]) { + pPriv->copyUnderlay = TRUE; + (*pScreen->CopyWindow) (pWin, oldpt, gravitate2[g]); + } + if (gravitate[g]) { + pPriv->copyUnderlay = FALSE; + (*pScreen->CopyWindow) (pWin, oldpt, gravitate[g]); + } + } + + /* remove any overwritten bits from the remaining useful bits */ + + if (gravitate[g]) + RegionSubtract(oldRegion, oldRegion, gravitate[g]); + if (gravitate2[g]) + RegionSubtract(oldRegion2, oldRegion2, gravitate2[g]); + + /* + * recompute exposed regions of child windows + */ + + for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { + if (pChild->winGravity != g) + continue; + + TwoRegions.over = gravitate[g]; + TwoRegions.under = gravitate2[g]; + + TraverseTree(pChild, miOverlayRecomputeExposures, + (pointer) (&TwoRegions)); + } + + /* + * remove the successfully copied regions of the + * window from its exposed region + */ + + if (g == pWin->bitGravity) { + if (gravitate[g]) + RegionSubtract(&pWin->valdata->after.exposed, + &pWin->valdata->after.exposed, gravitate[g]); + if (gravitate2[g] && pTree) + RegionSubtract(&pTree->valdata->exposed, + &pTree->valdata->exposed, gravitate2[g]); + } + if (gravitate[g]) { + if (!destClip) + destClip = gravitate[g]; + else { + RegionUnion(destClip, destClip, gravitate[g]); + RegionDestroy(gravitate[g]); + } + } + if (gravitate2[g]) { + if (!destClip2) + destClip2 = gravitate2[g]; + else { + RegionUnion(destClip2, destClip2, gravitate2[g]); + RegionDestroy(gravitate2[g]); + } + } + } + + RegionDestroy(pRegion); + RegionDestroy(oldRegion); + if (doUnderlay) + RegionDestroy(oldRegion2); + if (destClip) + RegionDestroy(destClip); + if (destClip2) + RegionDestroy(destClip2); + (*pScreen->HandleExposures) (pWin->parent); + if (pScreen->PostValidateTree) + (*pScreen->PostValidateTree) (pWin->parent, pFirstChange, VTOther); + } + if (pWin->realized) + WindowsRestructured(); +} + +static void +miOverlaySetShape(WindowPtr pWin, int kind) +{ + Bool WasViewable = (Bool) (pWin->viewable); + ScreenPtr pScreen = pWin->drawable.pScreen; + + if (kind != ShapeInput) { + if (WasViewable) { + (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL); + + if (HasBorder(pWin)) { + RegionPtr borderVisible; + + borderVisible = RegionCreate(NullBox, 1); + RegionSubtract(borderVisible, + &pWin->borderClip, &pWin->winSize); + pWin->valdata->before.borderVisible = borderVisible; + pWin->valdata->before.resized = TRUE; + if (IN_UNDERLAY(pWin)) { + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + RegionPtr borderVisible2; + + borderVisible2 = RegionCreate(NULL, 1); + RegionSubtract(borderVisible2, + &pTree->borderClip, &pWin->winSize); + pTree->valdata->borderVisible = borderVisible2; + } + } + } + + SetWinSize(pWin); + SetBorderSize(pWin); + + ResizeChildrenWinSize(pWin, 0, 0, 0, 0); + + if (WasViewable) { + (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL); + + (*pScreen->ValidateTree) (pWin->parent, NullWindow, VTOther); + } + + if (WasViewable) { + (*pScreen->HandleExposures) (pWin->parent); + if (pScreen->PostValidateTree) + (*pScreen->PostValidateTree) (pWin->parent, NullWindow, + VTOther); + } + } + if (pWin->realized) + WindowsRestructured(); + CheckCursorConfinement(pWin); +} + +static void +miOverlayChangeBorderWidth(WindowPtr pWin, unsigned int width) +{ + int oldwidth; + ScreenPtr pScreen; + Bool WasViewable = (Bool) (pWin->viewable); + Bool HadBorder; + + oldwidth = wBorderWidth(pWin); + if (oldwidth == width) + return; + HadBorder = HasBorder(pWin); + pScreen = pWin->drawable.pScreen; + if (WasViewable && (width < oldwidth)) + (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL); + + pWin->borderWidth = width; + SetBorderSize(pWin); + + if (WasViewable) { + if (width > oldwidth) { + (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL); + + if (HadBorder) { + RegionPtr borderVisible; + + borderVisible = RegionCreate(NULL, 1); + RegionSubtract(borderVisible, + &pWin->borderClip, &pWin->winSize); + pWin->valdata->before.borderVisible = borderVisible; + if (IN_UNDERLAY(pWin)) { + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + RegionPtr borderVisible2; + + borderVisible2 = RegionCreate(NULL, 1); + RegionSubtract(borderVisible2, + &pTree->borderClip, &pWin->winSize); + pTree->valdata->borderVisible = borderVisible2; + } + } + } + (*pScreen->ValidateTree) (pWin->parent, pWin, VTOther); + (*pScreen->HandleExposures) (pWin->parent); + + if (pScreen->PostValidateTree) + (*pScreen->PostValidateTree) (pWin->parent, pWin, VTOther); + } + if (pWin->realized) + WindowsRestructured(); +} + +/* We need this as an addition since the xf86 common code doesn't + know about the second tree which is static to this file. */ + +void +miOverlaySetRootClip(ScreenPtr pScreen, Bool enable) +{ + WindowPtr pRoot = pScreen->root; + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pRoot); + + MARK_UNDERLAY(pRoot); + + if (enable) { + BoxRec box; + + box.x1 = 0; + box.y1 = 0; + box.x2 = pScreen->width; + box.y2 = pScreen->height; + + RegionReset(&pTree->borderClip, &box); + } + else + RegionEmpty(&pTree->borderClip); + + RegionBreak(&pTree->clipList); +} + +static void +miOverlayClearToBackground(WindowPtr pWin, + int x, int y, int w, int h, Bool generateExposures) +{ + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + BoxRec box; + RegionRec reg; + RegionPtr pBSReg = NullRegion; + ScreenPtr pScreen = pWin->drawable.pScreen; + miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); + RegionPtr clipList; + BoxPtr extents; + int x1, y1, x2, y2; + + x1 = pWin->drawable.x + x; + y1 = pWin->drawable.y + y; + if (w) + x2 = x1 + (int) w; + else + x2 = x1 + (int) pWin->drawable.width - (int) x; + if (h) + y2 = y1 + h; + else + y2 = y1 + (int) pWin->drawable.height - (int) y; + + clipList = ((*pScreenPriv->InOverlay) (pWin)) ? &pWin->clipList : + &pTree->clipList; + + extents = RegionExtents(clipList); + + if (x1 < extents->x1) + x1 = extents->x1; + if (x2 > extents->x2) + x2 = extents->x2; + if (y1 < extents->y1) + y1 = extents->y1; + if (y2 > extents->y2) + y2 = extents->y2; + + if (x2 <= x1 || y2 <= y1) + x2 = x1 = y2 = y1 = 0; + + box.x1 = x1; + box.x2 = x2; + box.y1 = y1; + box.y2 = y2; + + RegionInit(®, &box, 1); + + RegionIntersect(®, ®, clipList); + if (generateExposures) + (*pScreen->WindowExposures) (pWin, ®, pBSReg); + else if (pWin->backgroundState != None) + miPaintWindow(pWin, ®, PW_BACKGROUND); + RegionUninit(®); + if (pBSReg) + RegionDestroy(pBSReg); +} + +/****************************************************************/ + +/* not used */ +Bool +miOverlayGetPrivateClips(WindowPtr pWin, + RegionPtr *borderClip, RegionPtr *clipList) +{ + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + + if (pTree) { + *borderClip = &(pTree->borderClip); + *clipList = &(pTree->clipList); + return TRUE; + } + + *borderClip = *clipList = NULL; + + return FALSE; +} + +void +miOverlaySetTransFunction(ScreenPtr pScreen, miOverlayTransFunc transFunc) +{ + MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent = transFunc; +} + +Bool +miOverlayCopyUnderlay(ScreenPtr pScreen) +{ + return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->copyUnderlay; +} + +void +miOverlayComputeCompositeClip(GCPtr pGC, WindowPtr pWin) +{ + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + RegionPtr pregWin; + Bool freeTmpClip, freeCompClip; + + if (!pTree) { + miComputeCompositeClip(pGC, &pWin->drawable); + return; + } + + if (pGC->subWindowMode == IncludeInferiors) { + pregWin = RegionCreate(NullBox, 1); + freeTmpClip = TRUE; + if (pWin->parent || (screenIsSaved != SCREEN_SAVER_ON) || + !HasSaverWindow(pGC->pScreen)) { + RegionIntersect(pregWin, &pTree->borderClip, &pWin->winSize); + } + } + else { + pregWin = &pTree->clipList; + freeTmpClip = FALSE; + } + freeCompClip = pGC->freeCompClip; + if (pGC->clientClipType == CT_NONE) { + if (freeCompClip) + RegionDestroy(pGC->pCompositeClip); + pGC->pCompositeClip = pregWin; + pGC->freeCompClip = freeTmpClip; + } + else { + RegionTranslate(pGC->clientClip, + pWin->drawable.x + pGC->clipOrg.x, + pWin->drawable.y + pGC->clipOrg.y); + + if (freeCompClip) { + RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip); + if (freeTmpClip) + RegionDestroy(pregWin); + } + else if (freeTmpClip) { + RegionIntersect(pregWin, pregWin, pGC->clientClip); + pGC->pCompositeClip = pregWin; + } + else { + pGC->pCompositeClip = RegionCreate(NullBox, 0); + RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip); + } + pGC->freeCompClip = TRUE; + RegionTranslate(pGC->clientClip, + -(pWin->drawable.x + pGC->clipOrg.x), + -(pWin->drawable.y + pGC->clipOrg.y)); + } +} + +Bool +miOverlayCollectUnderlayRegions(WindowPtr pWin, RegionPtr *region) +{ + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + + if (pTree) { + *region = &pTree->borderClip; + return FALSE; + } + + *region = RegionCreate(NullBox, 0); + + CollectUnderlayChildrenRegions(pWin, *region); + + return TRUE; +} + +static miOverlayTreePtr +DoLeaf(WindowPtr pWin, miOverlayTreePtr parent, miOverlayTreePtr prevSib) +{ + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + + pTree->parent = parent; + pTree->firstChild = NULL; + pTree->lastChild = NULL; + pTree->prevSib = prevSib; + pTree->nextSib = NULL; + + if (prevSib) + prevSib->nextSib = pTree; + + if (!parent->firstChild) + parent->firstChild = parent->lastChild = pTree; + else if (parent->lastChild == prevSib) + parent->lastChild = pTree; + + return pTree; +} + +static void +RebuildTree(WindowPtr pWin) +{ + miOverlayTreePtr parent, prevSib, tChild; + WindowPtr pChild; + + prevSib = tChild = NULL; + + pWin = pWin->parent; + + while (IN_OVERLAY(pWin)) + pWin = pWin->parent; + + parent = MIOVERLAY_GET_WINDOW_TREE(pWin); + + pChild = pWin->firstChild; + parent->firstChild = parent->lastChild = NULL; + + while (1) { + if (IN_UNDERLAY(pChild)) + prevSib = tChild = DoLeaf(pChild, parent, prevSib); + + if (pChild->firstChild) { + if (IN_UNDERLAY(pChild)) { + parent = tChild; + prevSib = NULL; + } + pChild = pChild->firstChild; + continue; + } + + while (!pChild->nextSib) { + pChild = pChild->parent; + if (pChild == pWin) + return; + if (IN_UNDERLAY(pChild)) { + prevSib = tChild = MIOVERLAY_GET_WINDOW_TREE(pChild); + parent = tChild->parent; + } + } + + pChild = pChild->nextSib; + } +} + +static Bool +HasUnderlayChildren(WindowPtr pWin) +{ + WindowPtr pChild; + + if (!(pChild = pWin->firstChild)) + return FALSE; + + while (1) { + if (IN_UNDERLAY(pChild)) + return TRUE; + + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + + while (!pChild->nextSib && (pWin != pChild)) + pChild = pChild->parent; + + if (pChild == pWin) + break; + + pChild = pChild->nextSib; + } + + return FALSE; +} + +static Bool +CollectUnderlayChildrenRegions(WindowPtr pWin, RegionPtr pReg) +{ + WindowPtr pChild; + miOverlayTreePtr pTree; + Bool hasUnderlay; + + if (!(pChild = pWin->firstChild)) + return FALSE; + + hasUnderlay = FALSE; + + while (1) { + if ((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) { + RegionAppend(pReg, &pTree->borderClip); + hasUnderlay = TRUE; + } + else if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + + while (!pChild->nextSib && (pWin != pChild)) + pChild = pChild->parent; + + if (pChild == pWin) + break; + + pChild = pChild->nextSib; + } + + if (hasUnderlay) { + Bool overlap; + + RegionValidate(pReg, &overlap); + } + + return hasUnderlay; +} + +static void +MarkUnderlayWindow(WindowPtr pWin) +{ + miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); + + if (pTree->valdata) + return; + pTree->valdata = + (miOverlayValDataPtr) xnfalloc(sizeof(miOverlayValDataRec)); + pTree->valdata->oldAbsCorner.x = pWin->drawable.x; + pTree->valdata->oldAbsCorner.y = pWin->drawable.y; + pTree->valdata->borderVisible = NullRegion; +} diff --git a/xorg-server/mi/mioverlay.h b/xorg-server/mi/mioverlay.h index dca65ad37..f7ed027e9 100644 --- a/xorg-server/mi/mioverlay.h +++ b/xorg-server/mi/mioverlay.h @@ -6,27 +6,23 @@ #ifndef __MIOVERLAY_H #define __MIOVERLAY_H -typedef void (*miOverlayTransFunc)(ScreenPtr, int, BoxPtr); -typedef Bool (*miOverlayInOverlayFunc)(WindowPtr); +typedef void (*miOverlayTransFunc) (ScreenPtr, int, BoxPtr); +typedef Bool (*miOverlayInOverlayFunc) (WindowPtr); extern _X_EXPORT Bool -miInitOverlay( - ScreenPtr pScreen, - miOverlayInOverlayFunc inOverlay, - miOverlayTransFunc trans -); + +miInitOverlay(ScreenPtr pScreen, + miOverlayInOverlayFunc inOverlay, miOverlayTransFunc trans); extern _X_EXPORT Bool -miOverlayGetPrivateClips( - WindowPtr pWin, - RegionPtr *borderClip, - RegionPtr *clipList -); -extern _X_EXPORT Bool miOverlayCollectUnderlayRegions(WindowPtr, RegionPtr*); +miOverlayGetPrivateClips(WindowPtr pWin, + RegionPtr *borderClip, RegionPtr *clipList); + +extern _X_EXPORT Bool miOverlayCollectUnderlayRegions(WindowPtr, RegionPtr *); extern _X_EXPORT void miOverlayComputeCompositeClip(GCPtr, WindowPtr); extern _X_EXPORT Bool miOverlayCopyUnderlay(ScreenPtr); extern _X_EXPORT void miOverlaySetTransFunction(ScreenPtr, miOverlayTransFunc); extern _X_EXPORT void miOverlaySetRootClip(ScreenPtr, Bool); -#endif /* __MIOVERLAY_H */ +#endif /* __MIOVERLAY_H */ diff --git a/xorg-server/mi/mipointer.c b/xorg-server/mi/mipointer.c index 998c86c15..de6698a37 100644 --- a/xorg-server/mi/mipointer.c +++ b/xorg-server/mi/mipointer.c @@ -50,20 +50,20 @@ in this Software without prior written authorization from The Open Group. #include <dix-config.h> #endif -# include <X11/X.h> -# include <X11/Xmd.h> -# include <X11/Xproto.h> -# include "misc.h" -# include "windowstr.h" -# include "pixmapstr.h" -# include "mi.h" -# include "scrnintstr.h" -# include "mipointrst.h" -# include "cursorstr.h" -# include "dixstruct.h" -# include "inputstr.h" -# include "inpututils.h" -# include "eventstr.h" +#include <X11/X.h> +#include <X11/Xmd.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "mi.h" +#include "scrnintstr.h" +#include "mipointrst.h" +#include "cursorstr.h" +#include "dixstruct.h" +#include "inputstr.h" +#include "inpututils.h" +#include "eventstr.h" DevPrivateKeyRec miPointerScreenKeyRec; @@ -78,56 +78,53 @@ DevPrivateKeyRec miPointerPrivKeyRec; (miPointerPtr)dixLookupPrivate(&(dev)->devPrivates, miPointerPrivKey): \ (miPointerPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miPointerPrivKey)) -static Bool miPointerRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, +static Bool miPointerRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor); -static Bool miPointerUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, +static Bool miPointerUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor); -static Bool miPointerDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, +static Bool miPointerDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor); static void miPointerConstrainCursor(DeviceIntPtr pDev, ScreenPtr pScreen, - BoxPtr pBox); + BoxPtr pBox); static void miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, - CursorPtr pCursor, BoxPtr pHotBox, + CursorPtr pCursor, BoxPtr pHotBox, BoxPtr pTopLeftBox); -static Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, - int x, int y, - Bool generateEvent); +static Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y, Bool generateEvent); static Bool miPointerCloseScreen(int index, ScreenPtr pScreen); -static void miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, - int x, int y); +static void miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y); static Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen); -static void miPointerDeviceCleanup(DeviceIntPtr pDev, - ScreenPtr pScreen); -static void miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y); +static void miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen); +static void miPointerMoveNoEvent(DeviceIntPtr pDev, ScreenPtr pScreen, int x, + int y); -static InternalEvent* events; /* for WarpPointer MotionNotifies */ +static InternalEvent *events; /* for WarpPointer MotionNotifies */ Bool -miPointerInitialize (ScreenPtr pScreen, - miPointerSpriteFuncPtr spriteFuncs, - miPointerScreenFuncPtr screenFuncs, - Bool waitForUpdate) +miPointerInitialize(ScreenPtr pScreen, + miPointerSpriteFuncPtr spriteFuncs, + miPointerScreenFuncPtr screenFuncs, Bool waitForUpdate) { - miPointerScreenPtr pScreenPriv; + miPointerScreenPtr pScreenPriv; if (!dixRegisterPrivateKey(&miPointerScreenKeyRec, PRIVATE_SCREEN, 0)) - return FALSE; + return FALSE; if (!dixRegisterPrivateKey(&miPointerPrivKeyRec, PRIVATE_DEVICE, 0)) - return FALSE; + return FALSE; - pScreenPriv = malloc(sizeof (miPointerScreenRec)); + pScreenPriv = malloc(sizeof(miPointerScreenRec)); if (!pScreenPriv) - return FALSE; + return FALSE; pScreenPriv->spriteFuncs = spriteFuncs; pScreenPriv->screenFuncs = screenFuncs; /* * check for uninitialized methods */ if (!screenFuncs->EnqueueEvent) - screenFuncs->EnqueueEvent = mieqEnqueue; + screenFuncs->EnqueueEvent = mieqEnqueue; if (!screenFuncs->NewEventScreen) - screenFuncs->NewEventScreen = mieqSwitchScreen; + screenFuncs->NewEventScreen = mieqSwitchScreen; pScreenPriv->waitForUpdate = waitForUpdate; pScreenPriv->showTransparent = FALSE; pScreenPriv->CloseScreen = pScreen->CloseScreen; @@ -157,7 +154,7 @@ miPointerInitialize (ScreenPtr pScreen, * @param pScreen The actual screen pointer */ static Bool -miPointerCloseScreen (int index, ScreenPtr pScreen) +miPointerCloseScreen(int index, ScreenPtr pScreen) { SetupScreen(pScreen); @@ -173,29 +170,29 @@ miPointerCloseScreen (int index, ScreenPtr pScreen) */ static Bool -miPointerRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) +miPointerRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { SetupScreen(pScreen); return (*pScreenPriv->spriteFuncs->RealizeCursor) (pDev, pScreen, pCursor); } static Bool -miPointerUnrealizeCursor (DeviceIntPtr pDev, - ScreenPtr pScreen, - CursorPtr pCursor) +miPointerUnrealizeCursor(DeviceIntPtr pDev, + ScreenPtr pScreen, CursorPtr pCursor) { SetupScreen(pScreen); - return (*pScreenPriv->spriteFuncs->UnrealizeCursor) (pDev, pScreen, pCursor); + return (*pScreenPriv->spriteFuncs->UnrealizeCursor) (pDev, pScreen, + pCursor); } static Bool -miPointerDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) +miPointerDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { miPointerPtr pPointer; /* return for keyboards */ if (!IsPointerDevice(pDev)) - return FALSE; + return FALSE; pPointer = MIPOINTER(pDev); @@ -215,7 +212,7 @@ miPointerDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) * @param pScreen Used for copying screen confinement */ static void -miPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox) +miPointerConstrainCursor(DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox) { miPointerPtr pPointer; @@ -268,18 +265,18 @@ static Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, Bool generateEvent) { - SetupScreen (pScreen); + SetupScreen(pScreen); miPointerPtr pPointer = MIPOINTER(pDev); pPointer->generateEvent = generateEvent; if (pScreen->ConstrainCursorHarder) - pScreen->ConstrainCursorHarder(pDev, pScreen, Absolute, &x, &y); + pScreen->ConstrainCursorHarder(pDev, pScreen, Absolute, &x, &y); /* device dependent - must pend signal and call miPointerWarpCursor */ (*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y); if (!generateEvent) - miPointerUpdateSprite(pDev); + miPointerUpdateSprite(pDev); return TRUE; } @@ -295,7 +292,8 @@ static Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) { miPointerPtr pPointer; - SetupScreen (pScreen); + + SetupScreen(pScreen); pPointer = malloc(sizeof(miPointerRec)); if (!pPointer) @@ -314,8 +312,7 @@ miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) pPointer->y = 0; pPointer->generateEvent = FALSE; - if (!((*pScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen))) - { + if (!((*pScreenPriv->spriteFuncs->DeviceCursorInitialize) (pDev, pScreen))) { free(pPointer); return FALSE; } @@ -339,12 +336,11 @@ miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) if (!IsMaster(pDev) && !IsFloating(pDev)) return; - (*pScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen); + (*pScreenPriv->spriteFuncs->DeviceCursorCleanup) (pDev, pScreen); free(dixLookupPrivate(&pDev->devPrivates, miPointerPrivKey)); dixSetPrivate(&pDev->devPrivates, miPointerPrivKey, NULL); } - /** * Warp the pointer to the given position on the given screen. May generate * an event, depending on whether we're coming from miPointerSetPosition. @@ -358,22 +354,21 @@ miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) */ void -miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) +miPointerWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { miPointerPtr pPointer; BOOL changedScreen = FALSE; - SetupScreen (pScreen); + SetupScreen(pScreen); pPointer = MIPOINTER(pDev); - if (pPointer->pScreen != pScreen) - { - (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, TRUE); + if (pPointer->pScreen != pScreen) { + (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, TRUE); changedScreen = TRUE; } if (pPointer->generateEvent) - miPointerMove (pDev, pScreen, x, y); + miPointerMove(pDev, pScreen, x, y); else miPointerMoveNoEvent(pDev, pScreen, x, y); @@ -382,10 +377,10 @@ miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) * (FDO bug #18668) */ if (changedScreen #ifdef PANORAMIX - && noPanoramiXExtension + && noPanoramiXExtension #endif - ) - UpdateSpriteForScreen (pDev, pScreen) ; + ) + UpdateSpriteForScreen(pDev, pScreen); } /** @@ -394,13 +389,13 @@ miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) * @param pDev The device to sync */ void -miPointerUpdateSprite (DeviceIntPtr pDev) +miPointerUpdateSprite(DeviceIntPtr pDev) { - ScreenPtr pScreen; - miPointerScreenPtr pScreenPriv; - CursorPtr pCursor; - int x, y, devx, devy; - miPointerPtr pPointer; + ScreenPtr pScreen; + miPointerScreenPtr pScreenPriv; + CursorPtr pCursor; + int x, y, devx, devy; + miPointerPtr pPointer; if (!pDev || !pDev->coreEvents) return; @@ -412,60 +407,57 @@ miPointerUpdateSprite (DeviceIntPtr pDev) pScreen = pPointer->pScreen; if (!pScreen) - return; + return; x = pPointer->x; y = pPointer->y; devx = pPointer->devx; devy = pPointer->devy; - pScreenPriv = GetScreenPrivate (pScreen); + pScreenPriv = GetScreenPrivate(pScreen); /* * if the cursor has switched screens, disable the sprite * on the old screen */ - if (pScreen != pPointer->pSpriteScreen) - { - if (pPointer->pSpriteScreen) - { - miPointerScreenPtr pOldPriv; - - pOldPriv = GetScreenPrivate (pPointer->pSpriteScreen); - if (pPointer->pCursor) - { - (*pOldPriv->spriteFuncs->SetCursor) - (pDev, pPointer->pSpriteScreen, NullCursor, 0, 0); - } - (*pOldPriv->screenFuncs->CrossScreen) (pPointer->pSpriteScreen, FALSE); - } - (*pScreenPriv->screenFuncs->CrossScreen) (pScreen, TRUE); - (*pScreenPriv->spriteFuncs->SetCursor) - (pDev, pScreen, pPointer->pCursor, x, y); - pPointer->devx = x; - pPointer->devy = y; - pPointer->pSpriteCursor = pPointer->pCursor; - pPointer->pSpriteScreen = pScreen; + if (pScreen != pPointer->pSpriteScreen) { + if (pPointer->pSpriteScreen) { + miPointerScreenPtr pOldPriv; + + pOldPriv = GetScreenPrivate(pPointer->pSpriteScreen); + if (pPointer->pCursor) { + (*pOldPriv->spriteFuncs->SetCursor) + (pDev, pPointer->pSpriteScreen, NullCursor, 0, 0); + } + (*pOldPriv->screenFuncs->CrossScreen) (pPointer->pSpriteScreen, + FALSE); + } + (*pScreenPriv->screenFuncs->CrossScreen) (pScreen, TRUE); + (*pScreenPriv->spriteFuncs->SetCursor) + (pDev, pScreen, pPointer->pCursor, x, y); + pPointer->devx = x; + pPointer->devy = y; + pPointer->pSpriteCursor = pPointer->pCursor; + pPointer->pSpriteScreen = pScreen; } /* * if the cursor has changed, display the new one */ - else if (pPointer->pCursor != pPointer->pSpriteCursor) - { - pCursor = pPointer->pCursor; - if (!pCursor || (pCursor->bits->emptyMask && !pScreenPriv->showTransparent)) - pCursor = NullCursor; - (*pScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pCursor, x, y); - - pPointer->devx = x; - pPointer->devy = y; - pPointer->pSpriteCursor = pPointer->pCursor; + else if (pPointer->pCursor != pPointer->pSpriteCursor) { + pCursor = pPointer->pCursor; + if (!pCursor || + (pCursor->bits->emptyMask && !pScreenPriv->showTransparent)) + pCursor = NullCursor; + (*pScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pCursor, x, y); + + pPointer->devx = x; + pPointer->devy = y; + pPointer->pSpriteCursor = pPointer->pCursor; } - else if (x != devx || y != devy) - { - pPointer->devx = x; - pPointer->devy = y; - if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask) - (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); + else if (x != devx || y != devy) { + pPointer->devx = x; + pPointer->devy = y; + if (pPointer->pCursor && !pPointer->pCursor->bits->emptyMask) + (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); } } @@ -480,26 +472,26 @@ miPointerUpdateSprite (DeviceIntPtr pDev) void miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y) { - miPointerScreenPtr pScreenPriv; - ScreenPtr pScreen; - miPointerPtr pPointer; + miPointerScreenPtr pScreenPriv; + ScreenPtr pScreen; + miPointerPtr pPointer; - pPointer = MIPOINTER(pDev); + pPointer = MIPOINTER(pDev); - pScreen = screenInfo.screens[screen_no]; - pScreenPriv = GetScreenPrivate (pScreen); - (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE); - NewCurrentScreen (pDev, pScreen, x, y); + pScreen = screenInfo.screens[screen_no]; + pScreenPriv = GetScreenPrivate(pScreen); + (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE); + NewCurrentScreen(pDev, pScreen, x, y); - pPointer->limits.x2 = pScreen->width; - pPointer->limits.y2 = pScreen->height; + pPointer->limits.x2 = pScreen->width; + pPointer->limits.y2 = pScreen->height; } /** * @return The current screen of the VCP */ ScreenPtr -miPointerCurrentScreen (void) +miPointerCurrentScreen(void) { return miPointerGetScreen(inputInfo.pointer); } @@ -511,6 +503,7 @@ ScreenPtr miPointerGetScreen(DeviceIntPtr pDev) { miPointerPtr pPointer = MIPOINTER(pDev); + return (pPointer) ? pPointer->pScreen : NULL; } @@ -529,13 +522,12 @@ miPointerSetWaitForUpdate(ScreenPtr pScreen, Bool wait) return prevWait; } - /* Move the pointer on the current screen, and update the sprite. */ static void -miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, - int x, int y) +miPointerMoveNoEvent(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { miPointerPtr pPointer; + SetupScreen(pScreen); pPointer = MIPOINTER(pDev); @@ -545,12 +537,11 @@ miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, * SIGIO. This again leads to allocs during SIGIO which leads to SIGABRT. */ if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer - && !pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen) - { - pPointer->devx = x; - pPointer->devy = y; - if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask) - (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); + &&!pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen) { + pPointer->devx = x; + pPointer->devy = y; + if (pPointer->pCursor && !pPointer->pCursor->bits->emptyMask) + (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); } pPointer->x = x; @@ -573,15 +564,16 @@ miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, * @param[in,out] screeny The y coordinate in desktop coordinates */ ScreenPtr -miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx, double *screeny) +miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx, + double *screeny) { - miPointerScreenPtr pScreenPriv; - ScreenPtr pScreen; - ScreenPtr newScreen; - int x, y; - Bool switch_screen = FALSE; + miPointerScreenPtr pScreenPriv; + ScreenPtr pScreen; + ScreenPtr newScreen; + int x, y; + Bool switch_screen = FALSE; - miPointerPtr pPointer; + miPointerPtr pPointer; if (!pDev || !pDev->coreEvents) return NULL; @@ -589,7 +581,7 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx, double *scree pPointer = MIPOINTER(pDev); pScreen = pPointer->pScreen; if (!pScreen) - return NULL; /* called before ready */ + return NULL; /* called before ready */ x = trunc(*screenx); y = trunc(*screeny); @@ -601,39 +593,35 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx, double *scree x -= pScreen->x; y -= pScreen->y; - if (switch_screen) - { - pScreenPriv = GetScreenPrivate (pScreen); - if (!pPointer->confined) - { - newScreen = pScreen; - (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, &x, &y); - if (newScreen != pScreen) - { - pScreen = newScreen; - (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, - FALSE); - /* Smash the confine to the new screen */ + if (switch_screen) { + pScreenPriv = GetScreenPrivate(pScreen); + if (!pPointer->confined) { + newScreen = pScreen; + (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, &x, &y); + if (newScreen != pScreen) { + pScreen = newScreen; + (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, + FALSE); + /* Smash the confine to the new screen */ pPointer->limits.x2 = pScreen->width; pPointer->limits.y2 = pScreen->height; - } - } + } + } } /* Constrain the sprite to the current limits. */ if (x < pPointer->limits.x1) - x = pPointer->limits.x1; + x = pPointer->limits.x1; if (x >= pPointer->limits.x2) - x = pPointer->limits.x2 - 1; + x = pPointer->limits.x2 - 1; if (y < pPointer->limits.y1) - y = pPointer->limits.y1; + y = pPointer->limits.y1; if (y >= pPointer->limits.y2) - y = pPointer->limits.y2 - 1; + y = pPointer->limits.y2 - 1; if (pScreen->ConstrainCursorHarder) - pScreen->ConstrainCursorHarder(pDev, pScreen, mode, &x, &y); + pScreen->ConstrainCursorHarder(pDev, pScreen, mode, &x, &y); - if (pPointer->x != x || pPointer->y != y || - pPointer->pScreen != pScreen) + if (pPointer->x != x || pPointer->y != y || pPointer->pScreen != pScreen) miPointerMoveNoEvent(pDev, pScreen, x, y); /* Convert to desktop coordinates again */ @@ -681,7 +669,7 @@ void darwinEvents_unlock(void); * @param y The y coordinate in per-screen coordinates */ void -miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) +miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { int i, nevents; int valuators[2]; @@ -693,12 +681,10 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) valuators[0] = x; valuators[1] = y; - if (!events) - { + if (!events) { events = InitEventList(GetMaximumEventsNum()); - if (!events) - { + if (!events) { FatalError("Could not allocate event store.\n"); return; } @@ -706,7 +692,8 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) valuator_mask_set_range(&mask, 0, 2, valuators); nevents = GetPointerEvents(events, pDev, MotionNotify, 0, - POINTER_SCREEN | POINTER_ABSOLUTE | POINTER_NORAW, &mask); + POINTER_SCREEN | POINTER_ABSOLUTE | + POINTER_NORAW, &mask); OsBlockSignals(); #ifdef XQUARTZ diff --git a/xorg-server/mi/mipointer.h b/xorg-server/mi/mipointer.h index 45abb5b56..1500e216a 100644 --- a/xorg-server/mi/mipointer.h +++ b/xorg-server/mi/mipointer.h @@ -31,124 +31,105 @@ in this Software without prior written authorization from The Open Group. #include "privates.h" typedef struct _miPointerSpriteFuncRec { - Bool (*RealizeCursor)( - DeviceIntPtr /* pDev */, - ScreenPtr /* pScr */, - CursorPtr /* pCurs */ - ); - Bool (*UnrealizeCursor)( - DeviceIntPtr /* pDev */, - ScreenPtr /* pScr */, - CursorPtr /* pCurs */ - ); - void (*SetCursor)( - DeviceIntPtr /* pDev */, - ScreenPtr /* pScr */, - CursorPtr /* pCurs */, - int /* x */, - int /* y */ - ); - void (*MoveCursor)( - DeviceIntPtr /* pDev */, - ScreenPtr /* pScr */, - int /* x */, - int /* y */ - ); - Bool (*DeviceCursorInitialize)( - DeviceIntPtr /* pDev */, - ScreenPtr /* pScr */ - ); - void (*DeviceCursorCleanup)( - DeviceIntPtr /* pDev */, - ScreenPtr /* pScr */ - ); + Bool (*RealizeCursor) (DeviceIntPtr /* pDev */ , + ScreenPtr /* pScr */ , + CursorPtr /* pCurs */ + ); + Bool (*UnrealizeCursor) (DeviceIntPtr /* pDev */ , + ScreenPtr /* pScr */ , + CursorPtr /* pCurs */ + ); + void (*SetCursor) (DeviceIntPtr /* pDev */ , + ScreenPtr /* pScr */ , + CursorPtr /* pCurs */ , + int /* x */ , + int /* y */ + ); + void (*MoveCursor) (DeviceIntPtr /* pDev */ , + ScreenPtr /* pScr */ , + int /* x */ , + int /* y */ + ); + Bool (*DeviceCursorInitialize) (DeviceIntPtr /* pDev */ , + ScreenPtr /* pScr */ + ); + void (*DeviceCursorCleanup) (DeviceIntPtr /* pDev */ , + ScreenPtr /* pScr */ + ); } miPointerSpriteFuncRec, *miPointerSpriteFuncPtr; typedef struct _miPointerScreenFuncRec { - Bool (*CursorOffScreen)( - ScreenPtr* /* ppScr */, - int* /* px */, - int* /* py */ - ); - void (*CrossScreen)( - ScreenPtr /* pScr */, - int /* entering */ - ); - void (*WarpCursor)( - DeviceIntPtr /*pDev*/, - ScreenPtr /* pScr */, - int /* x */, - int /* y */ - ); - void (*EnqueueEvent)( - DeviceIntPtr /* pDev */, - InternalEvent* /* event */ - ); - void (*NewEventScreen)( - DeviceIntPtr /* pDev */, - ScreenPtr /* pScr */, - Bool /* set_dequeue_screen */ - ); + Bool (*CursorOffScreen) (ScreenPtr * /* ppScr */ , + int * /* px */ , + int * /* py */ + ); + void (*CrossScreen) (ScreenPtr /* pScr */ , + int /* entering */ + ); + void (*WarpCursor) (DeviceIntPtr /*pDev */ , + ScreenPtr /* pScr */ , + int /* x */ , + int /* y */ + ); + void (*EnqueueEvent) (DeviceIntPtr /* pDev */ , + InternalEvent * /* event */ + ); + void (*NewEventScreen) (DeviceIntPtr /* pDev */ , + ScreenPtr /* pScr */ , + Bool /* set_dequeue_screen */ + ); } miPointerScreenFuncRec, *miPointerScreenFuncPtr; -extern _X_EXPORT Bool miDCInitialize( - ScreenPtr /*pScreen*/, - miPointerScreenFuncPtr /*screenFuncs*/ -); - -extern _X_EXPORT Bool miPointerInitialize( - ScreenPtr /*pScreen*/, - miPointerSpriteFuncPtr /*spriteFuncs*/, - miPointerScreenFuncPtr /*screenFuncs*/, - Bool /*waitForUpdate*/ -); - -extern _X_EXPORT void miPointerWarpCursor( - DeviceIntPtr /*pDev*/, - ScreenPtr /*pScreen*/, - int /*x*/, - int /*y*/ -); +extern _X_EXPORT Bool miDCInitialize(ScreenPtr /*pScreen */ , + miPointerScreenFuncPtr /*screenFuncs */ + ); + +extern _X_EXPORT Bool miPointerInitialize(ScreenPtr /*pScreen */ , + miPointerSpriteFuncPtr + /*spriteFuncs */ , + miPointerScreenFuncPtr + /*screenFuncs */ , + Bool /*waitForUpdate */ + ); + +extern _X_EXPORT void miPointerWarpCursor(DeviceIntPtr /*pDev */ , + ScreenPtr /*pScreen */ , + int /*x */ , + int /*y */ + ); /* Deprecated in favour of miPointerGetScreen. */ -extern _X_EXPORT ScreenPtr miPointerCurrentScreen( - void +extern _X_EXPORT ScreenPtr +miPointerCurrentScreen(void ) _X_DEPRECATED; -extern _X_EXPORT ScreenPtr miPointerGetScreen( - DeviceIntPtr pDev); -extern _X_EXPORT void miPointerSetScreen( - DeviceIntPtr pDev, - int screen_num, - int x, - int y); +extern _X_EXPORT ScreenPtr +miPointerGetScreen(DeviceIntPtr pDev); +extern _X_EXPORT void +miPointerSetScreen(DeviceIntPtr pDev, int screen_num, int x, int y); /* Returns the current cursor position. */ -extern _X_EXPORT void miPointerGetPosition( - DeviceIntPtr pDev, - int *x, - int *y); +extern _X_EXPORT void +miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y); /* Moves the cursor to the specified position. May clip the co-ordinates: * x and y are modified in-place. */ -extern _X_EXPORT ScreenPtr miPointerSetPosition( - DeviceIntPtr pDev, - int mode, - double *x, - double *y); +extern _X_EXPORT ScreenPtr +miPointerSetPosition(DeviceIntPtr pDev, int mode, double *x, double *y); -extern _X_EXPORT void miPointerUpdateSprite( - DeviceIntPtr pDev); +extern _X_EXPORT void +miPointerUpdateSprite(DeviceIntPtr pDev); /* Sets whether the sprite should be updated immediately on pointer moves */ -extern _X_EXPORT Bool miPointerSetWaitForUpdate( - ScreenPtr pScreen, - Bool wait); +extern _X_EXPORT Bool +miPointerSetWaitForUpdate(ScreenPtr pScreen, Bool wait); extern _X_EXPORT DevPrivateKeyRec miPointerPrivKeyRec; + #define miPointerPrivKey (&miPointerPrivKeyRec) extern _X_EXPORT DevPrivateKeyRec miPointerScreenKeyRec; + #define miPointerScreenKey (&miPointerScreenKeyRec) -#endif /* MIPOINTER_H */ +#endif /* MIPOINTER_H */ diff --git a/xorg-server/mi/mipoly.c b/xorg-server/mi/mipoly.c index b3e2c2fb1..07d981845 100644 --- a/xorg-server/mi/mipoly.c +++ b/xorg-server/mi/mipoly.c @@ -22,7 +22,6 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved @@ -65,60 +64,50 @@ SOFTWARE. #include "mi.h" #include "regionstr.h" - void -miFillPolygon( DrawablePtr dst, GCPtr pgc, - int shape, int mode, - int count, DDXPointPtr pPts) +miFillPolygon(DrawablePtr dst, GCPtr pgc, + int shape, int mode, int count, DDXPointPtr pPts) { - int i; - int xorg, yorg; - DDXPointPtr ppt; + int i; + int xorg, yorg; + DDXPointPtr ppt; if (count == 0) - return; + return; ppt = pPts; - if (pgc->miTranslate) - { - xorg = dst->x; - yorg = dst->y; - - if (mode == CoordModeOrigin) - { - for (i = 0; i<count; i++) - { - ppt->x += xorg; - ppt++->y += yorg; - } + if (pgc->miTranslate) { + xorg = dst->x; + yorg = dst->y; + + if (mode == CoordModeOrigin) { + for (i = 0; i < count; i++) { + ppt->x += xorg; + ppt++->y += yorg; + } } - else - { - ppt->x += xorg; - ppt++->y += yorg; - for (i = 1; i<count; i++) - { - ppt->x += (ppt-1)->x; - ppt->y += (ppt-1)->y; - ppt++; - } + else { + ppt->x += xorg; + ppt++->y += yorg; + for (i = 1; i < count; i++) { + ppt->x += (ppt - 1)->x; + ppt->y += (ppt - 1)->y; + ppt++; + } } } - else - { - if (mode == CoordModePrevious) - { - ppt++; - for (i = 1; i<count; i++) - { - ppt->x += (ppt-1)->x; - ppt->y += (ppt-1)->y; - ppt++; - } + else { + if (mode == CoordModePrevious) { + ppt++; + for (i = 1; i < count; i++) { + ppt->x += (ppt - 1)->x; + ppt->y += (ppt - 1)->y; + ppt++; + } } } if (shape == Convex) - miFillConvexPoly(dst, pgc, count, pPts); + miFillConvexPoly(dst, pgc, count, pPts); else - miFillGeneralPoly(dst, pgc, count, pPts); + miFillGeneralPoly(dst, pgc, count, pPts); } diff --git a/xorg-server/mi/mipoly.h b/xorg-server/mi/mipoly.h index d94796e2f..e37fb48a2 100644 --- a/xorg-server/mi/mipoly.h +++ b/xorg-server/mi/mipoly.h @@ -26,7 +26,6 @@ from The Open Group. */ - /* * fill.h * @@ -83,32 +82,29 @@ from The Open Group. * for the winding number rule */ #define CLOCKWISE 1 -#define COUNTERCLOCKWISE -1 +#define COUNTERCLOCKWISE -1 typedef struct _EdgeTableEntry { - int ymax; /* ycoord at which we exit this edge. */ - BRESINFO bres; /* Bresenham info to run the edge */ - struct _EdgeTableEntry *next; /* next in the list */ - struct _EdgeTableEntry *back; /* for insertion sort */ - struct _EdgeTableEntry *nextWETE; /* for winding num rule */ - int ClockWise; /* flag for winding number rule */ + int ymax; /* ycoord at which we exit this edge. */ + BRESINFO bres; /* Bresenham info to run the edge */ + struct _EdgeTableEntry *next; /* next in the list */ + struct _EdgeTableEntry *back; /* for insertion sort */ + struct _EdgeTableEntry *nextWETE; /* for winding num rule */ + int ClockWise; /* flag for winding number rule */ } EdgeTableEntry; - -typedef struct _ScanLineList{ - int scanline; /* the scanline represented */ - EdgeTableEntry *edgelist; /* header node */ - struct _ScanLineList *next; /* next in the list */ +typedef struct _ScanLineList { + int scanline; /* the scanline represented */ + EdgeTableEntry *edgelist; /* header node */ + struct _ScanLineList *next; /* next in the list */ } ScanLineList; - typedef struct { - int ymax; /* ymax for the polygon */ - int ymin; /* ymin for the polygon */ - ScanLineList scanlines; /* header node */ + int ymax; /* ymax for the polygon */ + int ymin; /* ymin for the polygon */ + ScanLineList scanlines; /* header node */ } EdgeTable; - /* * Here is a struct to help with storage allocation * so we can allocate a big chunk at a time, and then take @@ -117,8 +113,8 @@ typedef struct { #define SLLSPERBLOCK 25 typedef struct _ScanLineListBlock { - ScanLineList SLLs[SLLSPERBLOCK]; - struct _ScanLineListBlock *next; + ScanLineList SLLs[SLLSPERBLOCK]; + struct _ScanLineListBlock *next; } ScanLineListBlock; /* @@ -126,7 +122,6 @@ typedef struct _ScanLineListBlock { * to scanlines() : Must be an even number */ #define NUMPTSTOBUFFER 200 - /* * @@ -156,7 +151,6 @@ typedef struct _ScanLineListBlock { } \ } - /* * Evaluate the given edge at the given scanline. * If the edge has expired, then we leave it and fix up @@ -180,28 +174,20 @@ typedef struct _ScanLineListBlock { /* mipolyutil.c */ -extern _X_EXPORT Bool miCreateETandAET( - int /*count*/, - DDXPointPtr /*pts*/, - EdgeTable * /*ET*/, - EdgeTableEntry * /*AET*/, - EdgeTableEntry * /*pETEs*/, - ScanLineListBlock * /*pSLLBlock*/ -); - -extern _X_EXPORT void miloadAET( - EdgeTableEntry * /*AET*/, - EdgeTableEntry * /*ETEs*/ -); - -extern _X_EXPORT void micomputeWAET( - EdgeTableEntry * /*AET*/ -); - -extern _X_EXPORT int miInsertionSort( - EdgeTableEntry * /*AET*/ -); - -extern _X_EXPORT void miFreeStorage( - ScanLineListBlock * /*pSLLBlock*/ -); +extern _X_EXPORT Bool miCreateETandAET(int /*count */ , + DDXPointPtr /*pts */ , + EdgeTable * /*ET*/, + EdgeTableEntry * /*AET*/, + EdgeTableEntry * /*pETEs */ , + ScanLineListBlock * /*pSLLBlock */ + ); + +extern _X_EXPORT void miloadAET(EdgeTableEntry * /*AET*/, EdgeTableEntry * /*ETEs */ + ); + +extern _X_EXPORT void micomputeWAET(EdgeTableEntry * /*AET*/); + +extern _X_EXPORT int miInsertionSort(EdgeTableEntry * /*AET*/); + +extern _X_EXPORT void miFreeStorage(ScanLineListBlock * /*pSLLBlock */ + ); diff --git a/xorg-server/mi/mipolycon.c b/xorg-server/mi/mipolycon.c index 7c9b47747..e831633fe 100644 --- a/xorg-server/mi/mipolycon.c +++ b/xorg-server/mi/mipolycon.c @@ -1,247 +1,235 @@ -/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "gcstruct.h"
-#include "pixmap.h"
-#include "mi.h"
-#include "miscanfill.h"
-
-static int getPolyYBounds(DDXPointPtr pts, int n, int *by, int *ty);
-
-/*
- * convexpoly.c
- *
- * Written by Brian Kelleher; Dec. 1985.
- *
- * Fill a convex polygon. If the given polygon
- * is not convex, then the result is undefined.
- * The algorithm is to order the edges from smallest
- * y to largest by partitioning the array into a left
- * edge list and a right edge list. The algorithm used
- * to traverse each edge is an extension of Bresenham's
- * line algorithm with y as the major axis.
- * For a derivation of the algorithm, see the author of
- * this code.
- */
-Bool
-miFillConvexPoly(
- DrawablePtr dst,
- GCPtr pgc,
- int count, /* number of points */
- DDXPointPtr ptsIn /* the points */
- )
-{
- int xl = 0, xr = 0; /* x vals of left and right edges */
- int dl = 0, dr = 0; /* decision variables */
- int ml = 0, m1l = 0;/* left edge slope and slope+1 */
- int mr = 0, m1r = 0; /* right edge slope and slope+1 */
- int incr1l = 0, incr2l = 0; /* left edge error increments */
- int incr1r = 0, incr2r = 0; /* right edge error increments */
- int dy; /* delta y */
- int y; /* current scanline */
- int left, right; /* indices to first endpoints */
- int i; /* loop counter */
- int nextleft, nextright; /* indices to second endpoints */
- DDXPointPtr ptsOut, FirstPoint; /* output buffer */
- int *width, *FirstWidth; /* output buffer */
- int imin; /* index of smallest vertex (in y) */
- int ymin; /* y-extents of polygon */
- int ymax;
-
- /*
- * find leftx, bottomy, rightx, topy, and the index
- * of bottomy. Also translate the points.
- */
- imin = getPolyYBounds(ptsIn, count, &ymin, &ymax);
-
- dy = ymax - ymin + 1;
- if ((count < 3) || (dy < 0))
- return TRUE;
- ptsOut = FirstPoint = malloc(sizeof(DDXPointRec)*dy);
- width = FirstWidth = malloc(sizeof(int) * dy);
- if(!FirstPoint || !FirstWidth)
- {
- free(FirstWidth);
- free(FirstPoint);
- return FALSE;
- }
-
- nextleft = nextright = imin;
- y = ptsIn[nextleft].y;
-
- /*
- * loop through all edges of the polygon
- */
- do {
- /*
- * add a left edge if we need to
- */
- if (ptsIn[nextleft].y == y) {
- left = nextleft;
-
- /*
- * find the next edge, considering the end
- * conditions of the array.
- */
- nextleft++;
- if (nextleft >= count)
- nextleft = 0;
-
- /*
- * now compute all of the random information
- * needed to run the iterative algorithm.
- */
- BRESINITPGON(ptsIn[nextleft].y-ptsIn[left].y,
- ptsIn[left].x,ptsIn[nextleft].x,
- xl, dl, ml, m1l, incr1l, incr2l);
- }
-
- /*
- * add a right edge if we need to
- */
- if (ptsIn[nextright].y == y) {
- right = nextright;
-
- /*
- * find the next edge, considering the end
- * conditions of the array.
- */
- nextright--;
- if (nextright < 0)
- nextright = count-1;
-
- /*
- * now compute all of the random information
- * needed to run the iterative algorithm.
- */
- BRESINITPGON(ptsIn[nextright].y-ptsIn[right].y,
- ptsIn[right].x,ptsIn[nextright].x,
- xr, dr, mr, m1r, incr1r, incr2r);
- }
-
- /*
- * generate scans to fill while we still have
- * a right edge as well as a left edge.
- */
- i = min(ptsIn[nextleft].y, ptsIn[nextright].y) - y;
- /* in case we're called with non-convex polygon */
- if(i < 0)
- {
- free(FirstWidth);
- free(FirstPoint);
- return TRUE;
- }
- while (i-- > 0)
- {
- ptsOut->y = y;
-
- /*
- * reverse the edges if necessary
- */
- if (xl < xr)
- {
- *(width++) = xr - xl;
- (ptsOut++)->x = xl;
- }
- else
- {
- *(width++) = xl - xr;
- (ptsOut++)->x = xr;
- }
- y++;
-
- /* increment down the edges */
- BRESINCRPGON(dl, xl, ml, m1l, incr1l, incr2l);
- BRESINCRPGON(dr, xr, mr, m1r, incr1r, incr2r);
- }
- } while (y != ymax);
-
- /*
- * Finally, fill the <remaining> spans
- */
- (*pgc->ops->FillSpans)(dst, pgc,
- ptsOut-FirstPoint,FirstPoint,FirstWidth,
- 1);
- free(FirstWidth);
- free(FirstPoint);
- return TRUE;
-}
-
-
-/*
- * Find the index of the point with the smallest y.
- */
-static int
-getPolyYBounds(DDXPointPtr pts, int n, int *by, int *ty)
-{
- DDXPointPtr ptMin;
- int ymin, ymax;
- DDXPointPtr ptsStart = pts;
-
- ptMin = pts;
- ymin = ymax = (pts++)->y;
-
- while (--n > 0) {
- if (pts->y < ymin)
- {
- ptMin = pts;
- ymin = pts->y;
- }
- if(pts->y > ymax)
- ymax = pts->y;
-
- pts++;
- }
-
- *by = ymin;
- *ty = ymax;
- return ptMin-ptsStart;
-}
+/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "gcstruct.h" +#include "pixmap.h" +#include "mi.h" +#include "miscanfill.h" + +static int getPolyYBounds(DDXPointPtr pts, int n, int *by, int *ty); + +/* + * convexpoly.c + * + * Written by Brian Kelleher; Dec. 1985. + * + * Fill a convex polygon. If the given polygon + * is not convex, then the result is undefined. + * The algorithm is to order the edges from smallest + * y to largest by partitioning the array into a left + * edge list and a right edge list. The algorithm used + * to traverse each edge is an extension of Bresenham's + * line algorithm with y as the major axis. + * For a derivation of the algorithm, see the author of + * this code. + */ +Bool +miFillConvexPoly(DrawablePtr dst, GCPtr pgc, int count, /* number of points */ + DDXPointPtr ptsIn /* the points */ + ) +{ + int xl = 0, xr = 0; /* x vals of left and right edges */ + int dl = 0, dr = 0; /* decision variables */ + int ml = 0, m1l = 0; /* left edge slope and slope+1 */ + int mr = 0, m1r = 0; /* right edge slope and slope+1 */ + int incr1l = 0, incr2l = 0; /* left edge error increments */ + int incr1r = 0, incr2r = 0; /* right edge error increments */ + int dy; /* delta y */ + int y; /* current scanline */ + int left, right; /* indices to first endpoints */ + int i; /* loop counter */ + int nextleft, nextright; /* indices to second endpoints */ + DDXPointPtr ptsOut, FirstPoint; /* output buffer */ + int *width, *FirstWidth; /* output buffer */ + int imin; /* index of smallest vertex (in y) */ + int ymin; /* y-extents of polygon */ + int ymax; + + /* + * find leftx, bottomy, rightx, topy, and the index + * of bottomy. Also translate the points. + */ + imin = getPolyYBounds(ptsIn, count, &ymin, &ymax); + + dy = ymax - ymin + 1; + if ((count < 3) || (dy < 0)) + return TRUE; + ptsOut = FirstPoint = malloc(sizeof(DDXPointRec) * dy); + width = FirstWidth = malloc(sizeof(int) * dy); + if (!FirstPoint || !FirstWidth) { + free(FirstWidth); + free(FirstPoint); + return FALSE; + } + + nextleft = nextright = imin; + y = ptsIn[nextleft].y; + + /* + * loop through all edges of the polygon + */ + do { + /* + * add a left edge if we need to + */ + if (ptsIn[nextleft].y == y) { + left = nextleft; + + /* + * find the next edge, considering the end + * conditions of the array. + */ + nextleft++; + if (nextleft >= count) + nextleft = 0; + + /* + * now compute all of the random information + * needed to run the iterative algorithm. + */ + BRESINITPGON(ptsIn[nextleft].y - ptsIn[left].y, + ptsIn[left].x, ptsIn[nextleft].x, + xl, dl, ml, m1l, incr1l, incr2l); + } + + /* + * add a right edge if we need to + */ + if (ptsIn[nextright].y == y) { + right = nextright; + + /* + * find the next edge, considering the end + * conditions of the array. + */ + nextright--; + if (nextright < 0) + nextright = count - 1; + + /* + * now compute all of the random information + * needed to run the iterative algorithm. + */ + BRESINITPGON(ptsIn[nextright].y - ptsIn[right].y, + ptsIn[right].x, ptsIn[nextright].x, + xr, dr, mr, m1r, incr1r, incr2r); + } + + /* + * generate scans to fill while we still have + * a right edge as well as a left edge. + */ + i = min(ptsIn[nextleft].y, ptsIn[nextright].y) - y; + /* in case we're called with non-convex polygon */ + if (i < 0) { + free(FirstWidth); + free(FirstPoint); + return TRUE; + } + while (i-- > 0) { + ptsOut->y = y; + + /* + * reverse the edges if necessary + */ + if (xl < xr) { + *(width++) = xr - xl; + (ptsOut++)->x = xl; + } + else { + *(width++) = xl - xr; + (ptsOut++)->x = xr; + } + y++; + + /* increment down the edges */ + BRESINCRPGON(dl, xl, ml, m1l, incr1l, incr2l); + BRESINCRPGON(dr, xr, mr, m1r, incr1r, incr2r); + } + } while (y != ymax); + + /* + * Finally, fill the <remaining> spans + */ + (*pgc->ops->FillSpans) (dst, pgc, + ptsOut - FirstPoint, FirstPoint, FirstWidth, 1); + free(FirstWidth); + free(FirstPoint); + return TRUE; +} + +/* + * Find the index of the point with the smallest y. + */ +static int +getPolyYBounds(DDXPointPtr pts, int n, int *by, int *ty) +{ + DDXPointPtr ptMin; + int ymin, ymax; + DDXPointPtr ptsStart = pts; + + ptMin = pts; + ymin = ymax = (pts++)->y; + + while (--n > 0) { + if (pts->y < ymin) { + ptMin = pts; + ymin = pts->y; + } + if (pts->y > ymax) + ymax = pts->y; + + pts++; + } + + *by = ymin; + *ty = ymax; + return ptMin - ptsStart; +} diff --git a/xorg-server/mi/mipolygen.c b/xorg-server/mi/mipolygen.c index ce65ca370..2031b42b7 100644 --- a/xorg-server/mi/mipolygen.c +++ b/xorg-server/mi/mipolygen.c @@ -1,230 +1,213 @@ -/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include "gcstruct.h"
-#include "miscanfill.h"
-#include "mipoly.h"
-#include "pixmap.h"
-#include "mi.h"
-
-/*
- *
- * Written by Brian Kelleher; Oct. 1985
- *
- * Routine to fill a polygon. Two fill rules are
- * supported: frWINDING and frEVENODD.
- *
- * See fillpoly.h for a complete description of the algorithm.
- */
-
-Bool
-miFillGeneralPoly(
- DrawablePtr dst,
- GCPtr pgc,
- int count, /* number of points */
- DDXPointPtr ptsIn /* the points */
- )
-{
- EdgeTableEntry *pAET; /* the Active Edge Table */
- int y; /* the current scanline */
- int nPts = 0; /* number of pts in buffer */
- EdgeTableEntry *pWETE; /* Winding Edge Table */
- ScanLineList *pSLL; /* Current ScanLineList */
- DDXPointPtr ptsOut; /* ptr to output buffers */
- int *width;
- DDXPointRec FirstPoint[NUMPTSTOBUFFER]; /* the output buffers */
- int FirstWidth[NUMPTSTOBUFFER];
- EdgeTableEntry *pPrevAET; /* previous AET entry */
- EdgeTable ET; /* Edge Table header node */
- EdgeTableEntry AET; /* Active ET header node */
- EdgeTableEntry *pETEs; /* Edge Table Entries buff */
- ScanLineListBlock SLLBlock; /* header for ScanLineList */
- int fixWAET = 0;
-
- if (count < 3)
- return TRUE;
-
- if(!(pETEs = malloc(sizeof(EdgeTableEntry) * count)))
- return FALSE;
- ptsOut = FirstPoint;
- width = FirstWidth;
- if (!miCreateETandAET(count, ptsIn, &ET, &AET, pETEs, &SLLBlock))
- {
- free(pETEs);
- return FALSE;
- }
- pSLL = ET.scanlines.next;
-
- if (pgc->fillRule == EvenOddRule)
- {
- /*
- * for each scanline
- */
- for (y = ET.ymin; y < ET.ymax; y++)
- {
- /*
- * Add a new edge to the active edge table when we
- * get to the next edge.
- */
- if (pSLL && y == pSLL->scanline)
- {
- miloadAET(&AET, pSLL->edgelist);
- pSLL = pSLL->next;
- }
- pPrevAET = &AET;
- pAET = AET.next;
-
- /*
- * for each active edge
- */
- while (pAET)
- {
- ptsOut->x = pAET->bres.minor;
- ptsOut++->y = y;
- *width++ = pAET->next->bres.minor - pAET->bres.minor;
- nPts++;
-
- /*
- * send out the buffer when its full
- */
- if (nPts == NUMPTSTOBUFFER)
- {
- (*pgc->ops->FillSpans)(dst, pgc,
- nPts, FirstPoint, FirstWidth,
- 1);
- ptsOut = FirstPoint;
- width = FirstWidth;
- nPts = 0;
- }
- EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
- EVALUATEEDGEEVENODD(pAET, pPrevAET, y);
- }
- miInsertionSort(&AET);
- }
- }
- else /* default to WindingNumber */
- {
- /*
- * for each scanline
- */
- for (y = ET.ymin; y < ET.ymax; y++)
- {
- /*
- * Add a new edge to the active edge table when we
- * get to the next edge.
- */
- if (pSLL && y == pSLL->scanline)
- {
- miloadAET(&AET, pSLL->edgelist);
- micomputeWAET(&AET);
- pSLL = pSLL->next;
- }
- pPrevAET = &AET;
- pAET = AET.next;
- pWETE = pAET;
-
- /*
- * for each active edge
- */
- while (pAET)
- {
- /*
- * if the next edge in the active edge table is
- * also the next edge in the winding active edge
- * table.
- */
- if (pWETE == pAET)
- {
- ptsOut->x = pAET->bres.minor;
- ptsOut++->y = y;
- *width++ = pAET->nextWETE->bres.minor - pAET->bres.minor;
- nPts++;
-
- /*
- * send out the buffer
- */
- if (nPts == NUMPTSTOBUFFER)
- {
- (*pgc->ops->FillSpans)(dst, pgc, nPts, FirstPoint,
- FirstWidth, 1);
- ptsOut = FirstPoint;
- width = FirstWidth;
- nPts = 0;
- }
-
- pWETE = pWETE->nextWETE;
- while (pWETE != pAET)
- EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
- pWETE = pWETE->nextWETE;
- }
- EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
- }
-
- /*
- * reevaluate the Winding active edge table if we
- * just had to resort it or if we just exited an edge.
- */
- if (miInsertionSort(&AET) || fixWAET)
- {
- micomputeWAET(&AET);
- fixWAET = 0;
- }
- }
- }
-
- /*
- * Get any spans that we missed by buffering
- */
- (*pgc->ops->FillSpans)(dst, pgc, nPts, FirstPoint, FirstWidth, 1);
- free(pETEs);
- miFreeStorage(SLLBlock.next);
- return TRUE;
-}
+/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include "gcstruct.h" +#include "miscanfill.h" +#include "mipoly.h" +#include "pixmap.h" +#include "mi.h" + +/* + * + * Written by Brian Kelleher; Oct. 1985 + * + * Routine to fill a polygon. Two fill rules are + * supported: frWINDING and frEVENODD. + * + * See fillpoly.h for a complete description of the algorithm. + */ + +Bool +miFillGeneralPoly(DrawablePtr dst, GCPtr pgc, int count, /* number of points */ + DDXPointPtr ptsIn /* the points */ + ) +{ + EdgeTableEntry *pAET; /* the Active Edge Table */ + int y; /* the current scanline */ + int nPts = 0; /* number of pts in buffer */ + EdgeTableEntry *pWETE; /* Winding Edge Table */ + ScanLineList *pSLL; /* Current ScanLineList */ + DDXPointPtr ptsOut; /* ptr to output buffers */ + int *width; + DDXPointRec FirstPoint[NUMPTSTOBUFFER]; /* the output buffers */ + int FirstWidth[NUMPTSTOBUFFER]; + EdgeTableEntry *pPrevAET; /* previous AET entry */ + EdgeTable ET; /* Edge Table header node */ + EdgeTableEntry AET; /* Active ET header node */ + EdgeTableEntry *pETEs; /* Edge Table Entries buff */ + ScanLineListBlock SLLBlock; /* header for ScanLineList */ + int fixWAET = 0; + + if (count < 3) + return TRUE; + + if (!(pETEs = malloc(sizeof(EdgeTableEntry) * count))) + return FALSE; + ptsOut = FirstPoint; + width = FirstWidth; + if (!miCreateETandAET(count, ptsIn, &ET, &AET, pETEs, &SLLBlock)) { + free(pETEs); + return FALSE; + } + pSLL = ET.scanlines.next; + + if (pgc->fillRule == EvenOddRule) { + /* + * for each scanline + */ + for (y = ET.ymin; y < ET.ymax; y++) { + /* + * Add a new edge to the active edge table when we + * get to the next edge. + */ + if (pSLL && y == pSLL->scanline) { + miloadAET(&AET, pSLL->edgelist); + pSLL = pSLL->next; + } + pPrevAET = &AET; + pAET = AET.next; + + /* + * for each active edge + */ + while (pAET) { + ptsOut->x = pAET->bres.minor; + ptsOut++->y = y; + *width++ = pAET->next->bres.minor - pAET->bres.minor; + nPts++; + + /* + * send out the buffer when its full + */ + if (nPts == NUMPTSTOBUFFER) { + (*pgc->ops->FillSpans) (dst, pgc, + nPts, FirstPoint, FirstWidth, 1); + ptsOut = FirstPoint; + width = FirstWidth; + nPts = 0; + } + EVALUATEEDGEEVENODD(pAET, pPrevAET, y) + EVALUATEEDGEEVENODD(pAET, pPrevAET, y); + } + miInsertionSort(&AET); + } + } + else { /* default to WindingNumber */ + + /* + * for each scanline + */ + for (y = ET.ymin; y < ET.ymax; y++) { + /* + * Add a new edge to the active edge table when we + * get to the next edge. + */ + if (pSLL && y == pSLL->scanline) { + miloadAET(&AET, pSLL->edgelist); + micomputeWAET(&AET); + pSLL = pSLL->next; + } + pPrevAET = &AET; + pAET = AET.next; + pWETE = pAET; + + /* + * for each active edge + */ + while (pAET) { + /* + * if the next edge in the active edge table is + * also the next edge in the winding active edge + * table. + */ + if (pWETE == pAET) { + ptsOut->x = pAET->bres.minor; + ptsOut++->y = y; + *width++ = pAET->nextWETE->bres.minor - pAET->bres.minor; + nPts++; + + /* + * send out the buffer + */ + if (nPts == NUMPTSTOBUFFER) { + (*pgc->ops->FillSpans) (dst, pgc, nPts, FirstPoint, + FirstWidth, 1); + ptsOut = FirstPoint; + width = FirstWidth; + nPts = 0; + } + + pWETE = pWETE->nextWETE; + while (pWETE != pAET) + EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET); + pWETE = pWETE->nextWETE; + } + EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET); + } + + /* + * reevaluate the Winding active edge table if we + * just had to resort it or if we just exited an edge. + */ + if (miInsertionSort(&AET) || fixWAET) { + micomputeWAET(&AET); + fixWAET = 0; + } + } + } + + /* + * Get any spans that we missed by buffering + */ + (*pgc->ops->FillSpans) (dst, pgc, nPts, FirstPoint, FirstWidth, 1); + free(pETEs); + miFreeStorage(SLLBlock.next); + return TRUE; +} diff --git a/xorg-server/mi/mipolypnt.c b/xorg-server/mi/mipolypnt.c index 29d3e29e1..086502b26 100644 --- a/xorg-server/mi/mipolypnt.c +++ b/xorg-server/mi/mipolypnt.c @@ -1,125 +1,112 @@ -/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xprotostr.h>
-#include "pixmapstr.h"
-#include "gcstruct.h"
-#include "windowstr.h"
-#include "mi.h"
-
-void
-miPolyPoint(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int mode, /* Origin or Previous */
- int npt,
- xPoint *pptInit
- )
-{
-
- int xorg;
- int yorg;
- int nptTmp;
- ChangeGCVal fsOld, fsNew;
- int *pwidthInit, *pwidth;
- int i;
- xPoint *ppt;
-
- if(!(pwidthInit = malloc(npt * sizeof(int))))
- return;
-
- /* make pointlist origin relative */
- if (mode == CoordModePrevious)
- {
- ppt = pptInit;
- nptTmp = npt;
- nptTmp--;
- while(nptTmp--)
- {
- ppt++;
- ppt->x += (ppt-1)->x;
- ppt->y += (ppt-1)->y;
- }
- }
-
- if(pGC->miTranslate)
- {
- ppt = pptInit;
- nptTmp = npt;
- xorg = pDrawable->x;
- yorg = pDrawable->y;
- while(nptTmp--)
- {
- ppt->x += xorg;
- ppt++->y += yorg;
- }
- }
-
- fsOld.val = pGC->fillStyle;
- fsNew.val = FillSolid;
- if(pGC->fillStyle != FillSolid)
- {
- ChangeGC(NullClient, pGC, GCFillStyle, &fsNew);
- ValidateGC(pDrawable, pGC);
- }
- pwidth = pwidthInit;
- for(i = 0; i < npt; i++)
- *pwidth++ = 1;
- (*pGC->ops->FillSpans)(pDrawable, pGC, npt, pptInit, pwidthInit, FALSE);
-
- if(fsOld.val != FillSolid)
- {
- ChangeGC(NullClient, pGC, GCFillStyle, &fsOld);
- ValidateGC(pDrawable, pGC);
- }
- free(pwidthInit);
-}
-
+/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xprotostr.h> +#include "pixmapstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "mi.h" + +void +miPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, /* Origin or Previous */ + int npt, xPoint * pptInit) +{ + + int xorg; + int yorg; + int nptTmp; + ChangeGCVal fsOld, fsNew; + int *pwidthInit, *pwidth; + int i; + xPoint *ppt; + + if (!(pwidthInit = malloc(npt * sizeof(int)))) + return; + + /* make pointlist origin relative */ + if (mode == CoordModePrevious) { + ppt = pptInit; + nptTmp = npt; + nptTmp--; + while (nptTmp--) { + ppt++; + ppt->x += (ppt - 1)->x; + ppt->y += (ppt - 1)->y; + } + } + + if (pGC->miTranslate) { + ppt = pptInit; + nptTmp = npt; + xorg = pDrawable->x; + yorg = pDrawable->y; + while (nptTmp--) { + ppt->x += xorg; + ppt++->y += yorg; + } + } + + fsOld.val = pGC->fillStyle; + fsNew.val = FillSolid; + if (pGC->fillStyle != FillSolid) { + ChangeGC(NullClient, pGC, GCFillStyle, &fsNew); + ValidateGC(pDrawable, pGC); + } + pwidth = pwidthInit; + for (i = 0; i < npt; i++) + *pwidth++ = 1; + (*pGC->ops->FillSpans) (pDrawable, pGC, npt, pptInit, pwidthInit, FALSE); + + if (fsOld.val != FillSolid) { + ChangeGC(NullClient, pGC, GCFillStyle, &fsOld); + ValidateGC(pDrawable, pGC); + } + free(pwidthInit); +} diff --git a/xorg-server/mi/mipolyrect.c b/xorg-server/mi/mipolyrect.c index 8b8810793..a0e88d2f2 100644 --- a/xorg-server/mi/mipolyrect.c +++ b/xorg-server/mi/mipolyrect.c @@ -1,187 +1,175 @@ -/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xprotostr.h>
-#include "regionstr.h"
-#include "gcstruct.h"
-#include "pixmap.h"
-#include "mi.h"
-
-void
-miPolyRectangle(DrawablePtr pDraw, GCPtr pGC, int nrects, xRectangle *pRects)
-{
- int i;
- xRectangle *pR = pRects;
- DDXPointRec rect[5];
- int bound_tmp;
-
-#define MINBOUND(dst,eqn) bound_tmp = eqn; \
- if (bound_tmp < -32768) \
- bound_tmp = -32768; \
- dst = bound_tmp;
-
-#define MAXBOUND(dst,eqn) bound_tmp = eqn; \
- if (bound_tmp > 32767) \
- bound_tmp = 32767; \
- dst = bound_tmp;
-
-#define MAXUBOUND(dst,eqn) bound_tmp = eqn; \
- if (bound_tmp > 65535) \
- bound_tmp = 65535; \
- dst = bound_tmp;
-
- if (pGC->lineStyle == LineSolid && pGC->joinStyle == JoinMiter &&
- pGC->lineWidth != 0)
- {
- xRectangle *tmp, *t;
- int ntmp;
- int offset1, offset2, offset3;
- int x, y, width, height;
-
- ntmp = (nrects << 2);
- offset2 = pGC->lineWidth;
- offset1 = offset2 >> 1;
- offset3 = offset2 - offset1;
- tmp = malloc(ntmp * sizeof (xRectangle));
- if (!tmp)
- return;
- t = tmp;
- for (i = 0; i < nrects; i++)
- {
- x = pR->x;
- y = pR->y;
- width = pR->width;
- height = pR->height;
- pR++;
- if (width == 0 && height == 0)
- {
- rect[0].x = x;
- rect[0].y = y;
- rect[1].x = x;
- rect[1].y = y;
- (*pGC->ops->Polylines)(pDraw, pGC, CoordModeOrigin, 2, rect);
- }
- else if (height < offset2 || width < offset1)
- {
- if (height == 0)
- {
- t->x = x;
- t->width = width;
- }
- else
- {
- MINBOUND (t->x, x - offset1)
- MAXUBOUND (t->width, width + offset2)
- }
- if (width == 0)
- {
- t->y = y;
- t->height = height;
- }
- else
- {
- MINBOUND (t->y, y - offset1)
- MAXUBOUND (t->height, height + offset2)
- }
- t++;
- }
- else
- {
- MINBOUND(t->x, x - offset1)
- MINBOUND(t->y, y - offset1)
- MAXUBOUND(t->width, width + offset2)
- t->height = offset2;
- t++;
- MINBOUND(t->x, x - offset1)
- MAXBOUND(t->y, y + offset3);
- t->width = offset2;
- t->height = height - offset2;
- t++;
- MAXBOUND(t->x, x + width - offset1);
- MAXBOUND(t->y, y + offset3)
- t->width = offset2;
- t->height = height - offset2;
- t++;
- MINBOUND(t->x, x - offset1)
- MAXBOUND(t->y, y + height - offset1)
- MAXUBOUND(t->width, width + offset2)
- t->height = offset2;
- t++;
- }
- }
- (*pGC->ops->PolyFillRect) (pDraw, pGC, t - tmp, tmp);
- free((pointer) tmp);
- }
- else
- {
-
- for (i=0; i<nrects; i++)
- {
- rect[0].x = pR->x;
- rect[0].y = pR->y;
-
- MAXBOUND(rect[1].x, pR->x + (int) pR->width)
- rect[1].y = rect[0].y;
-
- rect[2].x = rect[1].x;
- MAXBOUND(rect[2].y, pR->y + (int) pR->height);
-
- rect[3].x = rect[0].x;
- rect[3].y = rect[2].y;
-
- rect[4].x = rect[0].x;
- rect[4].y = rect[0].y;
-
- (*pGC->ops->Polylines)(pDraw, pGC, CoordModeOrigin, 5, rect);
- pR++;
- }
- }
-}
+/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xprotostr.h> +#include "regionstr.h" +#include "gcstruct.h" +#include "pixmap.h" +#include "mi.h" + +void +miPolyRectangle(DrawablePtr pDraw, GCPtr pGC, int nrects, xRectangle *pRects) +{ + int i; + xRectangle *pR = pRects; + DDXPointRec rect[5]; + int bound_tmp; + +#define MINBOUND(dst,eqn) bound_tmp = eqn; \ + if (bound_tmp < -32768) \ + bound_tmp = -32768; \ + dst = bound_tmp; + +#define MAXBOUND(dst,eqn) bound_tmp = eqn; \ + if (bound_tmp > 32767) \ + bound_tmp = 32767; \ + dst = bound_tmp; + +#define MAXUBOUND(dst,eqn) bound_tmp = eqn; \ + if (bound_tmp > 65535) \ + bound_tmp = 65535; \ + dst = bound_tmp; + + if (pGC->lineStyle == LineSolid && pGC->joinStyle == JoinMiter && + pGC->lineWidth != 0) { + xRectangle *tmp, *t; + int ntmp; + int offset1, offset2, offset3; + int x, y, width, height; + + ntmp = (nrects << 2); + offset2 = pGC->lineWidth; + offset1 = offset2 >> 1; + offset3 = offset2 - offset1; + tmp = malloc(ntmp * sizeof(xRectangle)); + if (!tmp) + return; + t = tmp; + for (i = 0; i < nrects; i++) { + x = pR->x; + y = pR->y; + width = pR->width; + height = pR->height; + pR++; + if (width == 0 && height == 0) { + rect[0].x = x; + rect[0].y = y; + rect[1].x = x; + rect[1].y = y; + (*pGC->ops->Polylines) (pDraw, pGC, CoordModeOrigin, 2, rect); + } + else if (height < offset2 || width < offset1) { + if (height == 0) { + t->x = x; + t->width = width; + } + else { + MINBOUND(t->x, x - offset1) + MAXUBOUND(t->width, width + offset2) + } + if (width == 0) { + t->y = y; + t->height = height; + } + else { + MINBOUND(t->y, y - offset1) + MAXUBOUND(t->height, height + offset2) + } + t++; + } + else { + MINBOUND(t->x, x - offset1) + MINBOUND(t->y, y - offset1) + MAXUBOUND(t->width, width + offset2) + t->height = offset2; + t++; + MINBOUND(t->x, x - offset1) + MAXBOUND(t->y, y + offset3); + t->width = offset2; + t->height = height - offset2; + t++; + MAXBOUND(t->x, x + width - offset1); + MAXBOUND(t->y, y + offset3) + t->width = offset2; + t->height = height - offset2; + t++; + MINBOUND(t->x, x - offset1) + MAXBOUND(t->y, y + height - offset1) + MAXUBOUND(t->width, width + offset2) + t->height = offset2; + t++; + } + } + (*pGC->ops->PolyFillRect) (pDraw, pGC, t - tmp, tmp); + free((pointer) tmp); + } + else { + + for (i = 0; i < nrects; i++) { + rect[0].x = pR->x; + rect[0].y = pR->y; + + MAXBOUND(rect[1].x, pR->x + (int) pR->width) + rect[1].y = rect[0].y; + + rect[2].x = rect[1].x; + MAXBOUND(rect[2].y, pR->y + (int) pR->height); + + rect[3].x = rect[0].x; + rect[3].y = rect[2].y; + + rect[4].x = rect[0].x; + rect[4].y = rect[0].y; + + (*pGC->ops->Polylines) (pDraw, pGC, CoordModeOrigin, 5, rect); + pR++; + } + } +} diff --git a/xorg-server/mi/mipolyseg.c b/xorg-server/mi/mipolyseg.c index bf7f0f92e..d6f18076c 100644 --- a/xorg-server/mi/mipolyseg.c +++ b/xorg-server/mi/mipolyseg.c @@ -22,7 +22,6 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved @@ -65,15 +64,14 @@ SOFTWARE. * *****************************************************************/ - void -miPolySegment(DrawablePtr pDraw, GCPtr pGC, int nseg, xSegment *pSegs) +miPolySegment(DrawablePtr pDraw, GCPtr pGC, int nseg, xSegment * pSegs) { int i; - for (i=0; i<nseg; i++) - { - (*pGC->ops->Polylines)(pDraw, pGC, CoordModeOrigin, 2,(DDXPointPtr)pSegs); - pSegs++; + for (i = 0; i < nseg; i++) { + (*pGC->ops->Polylines) (pDraw, pGC, CoordModeOrigin, 2, + (DDXPointPtr) pSegs); + pSegs++; } } diff --git a/xorg-server/mi/mipolytext.c b/xorg-server/mi/mipolytext.c index 508e0ffa7..02c45882f 100644 --- a/xorg-server/mi/mipolytext.c +++ b/xorg-server/mi/mipolytext.c @@ -22,7 +22,6 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved @@ -71,34 +70,37 @@ miPolyText8(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count, char *chars) { unsigned long n, i; int w; - CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */ + CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */ - GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars, - Linear8Bit, &n, charinfo); + GetGlyphs(pGC->font, (unsigned long) count, (unsigned char *) chars, + Linear8Bit, &n, charinfo); w = 0; - for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth; + for (i = 0; i < n; i++) + w += charinfo[i]->metrics.characterWidth; if (n != 0) - (*pGC->ops->PolyGlyphBlt)( - pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font)); - return x+w; + (*pGC->ops->PolyGlyphBlt) (pDraw, pGC, x, y, n, charinfo, + FONTGLYPHS(pGC->font)); + return x + w; } int -miPolyText16(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count, unsigned short *chars) +miPolyText16(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count, + unsigned short *chars) { unsigned long n, i; int w; - CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */ + CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */ - GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars, - (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit, - &n, charinfo); + GetGlyphs(pGC->font, (unsigned long) count, (unsigned char *) chars, + (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit, + &n, charinfo); w = 0; - for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth; + for (i = 0; i < n; i++) + w += charinfo[i]->metrics.characterWidth; if (n != 0) - (*pGC->ops->PolyGlyphBlt)( - pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font)); - return x+w; + (*pGC->ops->PolyGlyphBlt) (pDraw, pGC, x, y, n, charinfo, + FONTGLYPHS(pGC->font)); + return x + w; } void @@ -106,25 +108,27 @@ miImageText8(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count, char *chars) { unsigned long n; FontPtr font = pGC->font; - CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */ + CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */ - GetGlyphs(font, (unsigned long)count, (unsigned char *)chars, - Linear8Bit, &n, charinfo); - if (n !=0 ) - (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(font)); + GetGlyphs(font, (unsigned long) count, (unsigned char *) chars, + Linear8Bit, &n, charinfo); + if (n != 0) + (*pGC->ops->ImageGlyphBlt) (pDraw, pGC, x, y, n, charinfo, + FONTGLYPHS(font)); } void miImageText16(DrawablePtr pDraw, GCPtr pGC, int x, int y, - int count, unsigned short *chars) + int count, unsigned short *chars) { unsigned long n; FontPtr font = pGC->font; - CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */ + CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */ - GetGlyphs(font, (unsigned long)count, (unsigned char *)chars, - (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit, - &n, charinfo); - if (n !=0 ) - (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(font)); + GetGlyphs(font, (unsigned long) count, (unsigned char *) chars, + (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit, + &n, charinfo); + if (n != 0) + (*pGC->ops->ImageGlyphBlt) (pDraw, pGC, x, y, n, charinfo, + FONTGLYPHS(font)); } diff --git a/xorg-server/mi/mipolyutil.c b/xorg-server/mi/mipolyutil.c index e17fb52e4..5e6301d43 100644 --- a/xorg-server/mi/mipolyutil.c +++ b/xorg-server/mi/mipolyutil.c @@ -1,385 +1,369 @@ -/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "regionstr.h"
-#include "gc.h"
-#include "miscanfill.h"
-#include "mipoly.h"
-#include "misc.h" /* MAXINT */
-
-/*
- * fillUtils.c
- *
- * Written by Brian Kelleher; Oct. 1985
- *
- * This module contains all of the utility functions
- * needed to scan convert a polygon.
- *
- */
-
-/*
- * InsertEdgeInET
- *
- * Insert the given edge into the edge table.
- * First we must find the correct bucket in the
- * Edge table, then find the right slot in the
- * bucket. Finally, we can insert it.
- *
- */
-static Bool
-miInsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE, int scanline,
- ScanLineListBlock **SLLBlock, int *iSLLBlock)
-{
- EdgeTableEntry *start, *prev;
- ScanLineList *pSLL, *pPrevSLL;
- ScanLineListBlock *tmpSLLBlock;
-
- /*
- * find the right bucket to put the edge into
- */
- pPrevSLL = &ET->scanlines;
- pSLL = pPrevSLL->next;
- while (pSLL && (pSLL->scanline < scanline))
- {
- pPrevSLL = pSLL;
- pSLL = pSLL->next;
- }
-
- /*
- * reassign pSLL (pointer to ScanLineList) if necessary
- */
- if ((!pSLL) || (pSLL->scanline > scanline))
- {
- if (*iSLLBlock > SLLSPERBLOCK-1)
- {
- tmpSLLBlock = malloc(sizeof(ScanLineListBlock));
- if (!tmpSLLBlock)
- return FALSE;
- (*SLLBlock)->next = tmpSLLBlock;
- tmpSLLBlock->next = NULL;
- *SLLBlock = tmpSLLBlock;
- *iSLLBlock = 0;
- }
- pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
-
- pSLL->next = pPrevSLL->next;
- pSLL->edgelist = NULL;
- pPrevSLL->next = pSLL;
- }
- pSLL->scanline = scanline;
-
- /*
- * now insert the edge in the right bucket
- */
- prev = NULL;
- start = pSLL->edgelist;
- while (start && (start->bres.minor < ETE->bres.minor))
- {
- prev = start;
- start = start->next;
- }
- ETE->next = start;
-
- if (prev)
- prev->next = ETE;
- else
- pSLL->edgelist = ETE;
- return TRUE;
-}
-
-/*
- * CreateEdgeTable
- *
- * This routine creates the edge table for
- * scan converting polygons.
- * The Edge Table (ET) looks like:
- *
- * EdgeTable
- * --------
- * | ymax | ScanLineLists
- * |scanline|-->------------>-------------->...
- * -------- |scanline| |scanline|
- * |edgelist| |edgelist|
- * --------- ---------
- * | |
- * | |
- * V V
- * list of ETEs list of ETEs
- *
- * where ETE is an EdgeTableEntry data structure,
- * and there is one ScanLineList per scanline at
- * which an edge is initially entered.
- *
- */
-
-Bool
-miCreateETandAET(int count, DDXPointPtr pts, EdgeTable *ET, EdgeTableEntry *AET,
- EdgeTableEntry *pETEs, ScanLineListBlock *pSLLBlock)
-{
- DDXPointPtr top, bottom;
- DDXPointPtr PrevPt, CurrPt;
- int iSLLBlock = 0;
-
- int dy;
-
- if (count < 2) return TRUE;
-
- /*
- * initialize the Active Edge Table
- */
- AET->next = NULL;
- AET->back = NULL;
- AET->nextWETE = NULL;
- AET->bres.minor = MININT;
-
- /*
- * initialize the Edge Table.
- */
- ET->scanlines.next = NULL;
- ET->ymax = MININT;
- ET->ymin = MAXINT;
- pSLLBlock->next = NULL;
-
- PrevPt = &pts[count-1];
-
- /*
- * for each vertex in the array of points.
- * In this loop we are dealing with two vertices at
- * a time -- these make up one edge of the polygon.
- */
- while (count--)
- {
- CurrPt = pts++;
-
- /*
- * find out which point is above and which is below.
- */
- if (PrevPt->y > CurrPt->y)
- {
- bottom = PrevPt, top = CurrPt;
- pETEs->ClockWise = 0;
- }
- else
- {
- bottom = CurrPt, top = PrevPt;
- pETEs->ClockWise = 1;
- }
-
- /*
- * don't add horizontal edges to the Edge table.
- */
- if (bottom->y != top->y)
- {
- pETEs->ymax = bottom->y-1; /* -1 so we don't get last scanline */
-
- /*
- * initialize integer edge algorithm
- */
- dy = bottom->y - top->y;
- BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres);
-
- if (!miInsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock))
- {
- miFreeStorage(pSLLBlock->next);
- return FALSE;
- }
-
- ET->ymax = max(ET->ymax, PrevPt->y);
- ET->ymin = min(ET->ymin, PrevPt->y);
- pETEs++;
- }
-
- PrevPt = CurrPt;
- }
- return TRUE;
-}
-
-/*
- * loadAET
- *
- * This routine moves EdgeTableEntries from the
- * EdgeTable into the Active Edge Table,
- * leaving them sorted by smaller x coordinate.
- *
- */
-
-void
-miloadAET(EdgeTableEntry *AET, EdgeTableEntry *ETEs)
-{
- EdgeTableEntry *pPrevAET;
- EdgeTableEntry *tmp;
-
- pPrevAET = AET;
- AET = AET->next;
- while (ETEs)
- {
- while (AET && (AET->bres.minor < ETEs->bres.minor))
- {
- pPrevAET = AET;
- AET = AET->next;
- }
- tmp = ETEs->next;
- ETEs->next = AET;
- if (AET)
- AET->back = ETEs;
- ETEs->back = pPrevAET;
- pPrevAET->next = ETEs;
- pPrevAET = ETEs;
-
- ETEs = tmp;
- }
-}
-
-/*
- * computeWAET
- *
- * This routine links the AET by the
- * nextWETE (winding EdgeTableEntry) link for
- * use by the winding number rule. The final
- * Active Edge Table (AET) might look something
- * like:
- *
- * AET
- * ---------- --------- ---------
- * |ymax | |ymax | |ymax |
- * | ... | |... | |... |
- * |next |->|next |->|next |->...
- * |nextWETE| |nextWETE| |nextWETE|
- * --------- --------- ^--------
- * | | |
- * V-------------------> V---> ...
- *
- */
-void
-micomputeWAET(EdgeTableEntry *AET)
-{
- EdgeTableEntry *pWETE;
- int inside = 1;
- int isInside = 0;
-
- AET->nextWETE = NULL;
- pWETE = AET;
- AET = AET->next;
- while (AET)
- {
- if (AET->ClockWise)
- isInside++;
- else
- isInside--;
-
- if ((!inside && !isInside) ||
- ( inside && isInside))
- {
- pWETE->nextWETE = AET;
- pWETE = AET;
- inside = !inside;
- }
- AET = AET->next;
- }
- pWETE->nextWETE = NULL;
-}
-
-/*
- * InsertionSort
- *
- * Just a simple insertion sort using
- * pointers and back pointers to sort the Active
- * Edge Table.
- *
- */
-
-int
-miInsertionSort(EdgeTableEntry *AET)
-{
- EdgeTableEntry *pETEchase;
- EdgeTableEntry *pETEinsert;
- EdgeTableEntry *pETEchaseBackTMP;
- int changed = 0;
-
- AET = AET->next;
- while (AET)
- {
- pETEinsert = AET;
- pETEchase = AET;
- while (pETEchase->back->bres.minor > AET->bres.minor)
- pETEchase = pETEchase->back;
-
- AET = AET->next;
- if (pETEchase != pETEinsert)
- {
- pETEchaseBackTMP = pETEchase->back;
- pETEinsert->back->next = AET;
- if (AET)
- AET->back = pETEinsert->back;
- pETEinsert->next = pETEchase;
- pETEchase->back->next = pETEinsert;
- pETEchase->back = pETEinsert;
- pETEinsert->back = pETEchaseBackTMP;
- changed = 1;
- }
- }
- return changed;
-}
-
-/*
- * Clean up our act.
- */
-void
-miFreeStorage(ScanLineListBlock *pSLLBlock)
-{
- ScanLineListBlock *tmpSLLBlock;
-
- while (pSLLBlock)
- {
- tmpSLLBlock = pSLLBlock->next;
- free(pSLLBlock);
- pSLLBlock = tmpSLLBlock;
- }
-}
+/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "regionstr.h" +#include "gc.h" +#include "miscanfill.h" +#include "mipoly.h" +#include "misc.h" /* MAXINT */ + +/* + * fillUtils.c + * + * Written by Brian Kelleher; Oct. 1985 + * + * This module contains all of the utility functions + * needed to scan convert a polygon. + * + */ + +/* + * InsertEdgeInET + * + * Insert the given edge into the edge table. + * First we must find the correct bucket in the + * Edge table, then find the right slot in the + * bucket. Finally, we can insert it. + * + */ +static Bool +miInsertEdgeInET(EdgeTable * ET, EdgeTableEntry * ETE, int scanline, + ScanLineListBlock ** SLLBlock, int *iSLLBlock) +{ + EdgeTableEntry *start, *prev; + ScanLineList *pSLL, *pPrevSLL; + ScanLineListBlock *tmpSLLBlock; + + /* + * find the right bucket to put the edge into + */ + pPrevSLL = &ET->scanlines; + pSLL = pPrevSLL->next; + while (pSLL && (pSLL->scanline < scanline)) { + pPrevSLL = pSLL; + pSLL = pSLL->next; + } + + /* + * reassign pSLL (pointer to ScanLineList) if necessary + */ + if ((!pSLL) || (pSLL->scanline > scanline)) { + if (*iSLLBlock > SLLSPERBLOCK - 1) { + tmpSLLBlock = malloc(sizeof(ScanLineListBlock)); + if (!tmpSLLBlock) + return FALSE; + (*SLLBlock)->next = tmpSLLBlock; + tmpSLLBlock->next = NULL; + *SLLBlock = tmpSLLBlock; + *iSLLBlock = 0; + } + pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]); + + pSLL->next = pPrevSLL->next; + pSLL->edgelist = NULL; + pPrevSLL->next = pSLL; + } + pSLL->scanline = scanline; + + /* + * now insert the edge in the right bucket + */ + prev = NULL; + start = pSLL->edgelist; + while (start && (start->bres.minor < ETE->bres.minor)) { + prev = start; + start = start->next; + } + ETE->next = start; + + if (prev) + prev->next = ETE; + else + pSLL->edgelist = ETE; + return TRUE; +} + +/* + * CreateEdgeTable + * + * This routine creates the edge table for + * scan converting polygons. + * The Edge Table (ET) looks like: + * + * EdgeTable + * -------- + * | ymax | ScanLineLists + * |scanline|-->------------>-------------->... + * -------- |scanline| |scanline| + * |edgelist| |edgelist| + * --------- --------- + * | | + * | | + * V V + * list of ETEs list of ETEs + * + * where ETE is an EdgeTableEntry data structure, + * and there is one ScanLineList per scanline at + * which an edge is initially entered. + * + */ + +Bool +miCreateETandAET(int count, DDXPointPtr pts, EdgeTable * ET, + EdgeTableEntry * AET, EdgeTableEntry * pETEs, + ScanLineListBlock * pSLLBlock) +{ + DDXPointPtr top, bottom; + DDXPointPtr PrevPt, CurrPt; + int iSLLBlock = 0; + + int dy; + + if (count < 2) + return TRUE; + + /* + * initialize the Active Edge Table + */ + AET->next = NULL; + AET->back = NULL; + AET->nextWETE = NULL; + AET->bres.minor = MININT; + + /* + * initialize the Edge Table. + */ + ET->scanlines.next = NULL; + ET->ymax = MININT; + ET->ymin = MAXINT; + pSLLBlock->next = NULL; + + PrevPt = &pts[count - 1]; + + /* + * for each vertex in the array of points. + * In this loop we are dealing with two vertices at + * a time -- these make up one edge of the polygon. + */ + while (count--) { + CurrPt = pts++; + + /* + * find out which point is above and which is below. + */ + if (PrevPt->y > CurrPt->y) { + bottom = PrevPt, top = CurrPt; + pETEs->ClockWise = 0; + } + else { + bottom = CurrPt, top = PrevPt; + pETEs->ClockWise = 1; + } + + /* + * don't add horizontal edges to the Edge table. + */ + if (bottom->y != top->y) { + pETEs->ymax = bottom->y - 1; /* -1 so we don't get last scanline */ + + /* + * initialize integer edge algorithm + */ + dy = bottom->y - top->y; + BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres); + + if (!miInsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock)) { + miFreeStorage(pSLLBlock->next); + return FALSE; + } + + ET->ymax = max(ET->ymax, PrevPt->y); + ET->ymin = min(ET->ymin, PrevPt->y); + pETEs++; + } + + PrevPt = CurrPt; + } + return TRUE; +} + +/* + * loadAET + * + * This routine moves EdgeTableEntries from the + * EdgeTable into the Active Edge Table, + * leaving them sorted by smaller x coordinate. + * + */ + +void +miloadAET(EdgeTableEntry * AET, EdgeTableEntry * ETEs) +{ + EdgeTableEntry *pPrevAET; + EdgeTableEntry *tmp; + + pPrevAET = AET; + AET = AET->next; + while (ETEs) { + while (AET && (AET->bres.minor < ETEs->bres.minor)) { + pPrevAET = AET; + AET = AET->next; + } + tmp = ETEs->next; + ETEs->next = AET; + if (AET) + AET->back = ETEs; + ETEs->back = pPrevAET; + pPrevAET->next = ETEs; + pPrevAET = ETEs; + + ETEs = tmp; + } +} + +/* + * computeWAET + * + * This routine links the AET by the + * nextWETE (winding EdgeTableEntry) link for + * use by the winding number rule. The final + * Active Edge Table (AET) might look something + * like: + * + * AET + * ---------- --------- --------- + * |ymax | |ymax | |ymax | + * | ... | |... | |... | + * |next |->|next |->|next |->... + * |nextWETE| |nextWETE| |nextWETE| + * --------- --------- ^-------- + * | | | + * V-------------------> V---> ... + * + */ +void +micomputeWAET(EdgeTableEntry * AET) +{ + EdgeTableEntry *pWETE; + int inside = 1; + int isInside = 0; + + AET->nextWETE = NULL; + pWETE = AET; + AET = AET->next; + while (AET) { + if (AET->ClockWise) + isInside++; + else + isInside--; + + if ((!inside && !isInside) || (inside && isInside)) { + pWETE->nextWETE = AET; + pWETE = AET; + inside = !inside; + } + AET = AET->next; + } + pWETE->nextWETE = NULL; +} + +/* + * InsertionSort + * + * Just a simple insertion sort using + * pointers and back pointers to sort the Active + * Edge Table. + * + */ + +int +miInsertionSort(EdgeTableEntry * AET) +{ + EdgeTableEntry *pETEchase; + EdgeTableEntry *pETEinsert; + EdgeTableEntry *pETEchaseBackTMP; + int changed = 0; + + AET = AET->next; + while (AET) { + pETEinsert = AET; + pETEchase = AET; + while (pETEchase->back->bres.minor > AET->bres.minor) + pETEchase = pETEchase->back; + + AET = AET->next; + if (pETEchase != pETEinsert) { + pETEchaseBackTMP = pETEchase->back; + pETEinsert->back->next = AET; + if (AET) + AET->back = pETEinsert->back; + pETEinsert->next = pETEchase; + pETEchase->back->next = pETEinsert; + pETEchase->back = pETEinsert; + pETEinsert->back = pETEchaseBackTMP; + changed = 1; + } + } + return changed; +} + +/* + * Clean up our act. + */ +void +miFreeStorage(ScanLineListBlock * pSLLBlock) +{ + ScanLineListBlock *tmpSLLBlock; + + while (pSLLBlock) { + tmpSLLBlock = pSLLBlock->next; + free(pSLLBlock); + pSLLBlock = tmpSLLBlock; + } +} diff --git a/xorg-server/mi/mipushpxl.c b/xorg-server/mi/mipushpxl.c index 9c3d9b342..9a78f4050 100644 --- a/xorg-server/mi/mipushpxl.c +++ b/xorg-server/mi/mipushpxl.c @@ -1,271 +1,249 @@ -/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include "gcstruct.h"
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "regionstr.h"
-#include "mi.h"
-#include "servermd.h"
-
-#define NPT 128
-
-/* These were stolen from mfb. They don't really belong here. */
-#define LONG2CHARSSAMEORDER(x) ((MiBits)(x))
-#define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & (MiBits)0x000000FF ) << 0x18 ) \
- | ( ( ( x ) & (MiBits)0x0000FF00 ) << 0x08 ) \
- | ( ( ( x ) & (MiBits)0x00FF0000 ) >> 0x08 ) \
- | ( ( ( x ) & (MiBits)0xFF000000 ) >> 0x18 ) )
-
-
-#define PGSZB 4
-#define PPW (PGSZB<<3) /* assuming 8 bits per byte */
-#define PGSZ PPW
-#define PLST (PPW-1)
-#define PIM PLST
-#define PWSH 5
-
-/* miPushPixels -- squeegees the fill style of pGC through pBitMap
- * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may
- * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit
- * is set in the bitmap, the fill style is put onto the drawable using
- * the GC's logical function. The drawable is not changed where the bitmap
- * has a zero bit or outside the area covered by the stencil.
-
-WARNING:
- this code works if the 1-bit deep pixmap format returned by GetSpans
-is the same as the format defined by the mfb code (i.e. 32-bit padding
-per scanline, scanline unit = 32 bits; later, this might mean
-bitsizeof(int) padding and sacnline unit == bitsizeof(int).)
-
- */
-
-/*
- * in order to have both (MSB_FIRST and LSB_FIRST) versions of this
- * in the server, we need to rename one of them
- */
-void
-miPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable,
- int dx, int dy, int xOrg, int yOrg)
-{
- int h, dxDivPPW, ibEnd;
- MiBits *pwLineStart;
- MiBits *pw, *pwEnd;
- MiBits msk;
- int ib, w;
- int ipt; /* index into above arrays */
- Bool fInBox;
- DDXPointRec pt[NPT], ptThisLine;
- int width[NPT];
-#if 1
- MiBits startmask;
- if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
- if (screenInfo.bitmapBitOrder == LSBFirst)
- startmask = (MiBits)(-1) ^
- LONG2CHARSSAMEORDER((MiBits)(-1) << 1);
- else
- startmask = (MiBits)(-1) ^
- LONG2CHARSSAMEORDER((MiBits)(-1) >> 1);
- else
- if (screenInfo.bitmapBitOrder == LSBFirst)
- startmask = (MiBits)(-1) ^
- LONG2CHARSDIFFORDER((MiBits)(-1) << 1);
- else
- startmask = (MiBits)(-1) ^
- LONG2CHARSDIFFORDER((MiBits)(-1) >> 1);
-#endif
-
- pwLineStart = malloc(BitmapBytePad(dx));
- if (!pwLineStart)
- return;
- ipt = 0;
- dxDivPPW = dx/PPW;
-
- for(h = 0, ptThisLine.x = 0, ptThisLine.y = 0;
- h < dy;
- h++, ptThisLine.y++)
- {
-
- (*pBitMap->drawable.pScreen->GetSpans)((DrawablePtr)pBitMap, dx,
- &ptThisLine, &dx, 1, (char *)pwLineStart);
-
- pw = pwLineStart;
- /* Process all words which are fully in the pixmap */
-
- fInBox = FALSE;
- pwEnd = pwLineStart + dxDivPPW;
- while(pw < pwEnd)
- {
- w = *pw;
-#if 1
- msk = startmask;
-#else
- msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1);
-#endif
- for(ib = 0; ib < PPW; ib++)
- {
- if(w & msk)
- {
- if(!fInBox)
- {
- pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
- pt[ipt].y = h + yOrg;
- /* start new box */
- fInBox = TRUE;
- }
- }
- else
- {
- if(fInBox)
- {
- width[ipt] = ((pw - pwLineStart) << PWSH) +
- ib + xOrg - pt[ipt].x;
- if (++ipt >= NPT)
- {
- (*pGC->ops->FillSpans)(pDrawable, pGC,
- NPT, pt, width, TRUE);
- ipt = 0;
- }
- /* end box */
- fInBox = FALSE;
- }
- }
-#if 1
- /* This is not quite right, but it'll do for now */
- if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
- if (screenInfo.bitmapBitOrder == LSBFirst)
- msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1);
- else
- msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1);
- else
- if (screenInfo.bitmapBitOrder == LSBFirst)
- msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1);
- else
- msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
-#else
- msk = SCRRIGHT(msk, 1);
-#endif
- }
- pw++;
- }
- ibEnd = dx & PIM;
- if(ibEnd)
- {
- /* Process final partial word on line */
- w = *pw;
-#if 1
- msk = startmask;
-#else
- msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1);
-#endif
- for(ib = 0; ib < ibEnd; ib++)
- {
- if(w & msk)
- {
- if(!fInBox)
- {
- /* start new box */
- pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
- pt[ipt].y = h + yOrg;
- fInBox = TRUE;
- }
- }
- else
- {
- if(fInBox)
- {
- /* end box */
- width[ipt] = ((pw - pwLineStart) << PWSH) +
- ib + xOrg - pt[ipt].x;
- if (++ipt >= NPT)
- {
- (*pGC->ops->FillSpans)(pDrawable,
- pGC, NPT, pt, width, TRUE);
- ipt = 0;
- }
- fInBox = FALSE;
- }
- }
-#if 1
- /* This is not quite right, but it'll do for now */
- if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
- if (screenInfo.bitmapBitOrder == LSBFirst)
- msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1);
- else
- msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1);
- else
- if (screenInfo.bitmapBitOrder == LSBFirst)
- msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1);
- else
- msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
-#else
- msk = SCRRIGHT(msk, 1);
-#endif
- }
- }
- /* If scanline ended with last bit set, end the box */
- if(fInBox)
- {
- width[ipt] = dx + xOrg - pt[ipt].x;
- if (++ipt >= NPT)
- {
- (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt, width, TRUE);
- ipt = 0;
- }
- }
- }
- free(pwLineStart);
- /* Flush any remaining spans */
- if (ipt)
- {
- (*pGC->ops->FillSpans)(pDrawable, pGC, ipt, pt, width, TRUE);
- }
-}
+/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include "gcstruct.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "mi.h" +#include "servermd.h" + +#define NPT 128 + +/* These were stolen from mfb. They don't really belong here. */ +#define LONG2CHARSSAMEORDER(x) ((MiBits)(x)) +#define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & (MiBits)0x000000FF ) << 0x18 ) \ + | ( ( ( x ) & (MiBits)0x0000FF00 ) << 0x08 ) \ + | ( ( ( x ) & (MiBits)0x00FF0000 ) >> 0x08 ) \ + | ( ( ( x ) & (MiBits)0xFF000000 ) >> 0x18 ) ) + +#define PGSZB 4 +#define PPW (PGSZB<<3) /* assuming 8 bits per byte */ +#define PGSZ PPW +#define PLST (PPW-1) +#define PIM PLST +#define PWSH 5 + +/* miPushPixels -- squeegees the fill style of pGC through pBitMap + * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may + * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit + * is set in the bitmap, the fill style is put onto the drawable using + * the GC's logical function. The drawable is not changed where the bitmap + * has a zero bit or outside the area covered by the stencil. + +WARNING: + this code works if the 1-bit deep pixmap format returned by GetSpans +is the same as the format defined by the mfb code (i.e. 32-bit padding +per scanline, scanline unit = 32 bits; later, this might mean +bitsizeof(int) padding and sacnline unit == bitsizeof(int).) + + */ + +/* + * in order to have both (MSB_FIRST and LSB_FIRST) versions of this + * in the server, we need to rename one of them + */ +void +miPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, + int dx, int dy, int xOrg, int yOrg) +{ + int h, dxDivPPW, ibEnd; + MiBits *pwLineStart; + MiBits *pw, *pwEnd; + MiBits msk; + int ib, w; + int ipt; /* index into above arrays */ + Bool fInBox; + DDXPointRec pt[NPT], ptThisLine; + int width[NPT]; + +#if 1 + MiBits startmask; + + if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER) + if (screenInfo.bitmapBitOrder == LSBFirst) + startmask = (MiBits) (-1) ^ LONG2CHARSSAMEORDER((MiBits) (-1) << 1); + else + startmask = (MiBits) (-1) ^ LONG2CHARSSAMEORDER((MiBits) (-1) >> 1); + else if (screenInfo.bitmapBitOrder == LSBFirst) + startmask = (MiBits) (-1) ^ LONG2CHARSDIFFORDER((MiBits) (-1) << 1); + else + startmask = (MiBits) (-1) ^ LONG2CHARSDIFFORDER((MiBits) (-1) >> 1); +#endif + + pwLineStart = malloc(BitmapBytePad(dx)); + if (!pwLineStart) + return; + ipt = 0; + dxDivPPW = dx / PPW; + + for (h = 0, ptThisLine.x = 0, ptThisLine.y = 0; h < dy; h++, ptThisLine.y++) { + + (*pBitMap->drawable.pScreen->GetSpans) ((DrawablePtr) pBitMap, dx, + &ptThisLine, &dx, 1, + (char *) pwLineStart); + + pw = pwLineStart; + /* Process all words which are fully in the pixmap */ + + fInBox = FALSE; + pwEnd = pwLineStart + dxDivPPW; + while (pw < pwEnd) { + w = *pw; +#if 1 + msk = startmask; +#else + msk = (MiBits) (-1) ^ SCRRIGHT((MiBits) (-1), 1); +#endif + for (ib = 0; ib < PPW; ib++) { + if (w & msk) { + if (!fInBox) { + pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg; + pt[ipt].y = h + yOrg; + /* start new box */ + fInBox = TRUE; + } + } + else { + if (fInBox) { + width[ipt] = ((pw - pwLineStart) << PWSH) + + ib + xOrg - pt[ipt].x; + if (++ipt >= NPT) { + (*pGC->ops->FillSpans) (pDrawable, pGC, + NPT, pt, width, TRUE); + ipt = 0; + } + /* end box */ + fInBox = FALSE; + } + } +#if 1 + /* This is not quite right, but it'll do for now */ + if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER) + if (screenInfo.bitmapBitOrder == LSBFirst) + msk = + LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1); + else + msk = + LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1); + else if (screenInfo.bitmapBitOrder == LSBFirst) + msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1); + else + msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1); +#else + msk = SCRRIGHT(msk, 1); +#endif + } + pw++; + } + ibEnd = dx & PIM; + if (ibEnd) { + /* Process final partial word on line */ + w = *pw; +#if 1 + msk = startmask; +#else + msk = (MiBits) (-1) ^ SCRRIGHT((MiBits) (-1), 1); +#endif + for (ib = 0; ib < ibEnd; ib++) { + if (w & msk) { + if (!fInBox) { + /* start new box */ + pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg; + pt[ipt].y = h + yOrg; + fInBox = TRUE; + } + } + else { + if (fInBox) { + /* end box */ + width[ipt] = ((pw - pwLineStart) << PWSH) + + ib + xOrg - pt[ipt].x; + if (++ipt >= NPT) { + (*pGC->ops->FillSpans) (pDrawable, + pGC, NPT, pt, width, TRUE); + ipt = 0; + } + fInBox = FALSE; + } + } +#if 1 + /* This is not quite right, but it'll do for now */ + if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER) + if (screenInfo.bitmapBitOrder == LSBFirst) + msk = + LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1); + else + msk = + LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1); + else if (screenInfo.bitmapBitOrder == LSBFirst) + msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1); + else + msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1); +#else + msk = SCRRIGHT(msk, 1); +#endif + } + } + /* If scanline ended with last bit set, end the box */ + if (fInBox) { + width[ipt] = dx + xOrg - pt[ipt].x; + if (++ipt >= NPT) { + (*pGC->ops->FillSpans) (pDrawable, pGC, NPT, pt, width, TRUE); + ipt = 0; + } + } + } + free(pwLineStart); + /* Flush any remaining spans */ + if (ipt) { + (*pGC->ops->FillSpans) (pDrawable, pGC, ipt, pt, width, TRUE); + } +} diff --git a/xorg-server/mi/miscrinit.c b/xorg-server/mi/miscrinit.c index f56083050..2850c8d79 100644 --- a/xorg-server/mi/miscrinit.c +++ b/xorg-server/mi/miscrinit.c @@ -1,296 +1,293 @@ -/*
-
-Copyright 1990, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include "servermd.h"
-#include "misc.h"
-#include "mi.h"
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "dix.h"
-#include "miline.h"
-#ifdef MITSHM
-#include <X11/extensions/shm.h>
-#include "shmint.h"
-#endif
-
-/* We use this structure to propogate some information from miScreenInit to
- * miCreateScreenResources. miScreenInit allocates the structure, fills it
- * in, and puts it into pScreen->devPrivate. miCreateScreenResources
- * extracts the info and frees the structure. We could've accomplished the
- * same thing by adding fields to the screen structure, but they would have
- * ended up being redundant, and would have exposed this mi implementation
- * detail to the whole server.
- */
-
-typedef struct
-{
- pointer pbits; /* pointer to framebuffer */
- int width; /* delta to add to a framebuffer addr to move one row down */
-} miScreenInitParmsRec, *miScreenInitParmsPtr;
-
-
-/* this plugs into pScreen->ModifyPixmapHeader */
-Bool
-miModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
- int bitsPerPixel, int devKind, pointer pPixData)
-{
- if (!pPixmap)
- return FALSE;
-
- /*
- * If all arguments are specified, reinitialize everything (including
- * validated state).
- */
- if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) &&
- (devKind > 0) && pPixData) {
- pPixmap->drawable.depth = depth;
- pPixmap->drawable.bitsPerPixel = bitsPerPixel;
- pPixmap->drawable.id = 0;
- pPixmap->drawable.x = 0;
- pPixmap->drawable.y = 0;
- pPixmap->drawable.width = width;
- pPixmap->drawable.height = height;
- pPixmap->devKind = devKind;
- pPixmap->refcnt = 1;
- pPixmap->devPrivate.ptr = pPixData;
- } else {
- /*
- * Only modify specified fields, keeping all others intact.
- */
-
- if (width > 0)
- pPixmap->drawable.width = width;
-
- if (height > 0)
- pPixmap->drawable.height = height;
-
- if (depth > 0)
- pPixmap->drawable.depth = depth;
-
- if (bitsPerPixel > 0)
- pPixmap->drawable.bitsPerPixel = bitsPerPixel;
- else if ((bitsPerPixel < 0) && (depth > 0))
- pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
-
- /*
- * CAVEAT: Non-SI DDXen may use devKind and devPrivate fields for
- * other purposes.
- */
- if (devKind > 0)
- pPixmap->devKind = devKind;
- else if ((devKind < 0) && ((width > 0) || (depth > 0)))
- pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
- pPixmap->drawable.depth);
-
- if (pPixData)
- pPixmap->devPrivate.ptr = pPixData;
- }
- pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- return TRUE;
-}
-
-static Bool
-miCloseScreen (int iScreen, ScreenPtr pScreen)
-{
- return ((*pScreen->DestroyPixmap)((PixmapPtr)pScreen->devPrivate));
-}
-
-/* With the introduction of pixmap privates, the "screen pixmap" can no
- * longer be created in miScreenInit, since all the modules that could
- * possibly ask for pixmap private space have not been initialized at
- * that time. pScreen->CreateScreenResources is called after all
- * possible private-requesting modules have been inited; we create the
- * screen pixmap here.
- */
-Bool
-miCreateScreenResources(ScreenPtr pScreen)
-{
- miScreenInitParmsPtr pScrInitParms;
- pointer value;
-
- pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
-
- /* if width is non-zero, pScreen->devPrivate will be a pixmap
- * else it will just take the value pbits
- */
- if (pScrInitParms->width)
- {
- PixmapPtr pPixmap;
-
- /* create a pixmap with no data, then redirect it to point to
- * the screen
- */
- pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
- if (!pPixmap)
- return FALSE;
-
- if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width,
- pScreen->height, pScreen->rootDepth,
- BitsPerPixel(pScreen->rootDepth),
- PixmapBytePad(pScrInitParms->width, pScreen->rootDepth),
- pScrInitParms->pbits))
- return FALSE;
- value = (pointer)pPixmap;
- }
- else
- {
- value = pScrInitParms->pbits;
- }
- free(pScreen->devPrivate); /* freeing miScreenInitParmsRec */
- pScreen->devPrivate = value; /* pPixmap or pbits */
- return TRUE;
-}
-
-Bool
-miScreenDevPrivateInit(ScreenPtr pScreen, int width, pointer pbits)
-{
- miScreenInitParmsPtr pScrInitParms;
-
- /* Stash pbits and width in a short-lived miScreenInitParmsRec attached
- * to the screen, until CreateScreenResources can put them in the
- * screen pixmap.
- */
- pScrInitParms = malloc(sizeof(miScreenInitParmsRec));
- if (!pScrInitParms)
- return FALSE;
- pScrInitParms->pbits = pbits;
- pScrInitParms->width = width;
- pScreen->devPrivate = (pointer)pScrInitParms;
- return TRUE;
-}
-
-static PixmapPtr
-miGetScreenPixmap(ScreenPtr pScreen)
-{
- return (PixmapPtr)(pScreen->devPrivate);
-}
-
-static void
-miSetScreenPixmap(PixmapPtr pPix)
-{
- if (pPix)
- pPix->drawable.pScreen->devPrivate = (pointer)pPix;
-}
-
-Bool
-miScreenInit(
- ScreenPtr pScreen,
- pointer pbits, /* pointer to screen bits */
- int xsize, int ysize, /* in pixels */
- int dpix, int dpiy, /* dots per inch */
- int width, /* pixel width of frame buffer */
- int rootDepth, /* depth of root window */
- int numDepths, /* number of depths supported */
- DepthRec *depths, /* supported depths */
- VisualID rootVisual, /* root visual */
- int numVisuals, /* number of visuals supported */
- VisualRec *visuals /* supported visuals */
- )
-{
- pScreen->width = xsize;
- pScreen->height = ysize;
- pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
- pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
- pScreen->numDepths = numDepths;
- pScreen->rootDepth = rootDepth;
- pScreen->allowedDepths = depths;
- pScreen->rootVisual = rootVisual;
- /* defColormap */
- pScreen->minInstalledCmaps = 1;
- pScreen->maxInstalledCmaps = 1;
- pScreen->backingStoreSupport = NotUseful;
- pScreen->saveUnderSupport = NotUseful;
- /* whitePixel, blackPixel */
- pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
- pScreen->CreateScreenResources = miCreateScreenResources;
- pScreen->GetScreenPixmap = miGetScreenPixmap;
- pScreen->SetScreenPixmap = miSetScreenPixmap;
- pScreen->numVisuals = numVisuals;
- pScreen->visuals = visuals;
- if (width)
- {
-#ifdef MITSHM
- ShmRegisterFbFuncs(pScreen);
-#endif
- pScreen->CloseScreen = miCloseScreen;
- }
- /* else CloseScreen */
- /* QueryBestSize, SaveScreen, GetImage, GetSpans */
- pScreen->SourceValidate = (SourceValidateProcPtr) 0;
- /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
- /* RealizeWindow, UnrealizeWindow */
- pScreen->ValidateTree = miValidateTree;
- pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
- pScreen->WindowExposures = miWindowExposures;
- /* CopyWindow */
- pScreen->ClearToBackground = miClearToBackground;
- pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
- pScreen->RestackWindow = (RestackWindowProcPtr) 0;
- /* CreatePixmap, DestroyPixmap */
- /* RealizeFont, UnrealizeFont */
- /* CreateGC */
- /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
- /* ListInstalledColormaps, StoreColors, ResolveColor */
- /* BitmapToRegion */
- pScreen->SendGraphicsExpose = miSendGraphicsExpose;
- pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA;
- pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA;
- pScreen->blockData = (pointer)0;
- pScreen->wakeupData = (pointer)0;
- pScreen->MarkWindow = miMarkWindow;
- pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
- pScreen->MoveWindow = miMoveWindow;
- pScreen->ResizeWindow = miSlideAndSizeWindow;
- pScreen->GetLayerWindow = miGetLayerWindow;
- pScreen->HandleExposures = miHandleValidateExposures;
- pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
- pScreen->ChangeBorderWidth = miChangeBorderWidth;
- pScreen->SetShape = miSetShape;
- pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
-
- miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
-
- return miScreenDevPrivateInit(pScreen, width, pbits);
-}
-
-DevPrivateKeyRec miZeroLineScreenKeyRec;
-
-void
-miSetZeroLineBias(ScreenPtr pScreen, unsigned int bias)
-{
- if (!dixRegisterPrivateKey(&miZeroLineScreenKeyRec, PRIVATE_SCREEN, 0))
- return;
-
- dixSetPrivate(&pScreen->devPrivates, miZeroLineScreenKey,
- (unsigned long *)(unsigned long)bias);
-}
+/* + +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include "servermd.h" +#include "misc.h" +#include "mi.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "dix.h" +#include "miline.h" +#ifdef MITSHM +#include <X11/extensions/shm.h> +#include "shmint.h" +#endif + +/* We use this structure to propogate some information from miScreenInit to + * miCreateScreenResources. miScreenInit allocates the structure, fills it + * in, and puts it into pScreen->devPrivate. miCreateScreenResources + * extracts the info and frees the structure. We could've accomplished the + * same thing by adding fields to the screen structure, but they would have + * ended up being redundant, and would have exposed this mi implementation + * detail to the whole server. + */ + +typedef struct { + pointer pbits; /* pointer to framebuffer */ + int width; /* delta to add to a framebuffer addr to move one row down */ +} miScreenInitParmsRec, *miScreenInitParmsPtr; + +/* this plugs into pScreen->ModifyPixmapHeader */ +Bool +miModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, + int bitsPerPixel, int devKind, pointer pPixData) +{ + if (!pPixmap) + return FALSE; + + /* + * If all arguments are specified, reinitialize everything (including + * validated state). + */ + if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) && + (devKind > 0) && pPixData) { + pPixmap->drawable.depth = depth; + pPixmap->drawable.bitsPerPixel = bitsPerPixel; + pPixmap->drawable.id = 0; + pPixmap->drawable.x = 0; + pPixmap->drawable.y = 0; + pPixmap->drawable.width = width; + pPixmap->drawable.height = height; + pPixmap->devKind = devKind; + pPixmap->refcnt = 1; + pPixmap->devPrivate.ptr = pPixData; + } + else { + /* + * Only modify specified fields, keeping all others intact. + */ + + if (width > 0) + pPixmap->drawable.width = width; + + if (height > 0) + pPixmap->drawable.height = height; + + if (depth > 0) + pPixmap->drawable.depth = depth; + + if (bitsPerPixel > 0) + pPixmap->drawable.bitsPerPixel = bitsPerPixel; + else if ((bitsPerPixel < 0) && (depth > 0)) + pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth); + + /* + * CAVEAT: Non-SI DDXen may use devKind and devPrivate fields for + * other purposes. + */ + if (devKind > 0) + pPixmap->devKind = devKind; + else if ((devKind < 0) && ((width > 0) || (depth > 0))) + pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width, + pPixmap->drawable.depth); + + if (pPixData) + pPixmap->devPrivate.ptr = pPixData; + } + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + return TRUE; +} + +static Bool +miCloseScreen(int iScreen, ScreenPtr pScreen) +{ + return ((*pScreen->DestroyPixmap) ((PixmapPtr) pScreen->devPrivate)); +} + +/* With the introduction of pixmap privates, the "screen pixmap" can no + * longer be created in miScreenInit, since all the modules that could + * possibly ask for pixmap private space have not been initialized at + * that time. pScreen->CreateScreenResources is called after all + * possible private-requesting modules have been inited; we create the + * screen pixmap here. + */ +Bool +miCreateScreenResources(ScreenPtr pScreen) +{ + miScreenInitParmsPtr pScrInitParms; + pointer value; + + pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate; + + /* if width is non-zero, pScreen->devPrivate will be a pixmap + * else it will just take the value pbits + */ + if (pScrInitParms->width) { + PixmapPtr pPixmap; + + /* create a pixmap with no data, then redirect it to point to + * the screen + */ + pPixmap = + (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0); + if (!pPixmap) + return FALSE; + + if (!(*pScreen->ModifyPixmapHeader) (pPixmap, pScreen->width, + pScreen->height, + pScreen->rootDepth, + BitsPerPixel(pScreen->rootDepth), + PixmapBytePad(pScrInitParms->width, + pScreen->rootDepth), + pScrInitParms->pbits)) + return FALSE; + value = (pointer) pPixmap; + } + else { + value = pScrInitParms->pbits; + } + free(pScreen->devPrivate); /* freeing miScreenInitParmsRec */ + pScreen->devPrivate = value; /* pPixmap or pbits */ + return TRUE; +} + +Bool +miScreenDevPrivateInit(ScreenPtr pScreen, int width, pointer pbits) +{ + miScreenInitParmsPtr pScrInitParms; + + /* Stash pbits and width in a short-lived miScreenInitParmsRec attached + * to the screen, until CreateScreenResources can put them in the + * screen pixmap. + */ + pScrInitParms = malloc(sizeof(miScreenInitParmsRec)); + if (!pScrInitParms) + return FALSE; + pScrInitParms->pbits = pbits; + pScrInitParms->width = width; + pScreen->devPrivate = (pointer) pScrInitParms; + return TRUE; +} + +static PixmapPtr +miGetScreenPixmap(ScreenPtr pScreen) +{ + return (PixmapPtr) (pScreen->devPrivate); +} + +static void +miSetScreenPixmap(PixmapPtr pPix) +{ + if (pPix) + pPix->drawable.pScreen->devPrivate = (pointer) pPix; +} + +Bool +miScreenInit(ScreenPtr pScreen, pointer pbits, /* pointer to screen bits */ + int xsize, int ysize, /* in pixels */ + int dpix, int dpiy, /* dots per inch */ + int width, /* pixel width of frame buffer */ + int rootDepth, /* depth of root window */ + int numDepths, /* number of depths supported */ + DepthRec * depths, /* supported depths */ + VisualID rootVisual, /* root visual */ + int numVisuals, /* number of visuals supported */ + VisualRec * visuals /* supported visuals */ + ) +{ + pScreen->width = xsize; + pScreen->height = ysize; + pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10); + pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10); + pScreen->numDepths = numDepths; + pScreen->rootDepth = rootDepth; + pScreen->allowedDepths = depths; + pScreen->rootVisual = rootVisual; + /* defColormap */ + pScreen->minInstalledCmaps = 1; + pScreen->maxInstalledCmaps = 1; + pScreen->backingStoreSupport = NotUseful; + pScreen->saveUnderSupport = NotUseful; + /* whitePixel, blackPixel */ + pScreen->ModifyPixmapHeader = miModifyPixmapHeader; + pScreen->CreateScreenResources = miCreateScreenResources; + pScreen->GetScreenPixmap = miGetScreenPixmap; + pScreen->SetScreenPixmap = miSetScreenPixmap; + pScreen->numVisuals = numVisuals; + pScreen->visuals = visuals; + if (width) { +#ifdef MITSHM + ShmRegisterFbFuncs(pScreen); +#endif + pScreen->CloseScreen = miCloseScreen; + } + /* else CloseScreen */ + /* QueryBestSize, SaveScreen, GetImage, GetSpans */ + pScreen->SourceValidate = (SourceValidateProcPtr) 0; + /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */ + /* RealizeWindow, UnrealizeWindow */ + pScreen->ValidateTree = miValidateTree; + pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0; + pScreen->WindowExposures = miWindowExposures; + /* CopyWindow */ + pScreen->ClearToBackground = miClearToBackground; + pScreen->ClipNotify = (ClipNotifyProcPtr) 0; + pScreen->RestackWindow = (RestackWindowProcPtr) 0; + /* CreatePixmap, DestroyPixmap */ + /* RealizeFont, UnrealizeFont */ + /* CreateGC */ + /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */ + /* ListInstalledColormaps, StoreColors, ResolveColor */ + /* BitmapToRegion */ + pScreen->SendGraphicsExpose = miSendGraphicsExpose; + pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA; + pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA; + pScreen->blockData = (pointer) 0; + pScreen->wakeupData = (pointer) 0; + pScreen->MarkWindow = miMarkWindow; + pScreen->MarkOverlappedWindows = miMarkOverlappedWindows; + pScreen->MoveWindow = miMoveWindow; + pScreen->ResizeWindow = miSlideAndSizeWindow; + pScreen->GetLayerWindow = miGetLayerWindow; + pScreen->HandleExposures = miHandleValidateExposures; + pScreen->ReparentWindow = (ReparentWindowProcPtr) 0; + pScreen->ChangeBorderWidth = miChangeBorderWidth; + pScreen->SetShape = miSetShape; + pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow; + + miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS); + + return miScreenDevPrivateInit(pScreen, width, pbits); +} + +DevPrivateKeyRec miZeroLineScreenKeyRec; + +void +miSetZeroLineBias(ScreenPtr pScreen, unsigned int bias) +{ + if (!dixRegisterPrivateKey(&miZeroLineScreenKeyRec, PRIVATE_SCREEN, 0)) + return; + + dixSetPrivate(&pScreen->devPrivates, miZeroLineScreenKey, + (unsigned long *) (unsigned long) bias); +} diff --git a/xorg-server/mi/mispans.c b/xorg-server/mi/mispans.c index 21ba4da4f..0f89880e2 100644 --- a/xorg-server/mi/mispans.c +++ b/xorg-server/mi/mispans.c @@ -22,7 +22,6 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved @@ -45,7 +44,6 @@ SOFTWARE. ******************************************************************/ - #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> #endif @@ -64,168 +62,173 @@ Written by Joel McCormack, Summer 1989. */ - -void miInitSpanGroup(SpanGroup *spanGroup) +void +miInitSpanGroup(SpanGroup * spanGroup) { spanGroup->size = 0; spanGroup->count = 0; spanGroup->group = NULL; spanGroup->ymin = MAXSHORT; spanGroup->ymax = MINSHORT; -} /* InitSpanGroup */ +} /* InitSpanGroup */ #define YMIN(spans) (spans->points[0].y) #define YMAX(spans) (spans->points[spans->count-1].y) -static void miSubtractSpans (SpanGroup *spanGroup, Spans *sub) +static void +miSubtractSpans(SpanGroup * spanGroup, Spans * sub) { - int i, subCount, spansCount; - int ymin, ymax, xmin, xmax; - Spans *spans; - DDXPointPtr subPt, spansPt; - int *subWid, *spansWid; - int extra; + int i, subCount, spansCount; + int ymin, ymax, xmin, xmax; + Spans *spans; + DDXPointPtr subPt, spansPt; + int *subWid, *spansWid; + int extra; ymin = YMIN(sub); ymax = YMAX(sub); spans = spanGroup->group; for (i = spanGroup->count; i; i--, spans++) { - if (YMIN(spans) <= ymax && ymin <= YMAX(spans)) { - subCount = sub->count; - subPt = sub->points; - subWid = sub->widths; - spansCount = spans->count; - spansPt = spans->points; - spansWid = spans->widths; - extra = 0; - for (;;) - { - while (spansCount && spansPt->y < subPt->y) - { - spansPt++; spansWid++; spansCount--; - } - if (!spansCount) - break; - while (subCount && subPt->y < spansPt->y) - { - subPt++; subWid++; subCount--; - } - if (!subCount) - break; - if (subPt->y == spansPt->y) - { - xmin = subPt->x; - xmax = xmin + *subWid; - if (xmin >= spansPt->x + *spansWid || spansPt->x >= xmax) - { - ; - } - else if (xmin <= spansPt->x) - { - if (xmax >= spansPt->x + *spansWid) - { - memmove (spansPt, spansPt + 1, sizeof *spansPt * (spansCount - 1)); - memmove (spansWid, spansWid + 1, sizeof *spansWid * (spansCount - 1)); - spansPt--; - spansWid--; - spans->count--; - extra++; - } - else - { - *spansWid = *spansWid - (xmax - spansPt->x); - spansPt->x = xmax; - } - } - else - { - if (xmax >= spansPt->x + *spansWid) - { - *spansWid = xmin - spansPt->x; - } - else - { - if (!extra) { - DDXPointPtr newPt; - int *newwid; + if (YMIN(spans) <= ymax && ymin <= YMAX(spans)) { + subCount = sub->count; + subPt = sub->points; + subWid = sub->widths; + spansCount = spans->count; + spansPt = spans->points; + spansWid = spans->widths; + extra = 0; + for (;;) { + while (spansCount && spansPt->y < subPt->y) { + spansPt++; + spansWid++; + spansCount--; + } + if (!spansCount) + break; + while (subCount && subPt->y < spansPt->y) { + subPt++; + subWid++; + subCount--; + } + if (!subCount) + break; + if (subPt->y == spansPt->y) { + xmin = subPt->x; + xmax = xmin + *subWid; + if (xmin >= spansPt->x + *spansWid || spansPt->x >= xmax) { + ; + } + else if (xmin <= spansPt->x) { + if (xmax >= spansPt->x + *spansWid) { + memmove(spansPt, spansPt + 1, + sizeof *spansPt * (spansCount - 1)); + memmove(spansWid, spansWid + 1, + sizeof *spansWid * (spansCount - 1)); + spansPt--; + spansWid--; + spans->count--; + extra++; + } + else { + *spansWid = *spansWid - (xmax - spansPt->x); + spansPt->x = xmax; + } + } + else { + if (xmax >= spansPt->x + *spansWid) { + *spansWid = xmin - spansPt->x; + } + else { + if (!extra) { + DDXPointPtr newPt; + int *newwid; #define EXTRA 8 - newPt = (DDXPointPtr) realloc(spans->points, (spans->count + EXTRA) * sizeof (DDXPointRec)); - if (!newPt) - break; - spansPt = newPt + (spansPt - spans->points); - spans->points = newPt; - newwid = (int *) realloc(spans->widths, (spans->count + EXTRA) * sizeof (int)); - if (!newwid) - break; - spansWid = newwid + (spansWid - spans->widths); - spans->widths = newwid; - extra = EXTRA; - } - memmove (spansPt + 1, spansPt, sizeof *spansPt * (spansCount)); - memmove (spansWid + 1, spansWid, sizeof *spansWid * (spansCount)); - spans->count++; - extra--; - *spansWid = xmin - spansPt->x; - spansWid++; - spansPt++; - *spansWid = *spansWid - (xmax - spansPt->x); - spansPt->x = xmax; - } - } - } - spansPt++; spansWid++; spansCount--; - } - } + newPt = + (DDXPointPtr) realloc(spans->points, + (spans->count + + EXTRA) * + sizeof(DDXPointRec)); + if (!newPt) + break; + spansPt = newPt + (spansPt - spans->points); + spans->points = newPt; + newwid = + (int *) realloc(spans->widths, + (spans->count + + EXTRA) * sizeof(int)); + if (!newwid) + break; + spansWid = newwid + (spansWid - spans->widths); + spans->widths = newwid; + extra = EXTRA; + } + memmove(spansPt + 1, spansPt, + sizeof *spansPt * (spansCount)); + memmove(spansWid + 1, spansWid, + sizeof *spansWid * (spansCount)); + spans->count++; + extra--; + *spansWid = xmin - spansPt->x; + spansWid++; + spansPt++; + *spansWid = *spansWid - (xmax - spansPt->x); + spansPt->x = xmax; + } + } + } + spansPt++; + spansWid++; + spansCount--; + } + } } } -void miAppendSpans(SpanGroup *spanGroup, SpanGroup *otherGroup, Spans *spans) +void +miAppendSpans(SpanGroup * spanGroup, SpanGroup * otherGroup, Spans * spans) { int ymin, ymax; int spansCount; spansCount = spans->count; if (spansCount > 0) { - if (spanGroup->size == spanGroup->count) { - spanGroup->size = (spanGroup->size + 8) * 2; - spanGroup->group = (Spans *) - realloc(spanGroup->group, sizeof(Spans) * spanGroup->size); - } - - spanGroup->group[spanGroup->count] = *spans; - (spanGroup->count)++; - ymin = spans->points[0].y; - if (ymin < spanGroup->ymin) spanGroup->ymin = ymin; - ymax = spans->points[spansCount - 1].y; - if (ymax > spanGroup->ymax) spanGroup->ymax = ymax; - if (otherGroup && - otherGroup->ymin < ymax && - ymin < otherGroup->ymax) - { - miSubtractSpans (otherGroup, spans); - } + if (spanGroup->size == spanGroup->count) { + spanGroup->size = (spanGroup->size + 8) * 2; + spanGroup->group = (Spans *) + realloc(spanGroup->group, sizeof(Spans) * spanGroup->size); + } + + spanGroup->group[spanGroup->count] = *spans; + (spanGroup->count)++; + ymin = spans->points[0].y; + if (ymin < spanGroup->ymin) + spanGroup->ymin = ymin; + ymax = spans->points[spansCount - 1].y; + if (ymax > spanGroup->ymax) + spanGroup->ymax = ymax; + if (otherGroup && otherGroup->ymin < ymax && ymin < otherGroup->ymax) { + miSubtractSpans(otherGroup, spans); + } } - else - { - free(spans->points); - free(spans->widths); + else { + free(spans->points); + free(spans->widths); } -} /* AppendSpans */ +} /* AppendSpans */ -void miFreeSpanGroup(SpanGroup *spanGroup) +void +miFreeSpanGroup(SpanGroup * spanGroup) { free(spanGroup->group); } -static void QuickSortSpansX( - DDXPointRec points[], - int widths[], - int numSpans ) +static void +QuickSortSpansX(DDXPointRec points[], int widths[], int numSpans) { - int x; - int i, j, m; - DDXPointPtr r; + int x; + int i, j, m; + DDXPointPtr r; /* Always called with numSpans > 1 */ /* Sorts only by x, as all y should be the same */ @@ -240,86 +243,87 @@ static void QuickSortSpansX( } do { - if (numSpans < 9) { - /* Do insertion sort */ - int xprev; - - xprev = points[0].x; - i = 1; - do { /* while i != numSpans */ - x = points[i].x; - if (xprev > x) { - /* points[i] is out of order. Move into proper location. */ - DDXPointRec tpt; - int tw, k; - - for (j = 0; x >= points[j].x; j++) {} - tpt = points[i]; - tw = widths[i]; - for (k = i; k != j; k--) { - points[k] = points[k-1]; - widths[k] = widths[k-1]; - } - points[j] = tpt; - widths[j] = tw; - x = points[i].x; - } /* if out of order */ - xprev = x; - i++; - } while (i != numSpans); - return; - } - - /* Choose partition element, stick in location 0 */ - m = numSpans / 2; - if (points[m].x > points[0].x) ExchangeSpans(m, 0); - if (points[m].x > points[numSpans-1].x) ExchangeSpans(m, numSpans-1); - if (points[m].x > points[0].x) ExchangeSpans(m, 0); - x = points[0].x; + if (numSpans < 9) { + /* Do insertion sort */ + int xprev; + + xprev = points[0].x; + i = 1; + do { /* while i != numSpans */ + x = points[i].x; + if (xprev > x) { + /* points[i] is out of order. Move into proper location. */ + DDXPointRec tpt; + int tw, k; + + for (j = 0; x >= points[j].x; j++) { + } + tpt = points[i]; + tw = widths[i]; + for (k = i; k != j; k--) { + points[k] = points[k - 1]; + widths[k] = widths[k - 1]; + } + points[j] = tpt; + widths[j] = tw; + x = points[i].x; + } /* if out of order */ + xprev = x; + i++; + } while (i != numSpans); + return; + } + + /* Choose partition element, stick in location 0 */ + m = numSpans / 2; + if (points[m].x > points[0].x) + ExchangeSpans(m, 0); + if (points[m].x > points[numSpans - 1].x) + ExchangeSpans(m, numSpans - 1); + if (points[m].x > points[0].x) + ExchangeSpans(m, 0); + x = points[0].x; /* Partition array */ i = 0; j = numSpans; do { - r = &(points[i]); - do { - r++; - i++; + r = &(points[i]); + do { + r++; + i++; } while (i != numSpans && r->x < x); - r = &(points[j]); - do { - r--; - j--; + r = &(points[j]); + do { + r--; + j--; } while (x < r->x); - if (i < j) ExchangeSpans(i, j); + if (i < j) + ExchangeSpans(i, j); } while (i < j); /* Move partition element back to middle */ ExchangeSpans(0, j); - /* Recurse */ - if (numSpans-j-1 > 1) - QuickSortSpansX(&points[j+1], &widths[j+1], numSpans-j-1); + /* Recurse */ + if (numSpans - j - 1 > 1) + QuickSortSpansX(&points[j + 1], &widths[j + 1], numSpans - j - 1); numSpans = j; } while (numSpans > 1); -} /* QuickSortSpans */ - +} /* QuickSortSpans */ -static int UniquifySpansX( - Spans *spans, - DDXPointRec *newPoints, - int *newWidths ) +static int +UniquifySpansX(Spans * spans, DDXPointRec * newPoints, int *newWidths) { - int newx1, newx2, oldpt, i, y; - DDXPointRec *oldPoints; - int *oldWidths; - int *startNewWidths; + int newx1, newx2, oldpt, i, y; + DDXPointRec *oldPoints; + int *oldWidths; + int *startNewWidths; /* Always called with numSpans > 1 */ /* Uniquify the spans, and stash them into newPoints and newWidths. Return the number of unique spans. */ - startNewWidths = newWidths; oldPoints = spans->points; @@ -329,25 +333,27 @@ static int UniquifySpansX( newx1 = oldPoints->x; newx2 = newx1 + *oldWidths; - for (i = spans->count-1; i != 0; i--) { - oldPoints++; - oldWidths++; - oldpt = oldPoints->x; - if (oldpt > newx2) { - /* Write current span, start a new one */ - newPoints->x = newx1; - newPoints->y = y; - *newWidths = newx2 - newx1; - newPoints++; - newWidths++; - newx1 = oldpt; - newx2 = oldpt + *oldWidths; - } else { - /* extend current span, if old extends beyond new */ - oldpt = oldpt + *oldWidths; - if (oldpt > newx2) newx2 = oldpt; - } - } /* for */ + for (i = spans->count - 1; i != 0; i--) { + oldPoints++; + oldWidths++; + oldpt = oldPoints->x; + if (oldpt > newx2) { + /* Write current span, start a new one */ + newPoints->x = newx1; + newPoints->y = y; + *newWidths = newx2 - newx1; + newPoints++; + newWidths++; + newx1 = oldpt; + newx2 = oldpt + *oldWidths; + } + else { + /* extend current span, if old extends beyond new */ + oldpt = oldpt + *oldWidths; + if (oldpt > newx2) + newx2 = oldpt; + } + } /* for */ /* Write final span */ newPoints->x = newx1; @@ -355,170 +361,167 @@ static int UniquifySpansX( newPoints->y = y; return (newWidths - startNewWidths) + 1; -} /* UniquifySpansX */ +} /* UniquifySpansX */ static void -miDisposeSpanGroup (SpanGroup *spanGroup) +miDisposeSpanGroup(SpanGroup * spanGroup) { - int i; - Spans *spans; - - for (i = 0; i < spanGroup->count; i++) - { - spans = spanGroup->group + i; - free(spans->points); - free(spans->widths); + int i; + Spans *spans; + + for (i = 0; i < spanGroup->count; i++) { + spans = spanGroup->group + i; + free(spans->points); + free(spans->widths); } } -void miFillUniqueSpanGroup(DrawablePtr pDraw, GCPtr pGC, SpanGroup *spanGroup) +void +miFillUniqueSpanGroup(DrawablePtr pDraw, GCPtr pGC, SpanGroup * spanGroup) { - int i; - Spans *spans; - Spans *yspans; - int *ysizes; - int ymin, ylength; + int i; + Spans *spans; + Spans *yspans; + int *ysizes; + int ymin, ylength; /* Outgoing spans for one big call to FillSpans */ - DDXPointPtr points; - int *widths; - int count; + DDXPointPtr points; + int *widths; + int count; - if (spanGroup->count == 0) return; + if (spanGroup->count == 0) + return; if (spanGroup->count == 1) { - /* Already should be sorted, unique */ - spans = spanGroup->group; - (*pGC->ops->FillSpans) - (pDraw, pGC, spans->count, spans->points, spans->widths, TRUE); - free(spans->points); - free(spans->widths); + /* Already should be sorted, unique */ + spans = spanGroup->group; + (*pGC->ops->FillSpans) + (pDraw, pGC, spans->count, spans->points, spans->widths, TRUE); + free(spans->points); + free(spans->widths); } - else - { - /* Yuck. Gross. Radix sort into y buckets, then sort x and uniquify */ - /* This seems to be the fastest thing to do. I've tried sorting on - both x and y at the same time rather than creating into all those - y buckets, but it was somewhat slower. */ - - ymin = spanGroup->ymin; - ylength = spanGroup->ymax - ymin + 1; - - /* Allocate Spans for y buckets */ - yspans = malloc(ylength * sizeof(Spans)); - ysizes = malloc(ylength * sizeof (int)); - - if (!yspans || !ysizes) - { - free(yspans); - free(ysizes); - miDisposeSpanGroup (spanGroup); - return; - } - - for (i = 0; i != ylength; i++) { - ysizes[i] = 0; - yspans[i].count = 0; - yspans[i].points = NULL; - yspans[i].widths = NULL; - } - - /* Go through every single span and put it into the correct bucket */ - count = 0; - for (i = 0, spans = spanGroup->group; - i != spanGroup->count; - i++, spans++) { - int index; - int j; - - for (j = 0, points = spans->points, widths = spans->widths; - j != spans->count; - j++, points++, widths++) { - index = points->y - ymin; - if (index >= 0 && index < ylength) { - Spans *newspans = &(yspans[index]); - if (newspans->count == ysizes[index]) { - DDXPointPtr newpoints; - int *newwidths; - ysizes[index] = (ysizes[index] + 8) * 2; - newpoints = (DDXPointPtr) realloc( - newspans->points, - ysizes[index] * sizeof(DDXPointRec)); - newwidths = (int *) realloc( - newspans->widths, - ysizes[index] * sizeof(int)); - if (!newpoints || !newwidths) - { - int i; - - for (i = 0; i < ylength; i++) - { - free(yspans[i].points); - free(yspans[i].widths); - } - free(yspans); - free(ysizes); - free(newpoints); - free(newwidths); - miDisposeSpanGroup (spanGroup); - return; - } - newspans->points = newpoints; - newspans->widths = newwidths; - } - newspans->points[newspans->count] = *points; - newspans->widths[newspans->count] = *widths; - (newspans->count)++; - } /* if y value of span in range */ - } /* for j through spans */ - count += spans->count; - free(spans->points); - spans->points = NULL; - free(spans->widths); - spans->widths = NULL; - } /* for i thorough Spans */ - - /* Now sort by x and uniquify each bucket into the final array */ - points = malloc(count * sizeof(DDXPointRec)); - widths = malloc(count * sizeof(int)); - if (!points || !widths) - { - int i; - - for (i = 0; i < ylength; i++) - { - free(yspans[i].points); - free(yspans[i].widths); - } - free(yspans); - free(ysizes); - free(points); - free(widths); - return; - } - count = 0; - for (i = 0; i != ylength; i++) { - int ycount = yspans[i].count; - if (ycount > 0) { - if (ycount > 1) { - QuickSortSpansX(yspans[i].points, yspans[i].widths, ycount); - count += UniquifySpansX - (&(yspans[i]), &(points[count]), &(widths[count])); - } else { - points[count] = yspans[i].points[0]; - widths[count] = yspans[i].widths[0]; - count++; - } - free(yspans[i].points); - free(yspans[i].widths); - } - } - - (*pGC->ops->FillSpans) (pDraw, pGC, count, points, widths, TRUE); - free(points); - free(widths); - free(yspans); - free(ysizes); /* use (DE)xalloc for these? */ + else { + /* Yuck. Gross. Radix sort into y buckets, then sort x and uniquify */ + /* This seems to be the fastest thing to do. I've tried sorting on + both x and y at the same time rather than creating into all those + y buckets, but it was somewhat slower. */ + + ymin = spanGroup->ymin; + ylength = spanGroup->ymax - ymin + 1; + + /* Allocate Spans for y buckets */ + yspans = malloc(ylength * sizeof(Spans)); + ysizes = malloc(ylength * sizeof(int)); + + if (!yspans || !ysizes) { + free(yspans); + free(ysizes); + miDisposeSpanGroup(spanGroup); + return; + } + + for (i = 0; i != ylength; i++) { + ysizes[i] = 0; + yspans[i].count = 0; + yspans[i].points = NULL; + yspans[i].widths = NULL; + } + + /* Go through every single span and put it into the correct bucket */ + count = 0; + for (i = 0, spans = spanGroup->group; + i != spanGroup->count; i++, spans++) { + int index; + int j; + + for (j = 0, points = spans->points, widths = spans->widths; + j != spans->count; j++, points++, widths++) { + index = points->y - ymin; + if (index >= 0 && index < ylength) { + Spans *newspans = &(yspans[index]); + + if (newspans->count == ysizes[index]) { + DDXPointPtr newpoints; + int *newwidths; + + ysizes[index] = (ysizes[index] + 8) * 2; + newpoints = (DDXPointPtr) realloc(newspans->points, + ysizes[index] * + sizeof(DDXPointRec)); + newwidths = + (int *) realloc(newspans->widths, + ysizes[index] * sizeof(int)); + if (!newpoints || !newwidths) { + int i; + + for (i = 0; i < ylength; i++) { + free(yspans[i].points); + free(yspans[i].widths); + } + free(yspans); + free(ysizes); + free(newpoints); + free(newwidths); + miDisposeSpanGroup(spanGroup); + return; + } + newspans->points = newpoints; + newspans->widths = newwidths; + } + newspans->points[newspans->count] = *points; + newspans->widths[newspans->count] = *widths; + (newspans->count)++; + } /* if y value of span in range */ + } /* for j through spans */ + count += spans->count; + free(spans->points); + spans->points = NULL; + free(spans->widths); + spans->widths = NULL; + } /* for i thorough Spans */ + + /* Now sort by x and uniquify each bucket into the final array */ + points = malloc(count * sizeof(DDXPointRec)); + widths = malloc(count * sizeof(int)); + if (!points || !widths) { + int i; + + for (i = 0; i < ylength; i++) { + free(yspans[i].points); + free(yspans[i].widths); + } + free(yspans); + free(ysizes); + free(points); + free(widths); + return; + } + count = 0; + for (i = 0; i != ylength; i++) { + int ycount = yspans[i].count; + + if (ycount > 0) { + if (ycount > 1) { + QuickSortSpansX(yspans[i].points, yspans[i].widths, ycount); + count += UniquifySpansX + (&(yspans[i]), &(points[count]), &(widths[count])); + } + else { + points[count] = yspans[i].points[0]; + widths[count] = yspans[i].widths[0]; + count++; + } + free(yspans[i].points); + free(yspans[i].widths); + } + } + + (*pGC->ops->FillSpans) (pDraw, pGC, count, points, widths, TRUE); + free(points); + free(widths); + free(yspans); + free(ysizes); /* use (DE)xalloc for these? */ } spanGroup->count = 0; diff --git a/xorg-server/mi/mispans.h b/xorg-server/mi/mispans.h index 5a5f5d2b6..f3148ff19 100644 --- a/xorg-server/mi/mispans.h +++ b/xorg-server/mi/mispans.h @@ -1,92 +1,87 @@ -/***********************************************************
-
-Copyright 1989, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-#ifndef MISPANS_H
-#define MISPANS_H
-
-typedef struct {
- int count; /* number of spans */
- DDXPointPtr points; /* pointer to list of start points */
- int *widths; /* pointer to list of widths */
-} Spans;
-
-typedef struct {
- int size; /* Total number of *Spans allocated */
- int count; /* Number of *Spans actually in group */
- Spans *group; /* List of Spans */
- int ymin, ymax; /* Min, max y values encountered */
-} SpanGroup;
-
-/* Initialize SpanGroup. MUST BE DONE before use. */
-extern _X_EXPORT void miInitSpanGroup(
- SpanGroup * /*spanGroup*/
-);
-
-/* Add a Spans to a SpanGroup. The spans MUST BE in y-sorted order */
-extern _X_EXPORT void miAppendSpans(
- SpanGroup * /*spanGroup*/,
- SpanGroup * /*otherGroup*/,
- Spans * /*spans*/
-);
-
-/* Paint a span group, insuring that each pixel is painted at most once */
-extern _X_EXPORT void miFillUniqueSpanGroup(
- DrawablePtr /*pDraw*/,
- GCPtr /*pGC*/,
- SpanGroup * /*spanGroup*/
-);
-
-/* Free up data in a span group. MUST BE DONE or you'll suffer memory leaks */
-extern _X_EXPORT void miFreeSpanGroup(
- SpanGroup * /*spanGroup*/
-);
-
-/* Rops which must use span groups */
-#define miSpansCarefulRop(rop) (((rop) & 0xc) == 0x8 || ((rop) & 0x3) == 0x2)
-#define miSpansEasyRop(rop) (!miSpansCarefulRop(rop))
-
-#endif /* MISPANS_H */
+/*********************************************************** + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef MISPANS_H +#define MISPANS_H + +typedef struct { + int count; /* number of spans */ + DDXPointPtr points; /* pointer to list of start points */ + int *widths; /* pointer to list of widths */ +} Spans; + +typedef struct { + int size; /* Total number of *Spans allocated */ + int count; /* Number of *Spans actually in group */ + Spans *group; /* List of Spans */ + int ymin, ymax; /* Min, max y values encountered */ +} SpanGroup; + +/* Initialize SpanGroup. MUST BE DONE before use. */ +extern _X_EXPORT void miInitSpanGroup(SpanGroup * /*spanGroup */ + ); + +/* Add a Spans to a SpanGroup. The spans MUST BE in y-sorted order */ +extern _X_EXPORT void miAppendSpans(SpanGroup * /*spanGroup */ , + SpanGroup * /*otherGroup */ , + Spans * /*spans */ + ); + +/* Paint a span group, insuring that each pixel is painted at most once */ +extern _X_EXPORT void miFillUniqueSpanGroup(DrawablePtr /*pDraw */ , + GCPtr /*pGC */ , + SpanGroup * /*spanGroup */ + ); + +/* Free up data in a span group. MUST BE DONE or you'll suffer memory leaks */ +extern _X_EXPORT void miFreeSpanGroup(SpanGroup * /*spanGroup */ + ); + +/* Rops which must use span groups */ +#define miSpansCarefulRop(rop) (((rop) & 0xc) == 0x8 || ((rop) & 0x3) == 0x2) +#define miSpansEasyRop(rop) (!miSpansCarefulRop(rop)) + +#endif /* MISPANS_H */ diff --git a/xorg-server/mi/misprite.c b/xorg-server/mi/misprite.c index f0c008143..db35d667e 100644 --- a/xorg-server/mi/misprite.c +++ b/xorg-server/mi/misprite.c @@ -53,16 +53,16 @@ in this Software without prior written authorization from The Open Group. #include "damage.h" typedef struct { - CursorPtr pCursor; - int x; /* cursor hotspot */ - int y; - BoxRec saved; /* saved area from the screen */ - Bool isUp; /* cursor in frame buffer */ - Bool shouldBeUp; /* cursor should be displayed */ - WindowPtr pCacheWin; /* window the cursor last seen in */ - Bool isInCacheWin; - Bool checkPixels; /* check colormap collision */ - ScreenPtr pScreen; + CursorPtr pCursor; + int x; /* cursor hotspot */ + int y; + BoxRec saved; /* saved area from the screen */ + Bool isUp; /* cursor in frame buffer */ + Bool shouldBeUp; /* cursor should be displayed */ + WindowPtr pCacheWin; /* window the cursor last seen in */ + Bool isInCacheWin; + Bool checkPixels; /* check colormap collision */ + ScreenPtr pScreen; } miCursorInfoRec, *miCursorInfoPtr; /* @@ -71,32 +71,32 @@ typedef struct { typedef struct { /* screen procedures */ - CloseScreenProcPtr CloseScreen; - GetImageProcPtr GetImage; - GetSpansProcPtr GetSpans; - SourceValidateProcPtr SourceValidate; - + CloseScreenProcPtr CloseScreen; + GetImageProcPtr GetImage; + GetSpansProcPtr GetSpans; + SourceValidateProcPtr SourceValidate; + /* window procedures */ - CopyWindowProcPtr CopyWindow; - + CopyWindowProcPtr CopyWindow; + /* colormap procedures */ - InstallColormapProcPtr InstallColormap; - StoreColorsProcPtr StoreColors; - + InstallColormapProcPtr InstallColormap; + StoreColorsProcPtr StoreColors; + /* os layer procedures */ - ScreenBlockHandlerProcPtr BlockHandler; - + ScreenBlockHandlerProcPtr BlockHandler; + /* device cursor procedures */ - DeviceCursorInitializeProcPtr DeviceCursorInitialize; - DeviceCursorCleanupProcPtr DeviceCursorCleanup; - - xColorItem colors[2]; - ColormapPtr pInstalledMap; - ColormapPtr pColormap; - VisualPtr pVisual; - DamagePtr pDamage; /* damage tracking structure */ - Bool damageRegistered; - int numberOfCursors; + DeviceCursorInitializeProcPtr DeviceCursorInitialize; + DeviceCursorCleanupProcPtr DeviceCursorCleanup; + + xColorItem colors[2]; + ColormapPtr pInstalledMap; + ColormapPtr pColormap; + VisualPtr pVisual; + DamagePtr pDamage; /* damage tracking structure */ + Bool damageRegistered; + int numberOfCursors; } miSpriteScreenRec, *miSpriteScreenPtr; #define SOURCE_COLOR 0 @@ -134,7 +134,6 @@ typedef struct { #define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \ BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2)) - #define SPRITE_DEBUG_ENABLE 0 #if SPRITE_DEBUG_ENABLE #define SPRITE_DEBUG(x) ErrorF x @@ -151,9 +150,9 @@ static void miSpriteDisableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) { if (pScreenPriv->damageRegistered) { - DamageUnregister (&(pScreen->GetScreenPixmap(pScreen)->drawable), - pScreenPriv->pDamage); - pScreenPriv->damageRegistered = 0; + DamageUnregister(&(pScreen->GetScreenPixmap(pScreen)->drawable), + pScreenPriv->pDamage); + pScreenPriv->damageRegistered = 0; } } @@ -161,9 +160,9 @@ static void miSpriteEnableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) { if (!pScreenPriv->damageRegistered) { - pScreenPriv->damageRegistered = 1; - DamageRegister (&(pScreen->GetScreenPixmap(pScreen)->drawable), - pScreenPriv->pDamage); + pScreenPriv->damageRegistered = 1; + DamageRegister(&(pScreen->GetScreenPixmap(pScreen)->drawable), + pScreenPriv->pDamage); } } @@ -184,39 +183,36 @@ miSpriteIsDown(miCursorInfoPtr pDevCursor) */ static DevPrivateKeyRec miSpriteScreenKeyRec; + #define miSpriteScreenKey (&miSpriteScreenKeyRec) #define GetSpriteScreen(pScreen) \ (dixLookupPrivate(&(pScreen)->devPrivates, miSpriteScreenKey)) static DevPrivateKeyRec miSpriteDevPrivatesKeyRec; + #define miSpriteDevPrivatesKey (&miSpriteDevPrivatesKeyRec) -static Bool miSpriteCloseScreen(int i, ScreenPtr pScreen); -static void miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy, - int w, int h, unsigned int format, - unsigned long planemask, char *pdstLine); -static void miSpriteGetSpans(DrawablePtr pDrawable, int wMax, - DDXPointPtr ppt, int *pwidth, int nspans, - char *pdstStart); -static void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, - int width, int height, - unsigned int subWindowMode); -static void miSpriteCopyWindow (WindowPtr pWindow, - DDXPointRec ptOldOrg, - RegionPtr prgnSrc); -static void miSpriteBlockHandler(int i, pointer blockData, - pointer pTimeout, - pointer pReadMask); -static void miSpriteInstallColormap(ColormapPtr pMap); -static void miSpriteStoreColors(ColormapPtr pMap, int ndef, - xColorItem *pdef); - -static void miSpriteComputeSaved(DeviceIntPtr pDev, - ScreenPtr pScreen); - -static Bool miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, - ScreenPtr pScreen); -static void miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, - ScreenPtr pScreen); +static Bool miSpriteCloseScreen(int i, ScreenPtr pScreen); +static void miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy, + int w, int h, unsigned int format, + unsigned long planemask, char *pdstLine); +static void miSpriteGetSpans(DrawablePtr pDrawable, int wMax, + DDXPointPtr ppt, int *pwidth, int nspans, + char *pdstStart); +static void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, + int width, int height, + unsigned int subWindowMode); +static void miSpriteCopyWindow(WindowPtr pWindow, + DDXPointRec ptOldOrg, RegionPtr prgnSrc); +static void miSpriteBlockHandler(int i, pointer blockData, + pointer pTimeout, pointer pReadMask); +static void miSpriteInstallColormap(ColormapPtr pMap); +static void miSpriteStoreColors(ColormapPtr pMap, int ndef, xColorItem * pdef); + +static void miSpriteComputeSaved(DeviceIntPtr pDev, ScreenPtr pScreen); + +static Bool miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, + ScreenPtr pScreen); +static void miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen); #define SCREEN_PROLOGUE(pPriv, pScreen, field) ((pScreen)->field = \ (pPriv)->field) @@ -249,12 +245,9 @@ miPointerSpriteFuncRec miSpritePointerFuncs = { * other misc functions */ -static void miSpriteRemoveCursor(DeviceIntPtr pDev, - ScreenPtr pScreen); -static void miSpriteSaveUnderCursor(DeviceIntPtr pDev, - ScreenPtr pScreen); -static void miSpriteRestoreCursor(DeviceIntPtr pDev, - ScreenPtr pScreen); +static void miSpriteRemoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen); +static void miSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen); +static void miSpriteRestoreCursor(DeviceIntPtr pDev, ScreenPtr pScreen); static void miSpriteRegisterBlockHandler(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) @@ -266,24 +259,21 @@ miSpriteRegisterBlockHandler(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) } static void -miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure) +miSpriteReportDamage(DamagePtr pDamage, RegionPtr pRegion, void *closure) { - ScreenPtr pScreen = closure; - miCursorInfoPtr pCursorInfo; - DeviceIntPtr pDev; - - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) - { - if (DevHasCursor(pDev)) - { + ScreenPtr pScreen = closure; + miCursorInfoPtr pCursorInfo; + DeviceIntPtr pDev; + + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { + if (DevHasCursor(pDev)) { pCursorInfo = MISPRITE(pDev); if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && - RegionContainsRect(pRegion, &pCursorInfo->saved) != rgnOUT) - { + RegionContainsRect(pRegion, &pCursorInfo->saved) != rgnOUT) { SPRITE_DEBUG(("Damage remove\n")); - miSpriteRemoveCursor (pDev, pScreen); + miSpriteRemoveCursor(pDev, pScreen); } } } @@ -296,41 +286,36 @@ miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure) */ Bool -miSpriteInitialize (ScreenPtr pScreen, - miPointerScreenFuncPtr screenFuncs) +miSpriteInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs) { - miSpriteScreenPtr pScreenPriv; - VisualPtr pVisual; + miSpriteScreenPtr pScreenPriv; + VisualPtr pVisual; - if (!DamageSetup (pScreen)) - return FALSE; + if (!DamageSetup(pScreen)) + return FALSE; if (!dixRegisterPrivateKey(&miSpriteScreenKeyRec, PRIVATE_SCREEN, 0)) - return FALSE; + return FALSE; - if (!dixRegisterPrivateKey(&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, sizeof(miCursorInfoRec))) - return FALSE; + if (!dixRegisterPrivateKey + (&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, sizeof(miCursorInfoRec))) + return FALSE; - pScreenPriv = malloc(sizeof (miSpriteScreenRec)); + pScreenPriv = malloc(sizeof(miSpriteScreenRec)); if (!pScreenPriv) - return FALSE; - - pScreenPriv->pDamage = DamageCreate (miSpriteReportDamage, - NULL, - DamageReportRawRegion, - TRUE, - pScreen, - pScreen); - - if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE)) - { - free(pScreenPriv); - return FALSE; + return FALSE; + + pScreenPriv->pDamage = DamageCreate(miSpriteReportDamage, + NULL, + DamageReportRawRegion, + TRUE, pScreen, pScreen); + + if (!miPointerInitialize(pScreen, &miSpritePointerFuncs, screenFuncs, TRUE)) { + free(pScreenPriv); + return FALSE; } for (pVisual = pScreen->visuals; - pVisual->vid != pScreen->rootVisual; - pVisual++) - ; + pVisual->vid != pScreen->rootVisual; pVisual++); pScreenPriv->pVisual = pVisual; pScreenPriv->CloseScreen = pScreen->CloseScreen; pScreenPriv->GetImage = pScreen->GetImage; @@ -382,9 +367,9 @@ miSpriteInitialize (ScreenPtr pScreen, */ static Bool -miSpriteCloseScreen (int i, ScreenPtr pScreen) +miSpriteCloseScreen(int i, ScreenPtr pScreen) { - miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); + miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); pScreen->CloseScreen = pScreenPriv->CloseScreen; pScreen->GetImage = pScreenPriv->GetImage; @@ -393,7 +378,7 @@ miSpriteCloseScreen (int i, ScreenPtr pScreen) pScreen->InstallColormap = pScreenPriv->InstallColormap; pScreen->StoreColors = pScreenPriv->StoreColors; - DamageDestroy (pScreenPriv->pDamage); + DamageDestroy(pScreenPriv->pDamage); free(pScreenPriv); @@ -401,80 +386,66 @@ miSpriteCloseScreen (int i, ScreenPtr pScreen) } static void -miSpriteGetImage (DrawablePtr pDrawable, int sx, int sy, int w, int h, - unsigned int format, unsigned long planemask, - char *pdstLine) +miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, + unsigned int format, unsigned long planemask, char *pdstLine) { - ScreenPtr pScreen = pDrawable->pScreen; - DeviceIntPtr pDev; - miCursorInfoPtr pCursorInfo; - miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); - - SCREEN_PROLOGUE (pPriv, pScreen, GetImage); - - if (pDrawable->type == DRAWABLE_WINDOW) - { - for(pDev = inputInfo.devices; pDev; pDev = pDev->next) - { - if (DevHasCursor(pDev)) - { - pCursorInfo = MISPRITE(pDev); - if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && - ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y, - sx, sy, w, h)) - { - SPRITE_DEBUG (("GetImage remove\n")); - miSpriteRemoveCursor (pDev, pScreen); - } + ScreenPtr pScreen = pDrawable->pScreen; + DeviceIntPtr pDev; + miCursorInfoPtr pCursorInfo; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + + SCREEN_PROLOGUE(pPriv, pScreen, GetImage); + + if (pDrawable->type == DRAWABLE_WINDOW) { + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { + if (DevHasCursor(pDev)) { + pCursorInfo = MISPRITE(pDev); + if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && + ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, + sx, sy, w, h)) { + SPRITE_DEBUG(("GetImage remove\n")); + miSpriteRemoveCursor(pDev, pScreen); + } } } } - (*pScreen->GetImage) (pDrawable, sx, sy, w, h, - format, planemask, pdstLine); + (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine); - SCREEN_EPILOGUE (pPriv, pScreen, GetImage); + SCREEN_EPILOGUE(pPriv, pScreen, GetImage); } static void -miSpriteGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, - int *pwidth, int nspans, char *pdstStart) +miSpriteGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, + int *pwidth, int nspans, char *pdstStart) { - ScreenPtr pScreen = pDrawable->pScreen; - DeviceIntPtr pDev; - miCursorInfoPtr pCursorInfo; - miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); - - SCREEN_PROLOGUE (pPriv, pScreen, GetSpans); - - if (pDrawable->type == DRAWABLE_WINDOW) - { - for(pDev = inputInfo.devices; pDev; pDev = pDev->next) - { - if (DevHasCursor(pDev)) - { + ScreenPtr pScreen = pDrawable->pScreen; + DeviceIntPtr pDev; + miCursorInfoPtr pCursorInfo; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + + SCREEN_PROLOGUE(pPriv, pScreen, GetSpans); + + if (pDrawable->type == DRAWABLE_WINDOW) { + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { + if (DevHasCursor(pDev)) { pCursorInfo = MISPRITE(pDev); - if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) - { - DDXPointPtr pts; - int *widths; - int nPts; - int xorg, - yorg; + if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) { + DDXPointPtr pts; + int *widths; + int nPts; + int xorg, yorg; xorg = pDrawable->x; yorg = pDrawable->y; for (pts = ppt, widths = pwidth, nPts = nspans; - nPts--; - pts++, widths++) - { - if (SPN_OVERLAP(&pCursorInfo->saved,pts->y+yorg, - pts->x+xorg,*widths)) - { - SPRITE_DEBUG (("GetSpans remove\n")); - miSpriteRemoveCursor (pDev, pScreen); + nPts--; pts++, widths++) { + if (SPN_OVERLAP(&pCursorInfo->saved, pts->y + yorg, + pts->x + xorg, *widths)) { + SPRITE_DEBUG(("GetSpans remove\n")); + miSpriteRemoveCursor(pDev, pScreen); break; } } @@ -485,110 +456,96 @@ miSpriteGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); - SCREEN_EPILOGUE (pPriv, pScreen, GetSpans); + SCREEN_EPILOGUE(pPriv, pScreen, GetSpans); } static void -miSpriteSourceValidate (DrawablePtr pDrawable, int x, int y, int width, - int height, unsigned int subWindowMode) +miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, int width, + int height, unsigned int subWindowMode) { - ScreenPtr pScreen = pDrawable->pScreen; - DeviceIntPtr pDev; - miCursorInfoPtr pCursorInfo; - miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); - - SCREEN_PROLOGUE (pPriv, pScreen, SourceValidate); - - if (pDrawable->type == DRAWABLE_WINDOW) - { - for(pDev = inputInfo.devices; pDev; pDev = pDev->next) - { - if (DevHasCursor(pDev)) - { - pCursorInfo = MISPRITE(pDev); - if (pCursorInfo && pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && - ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, - x, y, width, height)) - { - SPRITE_DEBUG (("SourceValidate remove\n")); - miSpriteRemoveCursor (pDev, pScreen); - } - } - } + ScreenPtr pScreen = pDrawable->pScreen; + DeviceIntPtr pDev; + miCursorInfoPtr pCursorInfo; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + + SCREEN_PROLOGUE(pPriv, pScreen, SourceValidate); + + if (pDrawable->type == DRAWABLE_WINDOW) { + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { + if (DevHasCursor(pDev)) { + pCursorInfo = MISPRITE(pDev); + if (pCursorInfo && pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && + ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, + x, y, width, height)) { + SPRITE_DEBUG(("SourceValidate remove\n")); + miSpriteRemoveCursor(pDev, pScreen); + } + } + } } if (pScreen->SourceValidate) - (*pScreen->SourceValidate) (pDrawable, x, y, width, height, subWindowMode); + (*pScreen->SourceValidate) (pDrawable, x, y, width, height, + subWindowMode); - SCREEN_EPILOGUE (pPriv, pScreen, SourceValidate); + SCREEN_EPILOGUE(pPriv, pScreen, SourceValidate); } static void -miSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +miSpriteCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { - ScreenPtr pScreen = pWindow->drawable.pScreen; - DeviceIntPtr pDev; - miCursorInfoPtr pCursorInfo; - miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + ScreenPtr pScreen = pWindow->drawable.pScreen; + DeviceIntPtr pDev; + miCursorInfoPtr pCursorInfo; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); - SCREEN_PROLOGUE (pPriv, pScreen, CopyWindow); + SCREEN_PROLOGUE(pPriv, pScreen, CopyWindow); - for(pDev = inputInfo.devices; pDev; pDev = pDev->next) - { - if (DevHasCursor(pDev)) - { + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { + if (DevHasCursor(pDev)) { pCursorInfo = MISPRITE(pDev); /* * Damage will take care of destination check */ if (pCursorInfo && pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && - RegionContainsRect(prgnSrc, &pCursorInfo->saved) != rgnOUT) - { - SPRITE_DEBUG (("CopyWindow remove\n")); - miSpriteRemoveCursor (pDev, pScreen); + RegionContainsRect(prgnSrc, &pCursorInfo->saved) != rgnOUT) { + SPRITE_DEBUG(("CopyWindow remove\n")); + miSpriteRemoveCursor(pDev, pScreen); } } } (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc); - SCREEN_EPILOGUE (pPriv, pScreen, CopyWindow); + SCREEN_EPILOGUE(pPriv, pScreen, CopyWindow); } static void -miSpriteBlockHandler (int i, pointer blockData, pointer pTimeout, - pointer pReadmask) +miSpriteBlockHandler(int i, pointer blockData, pointer pTimeout, + pointer pReadmask) { - ScreenPtr pScreen = screenInfo.screens[i]; - miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); - DeviceIntPtr pDev; - miCursorInfoPtr pCursorInfo; - Bool WorkToDo = FALSE; - - for(pDev = inputInfo.devices; pDev; pDev = pDev->next) - { - if (DevHasCursor(pDev)) - { + ScreenPtr pScreen = screenInfo.screens[i]; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + DeviceIntPtr pDev; + miCursorInfoPtr pCursorInfo; + Bool WorkToDo = FALSE; + + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { + if (DevHasCursor(pDev)) { pCursorInfo = MISPRITE(pDev); if (pCursorInfo && !pCursorInfo->isUp - && pCursorInfo->pScreen == pScreen - && pCursorInfo->shouldBeUp) - { - SPRITE_DEBUG (("BlockHandler save")); - miSpriteSaveUnderCursor (pDev, pScreen); + && pCursorInfo->pScreen == pScreen && pCursorInfo->shouldBeUp) { + SPRITE_DEBUG(("BlockHandler save")); + miSpriteSaveUnderCursor(pDev, pScreen); } } } - for(pDev = inputInfo.devices; pDev; pDev = pDev->next) - { - if (DevHasCursor(pDev)) - { + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { + if (DevHasCursor(pDev)) { pCursorInfo = MISPRITE(pDev); if (pCursorInfo && !pCursorInfo->isUp && - pCursorInfo->pScreen == pScreen && - pCursorInfo->shouldBeUp) - { - SPRITE_DEBUG (("BlockHandler restore\n")); - miSpriteRestoreCursor (pDev, pScreen); + pCursorInfo->pScreen == pScreen && pCursorInfo->shouldBeUp) { + SPRITE_DEBUG(("BlockHandler restore\n")); + miSpriteRestoreCursor(pDev, pScreen); if (!pCursorInfo->isUp) WorkToDo = TRUE; } @@ -606,10 +563,10 @@ miSpriteBlockHandler (int i, pointer blockData, pointer pTimeout, } static void -miSpriteInstallColormap (ColormapPtr pMap) +miSpriteInstallColormap(ColormapPtr pMap) { - ScreenPtr pScreen = pMap->pScreen; - miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + ScreenPtr pScreen = pMap->pScreen; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); SCREEN_PROLOGUE(pPriv, pScreen, InstallColormap); @@ -619,14 +576,12 @@ miSpriteInstallColormap (ColormapPtr pMap) /* InstallColormap can be called before devices are initialized. */ pPriv->pInstalledMap = pMap; - if (pPriv->pColormap != pMap) - { + if (pPriv->pColormap != pMap) { DeviceIntPtr pDev; - miCursorInfoPtr pCursorInfo; - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) - { - if (DevHasCursor(pDev)) - { + miCursorInfoPtr pCursorInfo; + + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { + if (DevHasCursor(pDev)) { pCursorInfo = MISPRITE(pDev); if (pCursorInfo) { @@ -641,15 +596,15 @@ miSpriteInstallColormap (ColormapPtr pMap) } static void -miSpriteStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef) +miSpriteStoreColors(ColormapPtr pMap, int ndef, xColorItem * pdef) { - ScreenPtr pScreen = pMap->pScreen; - miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); - int i; - int updated; - VisualPtr pVisual; - DeviceIntPtr pDev; - miCursorInfoPtr pCursorInfo; + ScreenPtr pScreen = pMap->pScreen; + miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); + int i; + int updated; + VisualPtr pVisual; + DeviceIntPtr pDev; + miCursorInfoPtr pCursorInfo; SCREEN_PROLOGUE(pPriv, pScreen, StoreColors); @@ -657,12 +612,10 @@ miSpriteStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef) SCREEN_EPILOGUE(pPriv, pScreen, StoreColors); - if (pPriv->pColormap == pMap) - { + if (pPriv->pColormap == pMap) { updated = 0; pVisual = pMap->pVisual; - if (pVisual->class == DirectColor) - { + if (pVisual->class == DirectColor) { /* Direct color - match on any of the subfields */ #define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask))) @@ -679,43 +632,33 @@ miSpriteStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef) UpdateDAC(dev, plane,green,greenMask) \ UpdateDAC(dev, plane,blue,blueMask) - for (i = 0; i < ndef; i++) - { - CheckDirect (pPriv, SOURCE_COLOR) - CheckDirect (pPriv, MASK_COLOR) + for (i = 0; i < ndef; i++) { + CheckDirect(pPriv, SOURCE_COLOR) + CheckDirect(pPriv, MASK_COLOR) } } - else - { + else { /* PseudoColor/GrayScale - match on exact pixel */ - for (i = 0; i < ndef; i++) - { - if (pdef[i].pixel == - pPriv->colors[SOURCE_COLOR].pixel) - { + for (i = 0; i < ndef; i++) { + if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel) { pPriv->colors[SOURCE_COLOR] = pdef[i]; if (++updated == 2) break; } - if (pdef[i].pixel == - pPriv->colors[MASK_COLOR].pixel) - { + if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel) { pPriv->colors[MASK_COLOR] = pdef[i]; if (++updated == 2) break; } } } - if (updated) - { - for(pDev = inputInfo.devices; pDev; pDev = pDev->next) - { - if (DevHasCursor(pDev)) - { + if (updated) { + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { + if (DevHasCursor(pDev)) { pCursorInfo = MISPRITE(pDev); pCursorInfo->checkPixels = TRUE; if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) - miSpriteRemoveCursor (pDev, pScreen); + miSpriteRemoveCursor(pDev, pScreen); } } } @@ -723,35 +666,34 @@ miSpriteStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef) } static void -miSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen) +miSpriteFindColors(miCursorInfoPtr pDevCursor, ScreenPtr pScreen) { - miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); - CursorPtr pCursor; - xColorItem *sourceColor, *maskColor; + miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); + CursorPtr pCursor; + xColorItem *sourceColor, *maskColor; pCursor = pDevCursor->pCursor; sourceColor = &pScreenPriv->colors[SOURCE_COLOR]; maskColor = &pScreenPriv->colors[MASK_COLOR]; if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap || - !(pCursor->foreRed == sourceColor->red && - pCursor->foreGreen == sourceColor->green && + !(pCursor->foreRed == sourceColor->red && + pCursor->foreGreen == sourceColor->green && pCursor->foreBlue == sourceColor->blue && - pCursor->backRed == maskColor->red && - pCursor->backGreen == maskColor->green && - pCursor->backBlue == maskColor->blue)) - { - pScreenPriv->pColormap = pScreenPriv->pInstalledMap; - sourceColor->red = pCursor->foreRed; - sourceColor->green = pCursor->foreGreen; - sourceColor->blue = pCursor->foreBlue; - FakeAllocColor (pScreenPriv->pColormap, sourceColor); - maskColor->red = pCursor->backRed; - maskColor->green = pCursor->backGreen; - maskColor->blue = pCursor->backBlue; - FakeAllocColor (pScreenPriv->pColormap, maskColor); - /* "free" the pixels right away, don't let this confuse you */ - FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel); - FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel); + pCursor->backRed == maskColor->red && + pCursor->backGreen == maskColor->green && + pCursor->backBlue == maskColor->blue)) { + pScreenPriv->pColormap = pScreenPriv->pInstalledMap; + sourceColor->red = pCursor->foreRed; + sourceColor->green = pCursor->foreGreen; + sourceColor->blue = pCursor->foreBlue; + FakeAllocColor(pScreenPriv->pColormap, sourceColor); + maskColor->red = pCursor->backRed; + maskColor->green = pCursor->backGreen; + maskColor->blue = pCursor->backBlue; + FakeAllocColor(pScreenPriv->pColormap, maskColor); + /* "free" the pixels right away, don't let this confuse you */ + FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel); + FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel); } pDevCursor->checkPixels = FALSE; @@ -765,7 +707,7 @@ miSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen) #define SPRITE_PAD 8 static Bool -miSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) +miSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { miCursorInfoPtr pCursorInfo; @@ -775,7 +717,7 @@ miSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) pCursorInfo = MISPRITE(pDev); if (pCursor == pCursorInfo->pCursor) - pCursorInfo->checkPixels = TRUE; + pCursorInfo->checkPixels = TRUE; return miDCRealizeCursor(pScreen, pCursor); } @@ -787,11 +729,11 @@ miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) } static void -miSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, - CursorPtr pCursor, int x, int y) +miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor, int x, int y) { - miCursorInfoPtr pPointer; - miSpriteScreenPtr pScreenPriv; + miCursorInfoPtr pPointer; + miSpriteScreenPtr pScreenPriv; if (IsFloating(pDev)) return; @@ -799,55 +741,50 @@ miSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, pPointer = MISPRITE(pDev); pScreenPriv = GetSpriteScreen(pScreen); - if (!pCursor) - { - if (pPointer->shouldBeUp) - --pScreenPriv->numberOfCursors; - pPointer->shouldBeUp = FALSE; - if (pPointer->isUp) - miSpriteRemoveCursor (pDev, pScreen); - if (pScreenPriv->numberOfCursors == 0) - miSpriteDisableDamage(pScreen, pScreenPriv); - pPointer->pCursor = 0; - return; + if (!pCursor) { + if (pPointer->shouldBeUp) + --pScreenPriv->numberOfCursors; + pPointer->shouldBeUp = FALSE; + if (pPointer->isUp) + miSpriteRemoveCursor(pDev, pScreen); + if (pScreenPriv->numberOfCursors == 0) + miSpriteDisableDamage(pScreen, pScreenPriv); + pPointer->pCursor = 0; + return; } if (!pPointer->shouldBeUp) - pScreenPriv->numberOfCursors++; + pScreenPriv->numberOfCursors++; pPointer->shouldBeUp = TRUE; if (!pPointer->isUp) - miSpriteRegisterBlockHandler(pScreen, pScreenPriv); + miSpriteRegisterBlockHandler(pScreen, pScreenPriv); if (pPointer->x == x && - pPointer->y == y && - pPointer->pCursor == pCursor && - !pPointer->checkPixels) - { - return; + pPointer->y == y && + pPointer->pCursor == pCursor && !pPointer->checkPixels) { + return; } pPointer->x = x; pPointer->y = y; pPointer->pCacheWin = NullWindow; - if (pPointer->checkPixels || pPointer->pCursor != pCursor) - { - pPointer->pCursor = pCursor; - miSpriteFindColors (pPointer, pScreen); + if (pPointer->checkPixels || pPointer->pCursor != pCursor) { + pPointer->pCursor = pCursor; + miSpriteFindColors(pPointer, pScreen); } if (pPointer->isUp) { - /* TODO: reimplement flicker-free MoveCursor */ - SPRITE_DEBUG (("SetCursor remove %d\n", pDev->id)); - miSpriteRemoveCursor (pDev, pScreen); + /* TODO: reimplement flicker-free MoveCursor */ + SPRITE_DEBUG(("SetCursor remove %d\n", pDev->id)); + miSpriteRemoveCursor(pDev, pScreen); } - if (!pPointer->isUp && pPointer->pCursor) - { - SPRITE_DEBUG (("SetCursor restore %d\n", pDev->id)); + if (!pPointer->isUp && pPointer->pCursor) { + SPRITE_DEBUG(("SetCursor restore %d\n", pDev->id)); miSpriteSaveUnderCursor(pDev, pScreen); - miSpriteRestoreCursor (pDev, pScreen); + miSpriteRestoreCursor(pDev, pScreen); } } static void -miSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) +miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { CursorPtr pCursor; @@ -856,19 +793,19 @@ miSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) pCursor = MISPRITE(pDev)->pCursor; - miSpriteSetCursor (pDev, pScreen, pCursor, x, y); + miSpriteSetCursor(pDev, pScreen, pCursor, x, y); } - static Bool miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) { int ret = miDCDeviceInitialize(pDev, pScreen); - if (ret) - { + if (ret) { miCursorInfoPtr pCursorInfo; - pCursorInfo = dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey); + + pCursorInfo = + dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey); pCursorInfo->pCursor = NULL; pCursorInfo->x = 0; pCursorInfo->y = 0; @@ -886,7 +823,8 @@ miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) static void miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) { - miCursorInfoPtr pCursorInfo = dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey); + miCursorInfoPtr pCursorInfo = + dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey); if (DevHasCursor(pDev)) miDCDeviceCleanup(pDev, pScreen); @@ -899,16 +837,15 @@ miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) */ static void -miSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen) +miSpriteRemoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen) { - miSpriteScreenPtr pScreenPriv; - miCursorInfoPtr pCursorInfo; - + miSpriteScreenPtr pScreenPriv; + miCursorInfoPtr pCursorInfo; if (IsFloating(pDev)) return; - DamageDrawInternal (pScreen, TRUE); + DamageDrawInternal(pScreen, TRUE); pScreenPriv = GetSpriteScreen(pScreen); pCursorInfo = MISPRITE(pDev); @@ -923,12 +860,11 @@ miSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen) pCursorInfo->saved.x2 - pCursorInfo->saved.x1, pCursorInfo->saved.y2 - - pCursorInfo->saved.y1)) - { + pCursorInfo->saved.y1)) { miSpriteIsUp(pCursorInfo); } miSpriteEnableDamage(pScreen, pScreenPriv); - DamageDrawInternal (pScreen, FALSE); + DamageDrawInternal(pScreen, FALSE); } /* @@ -939,17 +875,17 @@ miSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen) static void miSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen) { - miSpriteScreenPtr pScreenPriv; - miCursorInfoPtr pCursorInfo; + miSpriteScreenPtr pScreenPriv; + miCursorInfoPtr pCursorInfo; if (IsFloating(pDev)) return; - DamageDrawInternal (pScreen, TRUE); + DamageDrawInternal(pScreen, TRUE); pScreenPriv = GetSpriteScreen(pScreen); pCursorInfo = MISPRITE(pDev); - miSpriteComputeSaved (pDev, pScreen); + miSpriteComputeSaved(pDev, pScreen); miSpriteDisableDamage(pScreen, pScreenPriv); @@ -959,53 +895,50 @@ miSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen) pCursorInfo->saved.y1, pCursorInfo->saved.x2 - pCursorInfo->saved.x1, - pCursorInfo->saved.y2 - - pCursorInfo->saved.y1); + pCursorInfo->saved.y2 - pCursorInfo->saved.y1); SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id)); miSpriteEnableDamage(pScreen, pScreenPriv); - DamageDrawInternal (pScreen, FALSE); + DamageDrawInternal(pScreen, FALSE); } - /* * Called from the block handler, restores the cursor * before waiting for something to do. */ static void -miSpriteRestoreCursor (DeviceIntPtr pDev, ScreenPtr pScreen) +miSpriteRestoreCursor(DeviceIntPtr pDev, ScreenPtr pScreen) { - miSpriteScreenPtr pScreenPriv; - int x, y; - CursorPtr pCursor; - miCursorInfoPtr pCursorInfo; + miSpriteScreenPtr pScreenPriv; + int x, y; + CursorPtr pCursor; + miCursorInfoPtr pCursorInfo; if (IsFloating(pDev)) return; - DamageDrawInternal (pScreen, TRUE); + DamageDrawInternal(pScreen, TRUE); pScreenPriv = GetSpriteScreen(pScreen); pCursorInfo = MISPRITE(pDev); - miSpriteComputeSaved (pDev, pScreen); + miSpriteComputeSaved(pDev, pScreen); pCursor = pCursorInfo->pCursor; - x = pCursorInfo->x - (int)pCursor->bits->xhot; - y = pCursorInfo->y - (int)pCursor->bits->yhot; + x = pCursorInfo->x - (int) pCursor->bits->xhot; + y = pCursorInfo->y - (int) pCursor->bits->yhot; miSpriteDisableDamage(pScreen, pScreenPriv); SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id)); if (pCursorInfo->checkPixels) - miSpriteFindColors (pCursorInfo, pScreen); + miSpriteFindColors(pCursorInfo, pScreen); if (miDCPutUpCursor(pDev, pScreen, - pCursor, x, y, - pScreenPriv->colors[SOURCE_COLOR].pixel, - pScreenPriv->colors[MASK_COLOR].pixel)) - { + pCursor, x, y, + pScreenPriv->colors[SOURCE_COLOR].pixel, + pScreenPriv->colors[MASK_COLOR].pixel)) { miSpriteIsUp(pCursorInfo); pCursorInfo->pScreen = pScreen; } miSpriteEnableDamage(pScreen, pScreenPriv); - DamageDrawInternal (pScreen, FALSE); + DamageDrawInternal(pScreen, FALSE); } /* @@ -1013,11 +946,11 @@ miSpriteRestoreCursor (DeviceIntPtr pDev, ScreenPtr pScreen) */ static void -miSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen) +miSpriteComputeSaved(DeviceIntPtr pDev, ScreenPtr pScreen) { - int x, y, w, h; - int wpad, hpad; - CursorPtr pCursor; + int x, y, w, h; + int wpad, hpad; + CursorPtr pCursor; miCursorInfoPtr pCursorInfo; if (IsFloating(pDev)) @@ -1026,8 +959,8 @@ miSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen) pCursorInfo = MISPRITE(pDev); pCursor = pCursorInfo->pCursor; - x = pCursorInfo->x - (int)pCursor->bits->xhot; - y = pCursorInfo->y - (int)pCursor->bits->yhot; + x = pCursorInfo->x - (int) pCursor->bits->xhot; + y = pCursorInfo->y - (int) pCursor->bits->yhot; w = pCursor->bits->width; h = pCursor->bits->height; wpad = SPRITE_PAD; @@ -1037,4 +970,3 @@ miSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen) pCursorInfo->saved.x2 = pCursorInfo->saved.x1 + w + wpad * 2; pCursorInfo->saved.y2 = pCursorInfo->saved.y1 + h + hpad * 2; } - diff --git a/xorg-server/mi/misprite.h b/xorg-server/mi/misprite.h index 635a6fad7..099cd0e38 100644 --- a/xorg-server/mi/misprite.h +++ b/xorg-server/mi/misprite.h @@ -1,50 +1,48 @@ -/*
- * misprite.h
- *
- * software-sprite/sprite drawing interface spec
- *
- * mi versions of these routines exist.
- */
-
-
-/*
-
-Copyright 1989, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-*/
-
-extern Bool miSpriteInitialize(
- ScreenPtr /*pScreen*/,
- miPointerScreenFuncPtr /*screenFuncs*/
-);
-
-extern Bool miDCRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
-extern Bool miDCUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
-extern Bool miDCPutUpCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
- CursorPtr pCursor, int x, int y,
- unsigned long source, unsigned long mask);
-extern Bool miDCSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
- int x, int y, int w, int h);
-extern Bool miDCRestoreUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
- int x, int y, int w, int h);
-extern Bool miDCDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen);
-extern void miDCDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen);
+/* + * misprite.h + * + * software-sprite/sprite drawing interface spec + * + * mi versions of these routines exist. + */ + +/* + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ + +extern Bool miSpriteInitialize(ScreenPtr /*pScreen */ , + miPointerScreenFuncPtr /*screenFuncs */ + ); + +extern Bool miDCRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor); +extern Bool miDCUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor); +extern Bool miDCPutUpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor, int x, int y, + unsigned long source, unsigned long mask); +extern Bool miDCSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y, int w, int h); +extern Bool miDCRestoreUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y, int w, int h); +extern Bool miDCDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen); +extern void miDCDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen); diff --git a/xorg-server/mi/mivaltree.c b/xorg-server/mi/mivaltree.c index f1de5bfd7..88f9a4084 100644 --- a/xorg-server/mi/mivaltree.c +++ b/xorg-server/mi/mivaltree.c @@ -79,15 +79,14 @@ Equipment Corporation. ******************************************************************/ - /* * Aug '86: Susan Angebranndt -- original code * July '87: Adam de Boor -- substantially modified and commented * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible. * In particular, much improved code for window mapping and * circulating. - * Bob Scheifler -- avoid miComputeClips for unmapped windows, - * valdata changes + * Bob Scheifler -- avoid miComputeClips for unmapped windows, + * valdata changes */ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> @@ -107,68 +106,66 @@ Equipment Corporation. * Compute the visibility of a shaped window */ int -miShapedWindowIn (RegionPtr universe, RegionPtr bounding, - BoxPtr rect, int x, int y) +miShapedWindowIn(RegionPtr universe, RegionPtr bounding, + BoxPtr rect, int x, int y) { - BoxRec box; - BoxPtr boundBox; - int nbox; - Bool someIn, someOut; - int t, x1, y1, x2, y2; - - nbox = RegionNumRects (bounding); - boundBox = RegionRects (bounding); + BoxRec box; + BoxPtr boundBox; + int nbox; + Bool someIn, someOut; + int t, x1, y1, x2, y2; + + nbox = RegionNumRects(bounding); + boundBox = RegionRects(bounding); someIn = someOut = FALSE; x1 = rect->x1; y1 = rect->y1; x2 = rect->x2; y2 = rect->y2; - while (nbox--) - { - if ((t = boundBox->x1 + x) < x1) - t = x1; - box.x1 = t; - if ((t = boundBox->y1 + y) < y1) - t = y1; - box.y1 = t; - if ((t = boundBox->x2 + x) > x2) - t = x2; - box.x2 = t; - if ((t = boundBox->y2 + y) > y2) - t = y2; - box.y2 = t; - if (box.x1 > box.x2) - box.x2 = box.x1; - if (box.y1 > box.y2) - box.y2 = box.y1; - switch (RegionContainsRect(universe, &box)) - { - case rgnIN: - if (someOut) - return rgnPART; - someIn = TRUE; - break; - case rgnOUT: - if (someIn) - return rgnPART; - someOut = TRUE; - break; - default: - return rgnPART; - } - boundBox++; + while (nbox--) { + if ((t = boundBox->x1 + x) < x1) + t = x1; + box.x1 = t; + if ((t = boundBox->y1 + y) < y1) + t = y1; + box.y1 = t; + if ((t = boundBox->x2 + x) > x2) + t = x2; + box.x2 = t; + if ((t = boundBox->y2 + y) > y2) + t = y2; + box.y2 = t; + if (box.x1 > box.x2) + box.x2 = box.x1; + if (box.y1 > box.y2) + box.y2 = box.y1; + switch (RegionContainsRect(universe, &box)) { + case rgnIN: + if (someOut) + return rgnPART; + someIn = TRUE; + break; + case rgnOUT: + if (someIn) + return rgnPART; + someOut = TRUE; + break; + default: + return rgnPART; + } + boundBox++; } if (someIn) - return rgnIN; + return rgnIN; return rgnOUT; } -static GetRedirectBorderClipProcPtr miGetRedirectBorderClipProc; -static SetRedirectBorderClipProcPtr miSetRedirectBorderClipProc; +static GetRedirectBorderClipProcPtr miGetRedirectBorderClipProc; +static SetRedirectBorderClipProcPtr miSetRedirectBorderClipProc; void -miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip, - GetRedirectBorderClipProcPtr getBorderClip) +miRegisterRedirectBorderClipProc(SetRedirectBorderClipProcPtr setBorderClip, + GetRedirectBorderClipProcPtr getBorderClip) { miSetRedirectBorderClipProc = setBorderClip; miGetRedirectBorderClipProc = getBorderClip; @@ -189,7 +186,6 @@ miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip, HasBorder(w) && \ (w)->backgroundState == ParentRelative) - /* *----------------------------------------------------------------------- * miComputeClips -- @@ -207,22 +203,19 @@ miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip, *----------------------------------------------------------------------- */ static void -miComputeClips ( - WindowPtr pParent, - ScreenPtr pScreen, - RegionPtr universe, - VTKind kind, - RegionPtr exposed ) /* for intermediate calculations */ -{ - int dx, - dy; - RegionRec childUniverse; - WindowPtr pChild; - int oldVis, newVis; - BoxRec borderSize; - RegionRec childUnion; - Bool overlap; - RegionPtr borderVisible; +miComputeClips(WindowPtr pParent, + ScreenPtr pScreen, + RegionPtr universe, VTKind kind, RegionPtr exposed) +{ /* for intermediate calculations */ + int dx, dy; + RegionRec childUniverse; + WindowPtr pChild; + int oldVis, newVis; + BoxRec borderSize; + RegionRec childUnion; + Bool overlap; + RegionPtr borderVisible; + /* * Figure out the new visibility of this window. * The extent of the universe should be the same as the extent of @@ -233,67 +226,65 @@ miComputeClips ( */ borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent); borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent); - dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent); + dx = (int) pParent->drawable.x + (int) pParent->drawable.width + + wBorderWidth(pParent); if (dx > 32767) - dx = 32767; + dx = 32767; borderSize.x2 = dx; - dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent); + dy = (int) pParent->drawable.y + (int) pParent->drawable.height + + wBorderWidth(pParent); if (dy > 32767) - dy = 32767; + dy = 32767; borderSize.y2 = dy; #ifdef COMPOSITE /* * In redirected drawing case, reset universe to borderSize */ - if (pParent->redirectDraw != RedirectDrawNone) - { - if (miSetRedirectBorderClipProc) - { - if (TreatAsTransparent (pParent)) - RegionEmpty(universe); - (*miSetRedirectBorderClipProc) (pParent, universe); - } - RegionCopy(universe, &pParent->borderSize); + if (pParent->redirectDraw != RedirectDrawNone) { + if (miSetRedirectBorderClipProc) { + if (TreatAsTransparent(pParent)) + RegionEmpty(universe); + (*miSetRedirectBorderClipProc) (pParent, universe); + } + RegionCopy(universe, &pParent->borderSize); } #endif oldVis = pParent->visibility; - switch (RegionContainsRect(universe, &borderSize)) - { - case rgnIN: - newVis = VisibilityUnobscured; - break; - case rgnPART: - newVis = VisibilityPartiallyObscured; - { - RegionPtr pBounding; - - if ((pBounding = wBoundingShape (pParent))) - { - switch (miShapedWindowIn (universe, pBounding, - &borderSize, - pParent->drawable.x, - pParent->drawable.y)) - { - case rgnIN: - newVis = VisibilityUnobscured; - break; - case rgnOUT: - newVis = VisibilityFullyObscured; - break; - } - } - } - break; - default: - newVis = VisibilityFullyObscured; - break; + switch (RegionContainsRect(universe, &borderSize)) { + case rgnIN: + newVis = VisibilityUnobscured; + break; + case rgnPART: + newVis = VisibilityPartiallyObscured; + { + RegionPtr pBounding; + + if ((pBounding = wBoundingShape(pParent))) { + switch (miShapedWindowIn(universe, pBounding, + &borderSize, + pParent->drawable.x, + pParent->drawable.y)) { + case rgnIN: + newVis = VisibilityUnobscured; + break; + case rgnOUT: + newVis = VisibilityFullyObscured; + break; + } + } + } + break; + default: + newVis = VisibilityFullyObscured; + break; } pParent->visibility = newVis; if (oldVis != newVis && - ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask)) - SendVisibilityNotify(pParent); + ((pParent-> + eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask)) + SendVisibilityNotify(pParent); if (pParent->valdata==UnmapValData) return; // return if no valid valdata @@ -309,74 +300,64 @@ miComputeClips ( case VTMap: case VTStack: case VTUnmap: - break; + break; case VTMove: - if ((oldVis == newVis) && - ((oldVis == VisibilityFullyObscured) || - (oldVis == VisibilityUnobscured))) - { - pChild = pParent; - while (1) - { - if (pChild->viewable) - { - if (pChild->visibility != VisibilityFullyObscured) - { - RegionTranslate(&pChild->borderClip, - dx, dy); - RegionTranslate(&pChild->clipList, - dx, dy); - pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; - if (pScreen->ClipNotify) - (* pScreen->ClipNotify) (pChild, dx, dy); - - } - if (pChild->valdata) - { - RegionNull(&pChild->valdata->after.borderExposed); - if (HasParentRelativeBorder(pChild)) - { - RegionSubtract(&pChild->valdata->after.borderExposed, - &pChild->borderClip, - &pChild->winSize); - } - RegionNull(&pChild->valdata->after.exposed); - } - if (pChild->firstChild) - { - pChild = pChild->firstChild; - continue; - } - } - while (!pChild->nextSib && (pChild != pParent)) - pChild = pChild->parent; - if (pChild == pParent) - break; - pChild = pChild->nextSib; - } - return; - } - /* fall through */ + if ((oldVis == newVis) && + ((oldVis == VisibilityFullyObscured) || + (oldVis == VisibilityUnobscured))) { + pChild = pParent; + while (1) { + if (pChild->viewable) { + if (pChild->visibility != VisibilityFullyObscured) { + RegionTranslate(&pChild->borderClip, dx, dy); + RegionTranslate(&pChild->clipList, dx, dy); + pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; + if (pScreen->ClipNotify) + (*pScreen->ClipNotify) (pChild, dx, dy); + + } + if (pChild->valdata) { + RegionNull(&pChild->valdata->after.borderExposed); + if (HasParentRelativeBorder(pChild)) { + RegionSubtract(&pChild->valdata->after. + borderExposed, &pChild->borderClip, + &pChild->winSize); + } + RegionNull(&pChild->valdata->after.exposed); + } + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + } + while (!pChild->nextSib && (pChild != pParent)) + pChild = pChild->parent; + if (pChild == pParent) + break; + pChild = pChild->nextSib; + } + return; + } + /* fall through */ default: - /* - * To calculate exposures correctly, we have to translate the old - * borderClip and clipList regions to the window's new location so there - * is a correspondence between pieces of the new and old clipping regions. - */ - if (dx || dy) - { - /* - * We translate the old clipList because that will be exposed or copied - * if gravity is right. - */ - RegionTranslate(&pParent->borderClip, dx, dy); - RegionTranslate(&pParent->clipList, dx, dy); - } - break; + /* + * To calculate exposures correctly, we have to translate the old + * borderClip and clipList regions to the window's new location so there + * is a correspondence between pieces of the new and old clipping regions. + */ + if (dx || dy) { + /* + * We translate the old clipList because that will be exposed or copied + * if gravity is right. + */ + RegionTranslate(&pParent->borderClip, dx, dy); + RegionTranslate(&pParent->clipList, dx, dy); + } + break; case VTBroken: - RegionEmpty(&pParent->borderClip); - RegionEmpty(&pParent->clipList); - break; + RegionEmpty(&pParent->borderClip); + RegionEmpty(&pParent->clipList); + break; } borderVisible = pParent->valdata->before.borderVisible; @@ -392,103 +373,89 @@ miComputeClips ( * This leaves a region of pieces that weren't exposed before. */ - if (HasBorder (pParent)) - { - if (borderVisible) - { - /* - * when the border changes shape, the old visible portions - * of the border will be saved by DIX in borderVisible -- - * use that region and destroy it - */ - RegionSubtract(exposed, universe, borderVisible); - RegionDestroy(borderVisible); - } - else - { - RegionSubtract(exposed, universe, &pParent->borderClip); - } - if (HasParentRelativeBorder(pParent) && (dx || dy)) - RegionSubtract(&pParent->valdata->after.borderExposed, - universe, - &pParent->winSize); - else - RegionSubtract(&pParent->valdata->after.borderExposed, - exposed, &pParent->winSize); - - RegionCopy(&pParent->borderClip, universe); - - /* - * To get the right clipList for the parent, and to make doubly sure - * that no child overlaps the parent's border, we remove the parent's - * border from the universe before proceeding. - */ - - RegionIntersect(universe, universe, &pParent->winSize); + if (HasBorder(pParent)) { + if (borderVisible) { + /* + * when the border changes shape, the old visible portions + * of the border will be saved by DIX in borderVisible -- + * use that region and destroy it + */ + RegionSubtract(exposed, universe, borderVisible); + RegionDestroy(borderVisible); + } + else { + RegionSubtract(exposed, universe, &pParent->borderClip); + } + if (HasParentRelativeBorder(pParent) && (dx || dy)) + RegionSubtract(&pParent->valdata->after.borderExposed, + universe, &pParent->winSize); + else + RegionSubtract(&pParent->valdata->after.borderExposed, + exposed, &pParent->winSize); + + RegionCopy(&pParent->borderClip, universe); + + /* + * To get the right clipList for the parent, and to make doubly sure + * that no child overlaps the parent's border, we remove the parent's + * border from the universe before proceeding. + */ + + RegionIntersect(universe, universe, &pParent->winSize); } else - RegionCopy(&pParent->borderClip, universe); - - if ((pChild = pParent->firstChild) && pParent->mapped) - { - RegionNull(&childUniverse); - RegionNull(&childUnion); - if ((pChild->drawable.y < pParent->lastChild->drawable.y) || - ((pChild->drawable.y == pParent->lastChild->drawable.y) && - (pChild->drawable.x < pParent->lastChild->drawable.x))) - { - for (; pChild; pChild = pChild->nextSib) - { - if (pChild->viewable && !TreatAsTransparent(pChild)) - RegionAppend(&childUnion, &pChild->borderSize); - } - } - else - { - for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib) - { - if (pChild->viewable && !TreatAsTransparent(pChild)) - RegionAppend(&childUnion, &pChild->borderSize); - } - } - RegionValidate(&childUnion, &overlap); - - for (pChild = pParent->firstChild; - pChild; - pChild = pChild->nextSib) - { - if (pChild->viewable) { - /* - * If the child is viewable, we want to remove its extents - * from the current universe, but we only re-clip it if - * it's been marked. - */ - if (pChild->valdata) { - /* - * Figure out the new universe from the child's - * perspective and recurse. - */ - RegionIntersect(&childUniverse, - universe, - &pChild->borderSize); - miComputeClips (pChild, pScreen, &childUniverse, kind, - exposed); - } - /* - * Once the child has been processed, we remove its extents - * from the current universe, thus denying its space to any - * other sibling. - */ - if (overlap && !TreatAsTransparent (pChild)) - RegionSubtract(universe, universe, - &pChild->borderSize); - } - } - if (!overlap) - RegionSubtract(universe, universe, &childUnion); - RegionUninit(&childUnion); - RegionUninit(&childUniverse); - } /* if any children */ + RegionCopy(&pParent->borderClip, universe); + + if ((pChild = pParent->firstChild) && pParent->mapped) { + RegionNull(&childUniverse); + RegionNull(&childUnion); + if ((pChild->drawable.y < pParent->lastChild->drawable.y) || + ((pChild->drawable.y == pParent->lastChild->drawable.y) && + (pChild->drawable.x < pParent->lastChild->drawable.x))) { + for (; pChild; pChild = pChild->nextSib) { + if (pChild->viewable && !TreatAsTransparent(pChild)) + RegionAppend(&childUnion, &pChild->borderSize); + } + } + else { + for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib) { + if (pChild->viewable && !TreatAsTransparent(pChild)) + RegionAppend(&childUnion, &pChild->borderSize); + } + } + RegionValidate(&childUnion, &overlap); + + for (pChild = pParent->firstChild; pChild; pChild = pChild->nextSib) { + if (pChild->viewable) { + /* + * If the child is viewable, we want to remove its extents + * from the current universe, but we only re-clip it if + * it's been marked. + */ + if (pChild->valdata) { + /* + * Figure out the new universe from the child's + * perspective and recurse. + */ + RegionIntersect(&childUniverse, + universe, &pChild->borderSize); + miComputeClips(pChild, pScreen, &childUniverse, kind, + exposed); + } + /* + * Once the child has been processed, we remove its extents + * from the current universe, thus denying its space to any + * other sibling. + */ + if (overlap && !TreatAsTransparent(pChild)) + RegionSubtract(universe, universe, &pChild->borderSize); + } + } + if (!overlap) + RegionSubtract(universe, universe, &childUnion); + RegionUninit(&childUnion); + RegionUninit(&childUniverse); + } /* if any children */ /* * 'universe' now contains the new clipList for the parent window. @@ -497,25 +464,22 @@ miComputeClips ( * new, just as for the border. */ - if (oldVis == VisibilityFullyObscured || - oldVis == VisibilityNotViewable) - { - RegionCopy(&pParent->valdata->after.exposed, universe); + if (oldVis == VisibilityFullyObscured || oldVis == VisibilityNotViewable) { + RegionCopy(&pParent->valdata->after.exposed, universe); } else if (newVis != VisibilityFullyObscured && - newVis != VisibilityNotViewable) - { - RegionSubtract(&pParent->valdata->after.exposed, - universe, &pParent->clipList); + newVis != VisibilityNotViewable) { + RegionSubtract(&pParent->valdata->after.exposed, + universe, &pParent->clipList); } /* HACK ALERT - copying contents of regions, instead of regions */ { - RegionRec tmp; + RegionRec tmp; - tmp = pParent->clipList; - pParent->clipList = *universe; - *universe = tmp; + tmp = pParent->clipList; + pParent->clipList = *universe; + *universe = tmp; } #ifdef NOTDEF @@ -525,36 +489,33 @@ miComputeClips ( pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; if (pScreen->ClipNotify) - (* pScreen->ClipNotify) (pParent, dx, dy); + (*pScreen->ClipNotify) (pParent, dx, dy); } static void -miTreeObscured( - WindowPtr pParent ) +miTreeObscured(WindowPtr pParent) { - WindowPtr pChild; - int oldVis; + WindowPtr pChild; + int oldVis; pChild = pParent; - while (1) - { - if (pChild->viewable) - { - oldVis = pChild->visibility; - if (oldVis != (pChild->visibility = VisibilityFullyObscured) && - ((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask)) - SendVisibilityNotify(pChild); - if (pChild->firstChild) - { - pChild = pChild->firstChild; - continue; - } - } - while (!pChild->nextSib && (pChild != pParent)) - pChild = pChild->parent; - if (pChild == pParent) - break; - pChild = pChild->nextSib; + while (1) { + if (pChild->viewable) { + oldVis = pChild->visibility; + if (oldVis != (pChild->visibility = VisibilityFullyObscured) && + ((pChild-> + eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask)) + SendVisibilityNotify(pChild); + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + } + while (!pChild->nextSib && (pChild != pParent)) + pChild = pChild->parent; + if (pChild == pParent) + break; + pChild = pChild->nextSib; } } @@ -587,33 +548,31 @@ miTreeObscured( * *----------------------------------------------------------------------- */ -/*ARGSUSED*/ -int -miValidateTree ( - WindowPtr pParent, /* Parent to validate */ - WindowPtr pChild, /* First child of pParent that was - * affected */ - VTKind kind /* What kind of configuration caused call */ + /*ARGSUSED*/ int +miValidateTree(WindowPtr pParent, /* Parent to validate */ + WindowPtr pChild, /* First child of pParent that was + * affected */ + VTKind kind /* What kind of configuration caused call */ ) { - RegionRec totalClip; /* Total clipping region available to - * the marked children. pParent's clipList - * merged with the borderClips of all - * the marked children. */ - RegionRec childClip; /* The new borderClip for the current - * child */ - RegionRec childUnion; /* the space covered by borderSize for - * all marked children */ - RegionRec exposed; /* For intermediate calculations */ - ScreenPtr pScreen; - WindowPtr pWin; - Bool overlap; - int viewvals; - Bool forward; + RegionRec totalClip; /* Total clipping region available to + * the marked children. pParent's clipList + * merged with the borderClips of all + * the marked children. */ + RegionRec childClip; /* The new borderClip for the current + * child */ + RegionRec childUnion; /* the space covered by borderSize for + * all marked children */ + RegionRec exposed; /* For intermediate calculations */ + ScreenPtr pScreen; + WindowPtr pWin; + Bool overlap; + int viewvals; + Bool forward; pScreen = pParent->drawable.pScreen; if (pChild == NullWindow) - pChild = pParent->firstChild; + pChild = pParent->firstChild; RegionNull(&childClip); RegionNull(&exposed); @@ -626,74 +585,68 @@ miValidateTree ( */ RegionNull(&totalClip); viewvals = 0; - if (RegionBroken(&pParent->clipList) && - !RegionBroken(&pParent->borderClip)) - { - kind = VTBroken; - /* - * When rebuilding clip lists after out of memory, - * assume everything is busted. - */ - forward = TRUE; - RegionCopy(&totalClip, &pParent->borderClip); - RegionIntersect(&totalClip, &totalClip, &pParent->winSize); - - for (pWin = pParent->firstChild; pWin != pChild; pWin = pWin->nextSib) - { - if (pWin->viewable && !TreatAsTransparent (pWin)) - RegionSubtract(&totalClip, &totalClip, &pWin->borderSize); - } - for (pWin = pChild; pWin; pWin = pWin->nextSib) - if (pWin->valdata && pWin->viewable) - viewvals++; - - RegionEmpty(&pParent->clipList); + if (RegionBroken(&pParent->clipList) && !RegionBroken(&pParent->borderClip)) { + kind = VTBroken; + /* + * When rebuilding clip lists after out of memory, + * assume everything is busted. + */ + forward = TRUE; + RegionCopy(&totalClip, &pParent->borderClip); + RegionIntersect(&totalClip, &totalClip, &pParent->winSize); + + for (pWin = pParent->firstChild; pWin != pChild; pWin = pWin->nextSib) { + if (pWin->viewable && !TreatAsTransparent(pWin)) + RegionSubtract(&totalClip, &totalClip, &pWin->borderSize); + } + for (pWin = pChild; pWin; pWin = pWin->nextSib) + if (pWin->valdata && pWin->viewable) + viewvals++; + + RegionEmpty(&pParent->clipList); } - else - { - if ((pChild->drawable.y < pParent->lastChild->drawable.y) || - ((pChild->drawable.y == pParent->lastChild->drawable.y) && - (pChild->drawable.x < pParent->lastChild->drawable.x))) - { - forward = TRUE; - for (pWin = pChild; pWin; pWin = pWin->nextSib) - { - if (pWin->valdata) - { - RegionPtr pBorderClip = &pWin->borderClip; + else { + if ((pChild->drawable.y < pParent->lastChild->drawable.y) || + ((pChild->drawable.y == pParent->lastChild->drawable.y) && + (pChild->drawable.x < pParent->lastChild->drawable.x))) { + forward = TRUE; + for (pWin = pChild; pWin; pWin = pWin->nextSib) { + if (pWin->valdata) { + RegionPtr pBorderClip = &pWin->borderClip; + #ifdef COMPOSITE - if (pWin->redirectDraw != RedirectDrawNone && miGetRedirectBorderClipProc) - pBorderClip = (*miGetRedirectBorderClipProc)(pWin); + if (pWin->redirectDraw != RedirectDrawNone && + miGetRedirectBorderClipProc) + pBorderClip = (*miGetRedirectBorderClipProc) (pWin); #endif - RegionAppend(&totalClip, pBorderClip ); - if (pWin->viewable) - viewvals++; - } - } - } - else - { - forward = FALSE; - pWin = pParent->lastChild; - while (1) - { - if (pWin->valdata) - { - RegionPtr pBorderClip = &pWin->borderClip; + RegionAppend(&totalClip, pBorderClip); + if (pWin->viewable) + viewvals++; + } + } + } + else { + forward = FALSE; + pWin = pParent->lastChild; + while (1) { + if (pWin->valdata) { + RegionPtr pBorderClip = &pWin->borderClip; + #ifdef COMPOSITE - if (pWin->redirectDraw != RedirectDrawNone && miGetRedirectBorderClipProc) - pBorderClip = (*miGetRedirectBorderClipProc)(pWin); + if (pWin->redirectDraw != RedirectDrawNone && + miGetRedirectBorderClipProc) + pBorderClip = (*miGetRedirectBorderClipProc) (pWin); #endif - RegionAppend(&totalClip, pBorderClip ); - if (pWin->viewable) - viewvals++; - } - if (pWin == pChild) - break; - pWin = pWin->prevSib; - } - } - RegionValidate(&totalClip, &overlap); + RegionAppend(&totalClip, pBorderClip); + if (pWin->viewable) + viewvals++; + } + if (pWin == pChild) + break; + pWin = pWin->prevSib; + } + } + RegionValidate(&totalClip, &overlap); } /* @@ -704,80 +657,68 @@ miValidateTree ( */ overlap = TRUE; - if (kind != VTStack) - { - RegionUnion(&totalClip, &totalClip, &pParent->clipList); - if (viewvals > 1) - { - /* - * precompute childUnion to discover whether any of them - * overlap. This seems redundant, but performance studies - * have demonstrated that the cost of this loop is - * lower than the cost of multiple Subtracts in the - * loop below. - */ - RegionNull(&childUnion); - if (forward) - { - for (pWin = pChild; pWin; pWin = pWin->nextSib) - if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin)) - RegionAppend(&childUnion, - &pWin->borderSize); - } - else - { - pWin = pParent->lastChild; - while (1) - { - if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin)) - RegionAppend(&childUnion, - &pWin->borderSize); - if (pWin == pChild) - break; - pWin = pWin->prevSib; - } - } - RegionValidate(&childUnion, &overlap); - if (overlap) - RegionUninit(&childUnion); - } + if (kind != VTStack) { + RegionUnion(&totalClip, &totalClip, &pParent->clipList); + if (viewvals > 1) { + /* + * precompute childUnion to discover whether any of them + * overlap. This seems redundant, but performance studies + * have demonstrated that the cost of this loop is + * lower than the cost of multiple Subtracts in the + * loop below. + */ + RegionNull(&childUnion); + if (forward) { + for (pWin = pChild; pWin; pWin = pWin->nextSib) + if (pWin->valdata && pWin->viewable && + !TreatAsTransparent(pWin)) + RegionAppend(&childUnion, &pWin->borderSize); + } + else { + pWin = pParent->lastChild; + while (1) { + if (pWin->valdata && pWin->viewable && + !TreatAsTransparent(pWin)) + RegionAppend(&childUnion, &pWin->borderSize); + if (pWin == pChild) + break; + pWin = pWin->prevSib; + } + } + RegionValidate(&childUnion, &overlap); + if (overlap) + RegionUninit(&childUnion); + } } - for (pWin = pChild; - pWin != NullWindow; - pWin = pWin->nextSib) - { - if (pWin->viewable) { - if (pWin->valdata) { - RegionIntersect(&childClip, - &totalClip, - &pWin->borderSize); - miComputeClips (pWin, pScreen, &childClip, kind, &exposed); - if (overlap && !TreatAsTransparent (pWin)) - { - RegionSubtract(&totalClip, - &totalClip, - &pWin->borderSize); - } - } else if (pWin->visibility == VisibilityNotViewable) { - miTreeObscured(pWin); - } - } else { - if (pWin->valdata) { - RegionEmpty(&pWin->clipList); - if (pScreen->ClipNotify) - (* pScreen->ClipNotify) (pWin, 0, 0); - RegionEmpty(&pWin->borderClip); - pWin->valdata = NULL; - } - } + for (pWin = pChild; pWin != NullWindow; pWin = pWin->nextSib) { + if (pWin->viewable) { + if (pWin->valdata) { + RegionIntersect(&childClip, &totalClip, &pWin->borderSize); + miComputeClips(pWin, pScreen, &childClip, kind, &exposed); + if (overlap && !TreatAsTransparent(pWin)) { + RegionSubtract(&totalClip, &totalClip, &pWin->borderSize); + } + } + else if (pWin->visibility == VisibilityNotViewable) { + miTreeObscured(pWin); + } + } + else { + if (pWin->valdata) { + RegionEmpty(&pWin->clipList); + if (pScreen->ClipNotify) + (*pScreen->ClipNotify) (pWin, 0, 0); + RegionEmpty(&pWin->borderClip); + pWin->valdata = NULL; + } + } } RegionUninit(&childClip); - if (!overlap) - { - RegionSubtract(&totalClip, &totalClip, &childUnion); - RegionUninit(&childUnion); + if (!overlap) { + RegionSubtract(&totalClip, &totalClip, &childUnion); + RegionUninit(&childUnion); } if (pParent->valdata && pParent->valdata!=UnmapValData) @@ -792,26 +733,26 @@ miValidateTree ( switch (kind) { case VTStack: - break; + break; default: - /* - * totalClip contains the new clipList for the parent. Figure out - * exposures and obscures as per miComputeClips and reset the parent's - * clipList. - */ - if (pParent->valdata && pParent->valdata!=UnmapValData) - RegionSubtract(&pParent->valdata->after.exposed, - &totalClip, &pParent->clipList); - /* fall through */ + /* + * totalClip contains the new clipList for the parent. Figure out + * exposures and obscures as per miComputeClips and reset the parent's + * clipList. + */ + if (pParent->valdata && pParent->valdata!=UnmapValData) + RegionSubtract(&pParent->valdata->after.exposed, + &totalClip, &pParent->clipList); + /* fall through */ case VTMap: - RegionCopy(&pParent->clipList, &totalClip); - pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; - break; + RegionCopy(&pParent->clipList, &totalClip); + pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; + break; } RegionUninit(&totalClip); RegionUninit(&exposed); if (pScreen->ClipNotify) - (*pScreen->ClipNotify) (pParent, 0, 0); + (*pScreen->ClipNotify) (pParent, 0, 0); return 1; } diff --git a/xorg-server/mi/miwideline.c b/xorg-server/mi/miwideline.c index 122566f38..242f3f8b0 100644 --- a/xorg-server/mi/miwideline.c +++ b/xorg-server/mi/miwideline.c @@ -41,7 +41,7 @@ from The Open Group. #ifdef _XOPEN_SOURCE #include <math.h> #else -#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */ +#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */ #include <math.h> #undef _XOPEN_SOURCE #endif @@ -57,16 +57,15 @@ from The Open Group. #include "mi.h" static Bool -InitSpans(Spans *spans, size_t nspans) +InitSpans(Spans * spans, size_t nspans) { - spans->points = malloc(nspans * sizeof (*spans->points)); + spans->points = malloc(nspans * sizeof(*spans->points)); if (!spans->points) - return FALSE; - spans->widths = malloc(nspans * sizeof (*spans->widths)); - if (!spans->widths) - { - free(spans->points); - return FALSE; + return FALSE; + spans->widths = malloc(nspans * sizeof(*spans->widths)); + if (!spans->widths) { + free(spans->points); + return FALSE; } return TRUE; } @@ -76,399 +75,355 @@ InitSpans(Spans *spans, size_t nspans) */ typedef struct _SpanData { - SpanGroup fgGroup, bgGroup; + SpanGroup fgGroup, bgGroup; } SpanDataRec, *SpanDataPtr; static void -AppendSpanGroup(GCPtr pGC, unsigned long pixel, Spans *spanPtr, SpanDataPtr spanData) +AppendSpanGroup(GCPtr pGC, unsigned long pixel, Spans * spanPtr, + SpanDataPtr spanData) { SpanGroup *group, *othergroup = NULL; - if (pixel == pGC->fgPixel) - { - group = &spanData->fgGroup; - if (pGC->lineStyle == LineDoubleDash) - othergroup = &spanData->bgGroup; + + if (pixel == pGC->fgPixel) { + group = &spanData->fgGroup; + if (pGC->lineStyle == LineDoubleDash) + othergroup = &spanData->bgGroup; } - else - { - group = &spanData->bgGroup; - othergroup = &spanData->fgGroup; + else { + group = &spanData->bgGroup; + othergroup = &spanData->fgGroup; } - miAppendSpans (group, othergroup, spanPtr); + miAppendSpans(group, othergroup, spanPtr); } - static void miLineArc(DrawablePtr pDraw, GCPtr pGC, - unsigned long pixel, SpanDataPtr spanData, - LineFacePtr leftFace, - LineFacePtr rightFace, - double xorg, double yorg, Bool isInt); - + unsigned long pixel, SpanDataPtr spanData, + LineFacePtr leftFace, + LineFacePtr rightFace, + double xorg, double yorg, Bool isInt); /* * spans-based polygon filler */ static void -fillSpans(DrawablePtr pDrawable, GCPtr pGC, unsigned long pixel, Spans *spans, SpanDataPtr spanData) +fillSpans(DrawablePtr pDrawable, GCPtr pGC, unsigned long pixel, Spans * spans, + SpanDataPtr spanData) { - if (!spanData) - { - ChangeGCVal oldPixel, tmpPixel; - oldPixel.val = pGC->fgPixel; - if (pixel != oldPixel.val) - { - tmpPixel.val = (XID)pixel; - ChangeGC (NullClient, pGC, GCForeground, &tmpPixel); - ValidateGC (pDrawable, pGC); - } - (*pGC->ops->FillSpans) (pDrawable, pGC, spans->count, spans->points, spans->widths, TRUE); - free(spans->widths); - free(spans->points); - if (pixel != oldPixel.val) - { - ChangeGC (NullClient, pGC, GCForeground, &oldPixel); - ValidateGC (pDrawable, pGC); - } + if (!spanData) { + ChangeGCVal oldPixel, tmpPixel; + + oldPixel.val = pGC->fgPixel; + if (pixel != oldPixel.val) { + tmpPixel.val = (XID) pixel; + ChangeGC(NullClient, pGC, GCForeground, &tmpPixel); + ValidateGC(pDrawable, pGC); + } + (*pGC->ops->FillSpans) (pDrawable, pGC, spans->count, spans->points, + spans->widths, TRUE); + free(spans->widths); + free(spans->points); + if (pixel != oldPixel.val) { + ChangeGC(NullClient, pGC, GCForeground, &oldPixel); + ValidateGC(pDrawable, pGC); + } } else - AppendSpanGroup (pGC, pixel, spans, spanData); + AppendSpanGroup(pGC, pixel, spans, spanData); } static void -miFillPolyHelper (DrawablePtr pDrawable, GCPtr pGC, unsigned long pixel, - SpanDataPtr spanData, int y, int overall_height, - PolyEdgePtr left, PolyEdgePtr right, - int left_count, int right_count) +miFillPolyHelper(DrawablePtr pDrawable, GCPtr pGC, unsigned long pixel, + SpanDataPtr spanData, int y, int overall_height, + PolyEdgePtr left, PolyEdgePtr right, + int left_count, int right_count) { int left_x = 0, left_e = 0; - int left_stepx = 0; - int left_signdx = 0; - int left_dy = 0, left_dx = 0; + int left_stepx = 0; + int left_signdx = 0; + int left_dy = 0, left_dx = 0; int right_x = 0, right_e = 0; - int right_stepx = 0; - int right_signdx = 0; - int right_dy = 0, right_dx = 0; + int right_stepx = 0; + int right_signdx = 0; + int right_dy = 0, right_dx = 0; - int height = 0; - int left_height = 0, right_height = 0; + int height = 0; + int left_height = 0, right_height = 0; DDXPointPtr ppt; - int *pwidth; - int xorg; - Spans spanRec; + int *pwidth; + int xorg; + Spans spanRec; if (!InitSpans(&spanRec, overall_height)) - return; + return; ppt = spanRec.points; pwidth = spanRec.widths; xorg = 0; - if (pGC->miTranslate) - { - y += pDrawable->y; - xorg = pDrawable->x; - } - while ((left_count || left_height) && - (right_count || right_height)) - { - if (!left_height && left_count) - { - left_height = left->height; - left_x = left->x; - left_stepx = left->stepx; - left_signdx = left->signdx; - left_e = left->e; - left_dy = left->dy; - left_dx = left->dx; - --left_count; - ++left; - } - - if (!right_height && right_count) - { - right_height = right->height; - right_x = right->x; - right_stepx = right->stepx; - right_signdx = right->signdx; - right_e = right->e; - right_dy = right->dy; - right_dx = right->dx; - --right_count; - ++right; - } - - height = left_height; - if (height > right_height) - height = right_height; - - left_height -= height; - right_height -= height; - - while (--height >= 0) - { - if (right_x >= left_x) - { - ppt->y = y; - ppt->x = left_x + xorg; - ppt++; - *pwidth++ = right_x - left_x + 1; - } - y++; - - left_x += left_stepx; - left_e += left_dx; - if (left_e > 0) - { - left_x += left_signdx; - left_e -= left_dy; - } - - right_x += right_stepx; - right_e += right_dx; - if (right_e > 0) - { - right_x += right_signdx; - right_e -= right_dy; - } - } + if (pGC->miTranslate) { + y += pDrawable->y; + xorg = pDrawable->x; + } + while ((left_count || left_height) && (right_count || right_height)) { + if (!left_height && left_count) { + left_height = left->height; + left_x = left->x; + left_stepx = left->stepx; + left_signdx = left->signdx; + left_e = left->e; + left_dy = left->dy; + left_dx = left->dx; + --left_count; + ++left; + } + + if (!right_height && right_count) { + right_height = right->height; + right_x = right->x; + right_stepx = right->stepx; + right_signdx = right->signdx; + right_e = right->e; + right_dy = right->dy; + right_dx = right->dx; + --right_count; + ++right; + } + + height = left_height; + if (height > right_height) + height = right_height; + + left_height -= height; + right_height -= height; + + while (--height >= 0) { + if (right_x >= left_x) { + ppt->y = y; + ppt->x = left_x + xorg; + ppt++; + *pwidth++ = right_x - left_x + 1; + } + y++; + + left_x += left_stepx; + left_e += left_dx; + if (left_e > 0) { + left_x += left_signdx; + left_e -= left_dy; + } + + right_x += right_stepx; + right_e += right_dx; + if (right_e > 0) { + right_x += right_signdx; + right_e -= right_dy; + } + } } spanRec.count = ppt - spanRec.points; - fillSpans (pDrawable, pGC, pixel, &spanRec, spanData); + fillSpans(pDrawable, pGC, pixel, &spanRec, spanData); } static void -miFillRectPolyHelper ( - DrawablePtr pDrawable, - GCPtr pGC, - unsigned long pixel, - SpanDataPtr spanData, - int x, - int y, - int w, - int h) +miFillRectPolyHelper(DrawablePtr pDrawable, + GCPtr pGC, + unsigned long pixel, + SpanDataPtr spanData, int x, int y, int w, int h) { DDXPointPtr ppt; - int *pwidth; - ChangeGCVal oldPixel, tmpPixel; - Spans spanRec; - xRectangle rect; - - if (!spanData) - { - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - oldPixel.val = pGC->fgPixel; - if (pixel != oldPixel.val) - { - tmpPixel.val = (XID)pixel; - ChangeGC (NullClient, pGC, GCForeground, &tmpPixel); - ValidateGC (pDrawable, pGC); - } - (*pGC->ops->PolyFillRect) (pDrawable, pGC, 1, &rect); - if (pixel != oldPixel.val) - { - ChangeGC (NullClient, pGC, GCForeground, &oldPixel); - ValidateGC (pDrawable, pGC); - } - } - else - { - if (!InitSpans(&spanRec, h)) - return; - ppt = spanRec.points; - pwidth = spanRec.widths; - - if (pGC->miTranslate) - { - y += pDrawable->y; - x += pDrawable->x; - } - while (h--) - { - ppt->x = x; - ppt->y = y; - ppt++; - *pwidth++ = w; - y++; - } - spanRec.count = ppt - spanRec.points; - AppendSpanGroup (pGC, pixel, &spanRec, spanData); + int *pwidth; + ChangeGCVal oldPixel, tmpPixel; + Spans spanRec; + xRectangle rect; + + if (!spanData) { + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + oldPixel.val = pGC->fgPixel; + if (pixel != oldPixel.val) { + tmpPixel.val = (XID) pixel; + ChangeGC(NullClient, pGC, GCForeground, &tmpPixel); + ValidateGC(pDrawable, pGC); + } + (*pGC->ops->PolyFillRect) (pDrawable, pGC, 1, &rect); + if (pixel != oldPixel.val) { + ChangeGC(NullClient, pGC, GCForeground, &oldPixel); + ValidateGC(pDrawable, pGC); + } + } + else { + if (!InitSpans(&spanRec, h)) + return; + ppt = spanRec.points; + pwidth = spanRec.widths; + + if (pGC->miTranslate) { + y += pDrawable->y; + x += pDrawable->x; + } + while (h--) { + ppt->x = x; + ppt->y = y; + ppt++; + *pwidth++ = w; + y++; + } + spanRec.count = ppt - spanRec.points; + AppendSpanGroup(pGC, pixel, &spanRec, spanData); } } /* static */ int -miPolyBuildEdge ( - double x0, - double y0, - double k, /* x0 * dy - y0 * dx */ - int dx, - int dy, - int xi, - int yi, - int left, - PolyEdgePtr edge) +miPolyBuildEdge(double x0, double y0, double k, /* x0 * dy - y0 * dx */ + int dx, int dy, int xi, int yi, int left, PolyEdgePtr edge) { - int x, y, e; - int xady; + int x, y, e; + int xady; - if (dy < 0) - { - dy = -dy; - dx = -dx; - k = -k; + if (dy < 0) { + dy = -dy; + dx = -dx; + k = -k; } #ifdef NOTDEF { - double realk, kerror; - realk = x0 * dy - y0 * dx; - kerror = fabs (realk - k); - if (kerror > .1) - printf ("realk: %g k: %g\n", realk, k); + double realk, kerror; + + realk = x0 * dy - y0 * dx; + kerror = fabs(realk - k); + if (kerror > .1) + printf("realk: %g k: %g\n", realk, k); } #endif - y = ICEIL (y0); - xady = ICEIL (k) + y * dx; + y = ICEIL(y0); + xady = ICEIL(k) + y * dx; if (xady <= 0) - x = - (-xady / dy) - 1; + x = -(-xady / dy) - 1; else - x = (xady - 1) / dy; + x = (xady - 1) / dy; e = xady - x * dy; - if (dx >= 0) - { - edge->signdx = 1; - edge->stepx = dx / dy; - edge->dx = dx % dy; + if (dx >= 0) { + edge->signdx = 1; + edge->stepx = dx / dy; + edge->dx = dx % dy; } - else - { - edge->signdx = -1; - edge->stepx = - (-dx / dy); - edge->dx = -dx % dy; - e = dy - e + 1; + else { + edge->signdx = -1; + edge->stepx = -(-dx / dy); + edge->dx = -dx % dy; + e = dy - e + 1; } edge->dy = dy; edge->x = x + left + xi; - edge->e = e - dy; /* bias to compare against 0 instead of dy */ + edge->e = e - dy; /* bias to compare against 0 instead of dy */ return y + yi; } #define StepAround(v, incr, max) (((v) + (incr) < 0) ? (max - 1) : ((v) + (incr) == max) ? 0 : ((v) + (incr))) /* static */ int -miPolyBuildPoly ( - PolyVertexPtr vertices, - PolySlopePtr slopes, - int count, - int xi, - int yi, - PolyEdgePtr left, - PolyEdgePtr right, - int *pnleft, - int *pnright, - int *h) +miPolyBuildPoly(PolyVertexPtr vertices, + PolySlopePtr slopes, + int count, + int xi, + int yi, + PolyEdgePtr left, + PolyEdgePtr right, int *pnleft, int *pnright, int *h) { - int top, bottom; - double miny, maxy; - int i; - int j; - int clockwise; - int slopeoff; - int s; - int nright, nleft; - int y, lasty = 0, bottomy, topy = 0; + int top, bottom; + double miny, maxy; + int i; + int j; + int clockwise; + int slopeoff; + int s; + int nright, nleft; + int y, lasty = 0, bottomy, topy = 0; /* find the top of the polygon */ maxy = miny = vertices[0].y; bottom = top = 0; - for (i = 1; i < count; i++) - { - if (vertices[i].y < miny) - { - top = i; - miny = vertices[i].y; - } - if (vertices[i].y >= maxy) - { - bottom = i; - maxy = vertices[i].y; - } + for (i = 1; i < count; i++) { + if (vertices[i].y < miny) { + top = i; + miny = vertices[i].y; + } + if (vertices[i].y >= maxy) { + bottom = i; + maxy = vertices[i].y; + } } clockwise = 1; slopeoff = 0; i = top; - j = StepAround (top, -1, count); + j = StepAround(top, -1, count); - if ((int64_t)slopes[j].dy * slopes[i].dx > (int64_t)slopes[i].dy * slopes[j].dx) - { - clockwise = -1; - slopeoff = -1; + if ((int64_t) slopes[j].dy * slopes[i].dx > + (int64_t) slopes[i].dy * slopes[j].dx) { + clockwise = -1; + slopeoff = -1; } - bottomy = ICEIL (maxy) + yi; + bottomy = ICEIL(maxy) + yi; nright = 0; - s = StepAround (top, slopeoff, count); + s = StepAround(top, slopeoff, count); i = top; - while (i != bottom) - { - if (slopes[s].dy != 0) - { - y = miPolyBuildEdge (vertices[i].x, vertices[i].y, - slopes[s].k, - slopes[s].dx, slopes[s].dy, - xi, yi, 0, - &right[nright]); - if (nright != 0) - right[nright-1].height = y - lasty; - else - topy = y; - nright++; - lasty = y; - } - - i = StepAround (i, clockwise, count); - s = StepAround (s, clockwise, count); + while (i != bottom) { + if (slopes[s].dy != 0) { + y = miPolyBuildEdge(vertices[i].x, vertices[i].y, + slopes[s].k, + slopes[s].dx, slopes[s].dy, + xi, yi, 0, &right[nright]); + if (nright != 0) + right[nright - 1].height = y - lasty; + else + topy = y; + nright++; + lasty = y; + } + + i = StepAround(i, clockwise, count); + s = StepAround(s, clockwise, count); } if (nright != 0) - right[nright-1].height = bottomy - lasty; + right[nright - 1].height = bottomy - lasty; if (slopeoff == 0) - slopeoff = -1; + slopeoff = -1; else - slopeoff = 0; + slopeoff = 0; nleft = 0; - s = StepAround (top, slopeoff, count); + s = StepAround(top, slopeoff, count); i = top; - while (i != bottom) - { - if (slopes[s].dy != 0) - { - y = miPolyBuildEdge (vertices[i].x, vertices[i].y, - slopes[s].k, - slopes[s].dx, slopes[s].dy, xi, yi, 1, - &left[nleft]); - - if (nleft != 0) - left[nleft-1].height = y - lasty; - nleft++; - lasty = y; - } - i = StepAround (i, -clockwise, count); - s = StepAround (s, -clockwise, count); + while (i != bottom) { + if (slopes[s].dy != 0) { + y = miPolyBuildEdge(vertices[i].x, vertices[i].y, + slopes[s].k, + slopes[s].dx, slopes[s].dy, xi, yi, 1, + &left[nleft]); + + if (nleft != 0) + left[nleft - 1].height = y - lasty; + nleft++; + lasty = y; + } + i = StepAround(i, -clockwise, count); + s = StepAround(s, -clockwise, count); } if (nleft != 0) - left[nleft-1].height = bottomy - lasty; + left[nleft - 1].height = bottomy - lasty; *pnleft = nleft; *pnright = nright; *h = bottomy - topy; @@ -476,198 +431,177 @@ miPolyBuildPoly ( } static void -miLineOnePoint ( - DrawablePtr pDrawable, - GCPtr pGC, - unsigned long pixel, - SpanDataPtr spanData, - int x, - int y) +miLineOnePoint(DrawablePtr pDrawable, + GCPtr pGC, + unsigned long pixel, SpanDataPtr spanData, int x, int y) { DDXPointRec pt; - int wid; - unsigned long oldPixel; - - MILINESETPIXEL (pDrawable, pGC, pixel, oldPixel); - if (pGC->fillStyle == FillSolid) - { - pt.x = x; - pt.y = y; - (*pGC->ops->PolyPoint) (pDrawable, pGC, CoordModeOrigin, 1, &pt); - } - else - { - wid = 1; - if (pGC->miTranslate) - { - x += pDrawable->x; - y += pDrawable->y; - } - pt.x = x; - pt.y = y; - (*pGC->ops->FillSpans) (pDrawable, pGC, 1, &pt, &wid, TRUE); - } - MILINERESETPIXEL (pDrawable, pGC, pixel, oldPixel); + int wid; + unsigned long oldPixel; + + MILINESETPIXEL(pDrawable, pGC, pixel, oldPixel); + if (pGC->fillStyle == FillSolid) { + pt.x = x; + pt.y = y; + (*pGC->ops->PolyPoint) (pDrawable, pGC, CoordModeOrigin, 1, &pt); + } + else { + wid = 1; + if (pGC->miTranslate) { + x += pDrawable->x; + y += pDrawable->y; + } + pt.x = x; + pt.y = y; + (*pGC->ops->FillSpans) (pDrawable, pGC, 1, &pt, &wid, TRUE); + } + MILINERESETPIXEL(pDrawable, pGC, pixel, oldPixel); } static void -miLineJoin ( - DrawablePtr pDrawable, - GCPtr pGC, - unsigned long pixel, - SpanDataPtr spanData, - LineFacePtr pLeft, - LineFacePtr pRight) +miLineJoin(DrawablePtr pDrawable, + GCPtr pGC, + unsigned long pixel, + SpanDataPtr spanData, LineFacePtr pLeft, LineFacePtr pRight) { - double mx = 0, my = 0; - double denom = 0.0; - PolyVertexRec vertices[4]; - PolySlopeRec slopes[4]; - int edgecount; - PolyEdgeRec left[4], right[4]; - int nleft, nright; - int y, height; - int swapslopes; - int joinStyle = pGC->joinStyle; - int lw = pGC->lineWidth; + double mx = 0, my = 0; + double denom = 0.0; + PolyVertexRec vertices[4]; + PolySlopeRec slopes[4]; + int edgecount; + PolyEdgeRec left[4], right[4]; + int nleft, nright; + int y, height; + int swapslopes; + int joinStyle = pGC->joinStyle; + int lw = pGC->lineWidth; if (lw == 1 && !spanData) { - /* See if one of the lines will draw the joining pixel */ - if (pLeft->dx > 0 || (pLeft->dx == 0 && pLeft->dy > 0)) - return; - if (pRight->dx > 0 || (pRight->dx == 0 && pRight->dy > 0)) - return; - if (joinStyle != JoinRound) { - denom = - pLeft->dx * (double)pRight->dy + pRight->dx * (double)pLeft->dy; - if (denom == 0) - return; /* no join to draw */ - } - if (joinStyle != JoinMiter) { - miLineOnePoint (pDrawable, pGC, pixel, spanData, pLeft->x, pLeft->y); - return; - } - } else { - if (joinStyle == JoinRound) - { - miLineArc(pDrawable, pGC, pixel, spanData, - pLeft, pRight, - (double)0.0, (double)0.0, TRUE); - return; - } - denom = - pLeft->dx * (double)pRight->dy + pRight->dx * (double)pLeft->dy; - if (denom == 0.0) - return; /* no join to draw */ + /* See if one of the lines will draw the joining pixel */ + if (pLeft->dx > 0 || (pLeft->dx == 0 && pLeft->dy > 0)) + return; + if (pRight->dx > 0 || (pRight->dx == 0 && pRight->dy > 0)) + return; + if (joinStyle != JoinRound) { + denom = + -pLeft->dx * (double) pRight->dy + + pRight->dx * (double) pLeft->dy; + if (denom == 0) + return; /* no join to draw */ + } + if (joinStyle != JoinMiter) { + miLineOnePoint(pDrawable, pGC, pixel, spanData, pLeft->x, pLeft->y); + return; + } + } + else { + if (joinStyle == JoinRound) { + miLineArc(pDrawable, pGC, pixel, spanData, + pLeft, pRight, (double) 0.0, (double) 0.0, TRUE); + return; + } + denom = + -pLeft->dx * (double) pRight->dy + pRight->dx * (double) pLeft->dy; + if (denom == 0.0) + return; /* no join to draw */ } swapslopes = 0; - if (denom > 0) - { - pLeft->xa = -pLeft->xa; - pLeft->ya = -pLeft->ya; - pLeft->dx = -pLeft->dx; - pLeft->dy = -pLeft->dy; + if (denom > 0) { + pLeft->xa = -pLeft->xa; + pLeft->ya = -pLeft->ya; + pLeft->dx = -pLeft->dx; + pLeft->dy = -pLeft->dy; } - else - { - swapslopes = 1; - pRight->xa = -pRight->xa; - pRight->ya = -pRight->ya; - pRight->dx = -pRight->dx; - pRight->dy = -pRight->dy; + else { + swapslopes = 1; + pRight->xa = -pRight->xa; + pRight->ya = -pRight->ya; + pRight->dx = -pRight->dx; + pRight->dy = -pRight->dy; } vertices[0].x = pRight->xa; vertices[0].y = pRight->ya; slopes[0].dx = -pRight->dy; - slopes[0].dy = pRight->dx; + slopes[0].dy = pRight->dx; slopes[0].k = 0; vertices[1].x = 0; vertices[1].y = 0; - slopes[1].dx = pLeft->dy; + slopes[1].dx = pLeft->dy; slopes[1].dy = -pLeft->dx; slopes[1].k = 0; vertices[2].x = pLeft->xa; vertices[2].y = pLeft->ya; - if (joinStyle == JoinMiter) - { - my = (pLeft->dy * (pRight->xa * pRight->dy - pRight->ya * pRight->dx) - - pRight->dy * (pLeft->xa * pLeft->dy - pLeft->ya * pLeft->dx )) / - denom; - if (pLeft->dy != 0) - { - mx = pLeft->xa + (my - pLeft->ya) * - (double) pLeft->dx / (double) pLeft->dy; - } - else - { - mx = pRight->xa + (my - pRight->ya) * - (double) pRight->dx / (double) pRight->dy; - } - /* check miter limit */ - if ((mx * mx + my * my) * 4 > SQSECANT * lw * lw) - joinStyle = JoinBevel; - } - - if (joinStyle == JoinMiter) - { - slopes[2].dx = pLeft->dx; - slopes[2].dy = pLeft->dy; - slopes[2].k = pLeft->k; - if (swapslopes) - { - slopes[2].dx = -slopes[2].dx; - slopes[2].dy = -slopes[2].dy; - slopes[2].k = -slopes[2].k; - } - vertices[3].x = mx; - vertices[3].y = my; - slopes[3].dx = pRight->dx; - slopes[3].dy = pRight->dy; - slopes[3].k = pRight->k; - if (swapslopes) - { - slopes[3].dx = -slopes[3].dx; - slopes[3].dy = -slopes[3].dy; - slopes[3].k = -slopes[3].k; - } - edgecount = 4; - } - else - { - double scale, dx, dy, adx, ady; - - adx = dx = pRight->xa - pLeft->xa; - ady = dy = pRight->ya - pLeft->ya; - if (adx < 0) - adx = -adx; - if (ady < 0) - ady = -ady; - scale = ady; - if (adx > ady) - scale = adx; - slopes[2].dx = (dx * 65536) / scale; - slopes[2].dy = (dy * 65536) / scale; - slopes[2].k = ((pLeft->xa + pRight->xa) * slopes[2].dy - - (pLeft->ya + pRight->ya) * slopes[2].dx) / 2.0; - edgecount = 3; - } - - y = miPolyBuildPoly (vertices, slopes, edgecount, pLeft->x, pLeft->y, - left, right, &nleft, &nright, &height); - miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, height, left, right, nleft, nright); + if (joinStyle == JoinMiter) { + my = (pLeft->dy * (pRight->xa * pRight->dy - pRight->ya * pRight->dx) - + pRight->dy * (pLeft->xa * pLeft->dy - pLeft->ya * pLeft->dx)) / + denom; + if (pLeft->dy != 0) { + mx = pLeft->xa + (my - pLeft->ya) * + (double) pLeft->dx / (double) pLeft->dy; + } + else { + mx = pRight->xa + (my - pRight->ya) * + (double) pRight->dx / (double) pRight->dy; + } + /* check miter limit */ + if ((mx * mx + my * my) * 4 > SQSECANT * lw * lw) + joinStyle = JoinBevel; + } + + if (joinStyle == JoinMiter) { + slopes[2].dx = pLeft->dx; + slopes[2].dy = pLeft->dy; + slopes[2].k = pLeft->k; + if (swapslopes) { + slopes[2].dx = -slopes[2].dx; + slopes[2].dy = -slopes[2].dy; + slopes[2].k = -slopes[2].k; + } + vertices[3].x = mx; + vertices[3].y = my; + slopes[3].dx = pRight->dx; + slopes[3].dy = pRight->dy; + slopes[3].k = pRight->k; + if (swapslopes) { + slopes[3].dx = -slopes[3].dx; + slopes[3].dy = -slopes[3].dy; + slopes[3].k = -slopes[3].k; + } + edgecount = 4; + } + else { + double scale, dx, dy, adx, ady; + + adx = dx = pRight->xa - pLeft->xa; + ady = dy = pRight->ya - pLeft->ya; + if (adx < 0) + adx = -adx; + if (ady < 0) + ady = -ady; + scale = ady; + if (adx > ady) + scale = adx; + slopes[2].dx = (dx * 65536) / scale; + slopes[2].dy = (dy * 65536) / scale; + slopes[2].k = ((pLeft->xa + pRight->xa) * slopes[2].dy - + (pLeft->ya + pRight->ya) * slopes[2].dx) / 2.0; + edgecount = 3; + } + + y = miPolyBuildPoly(vertices, slopes, edgecount, pLeft->x, pLeft->y, + left, right, &nleft, &nright, &height); + miFillPolyHelper(pDrawable, pGC, pixel, spanData, y, height, left, right, + nleft, nright); } static int -miLineArcI ( - DrawablePtr pDraw, - GCPtr pGC, - int xorg, - int yorg, - DDXPointPtr points, - int *widths) +miLineArcI(DrawablePtr pDraw, + GCPtr pGC, int xorg, int yorg, DDXPointPtr points, int *widths) { DDXPointPtr tpts, bpts; int *twids, *bwids; @@ -675,51 +609,46 @@ miLineArcI ( tpts = points; twids = widths; - if (pGC->miTranslate) - { - xorg += pDraw->x; - yorg += pDraw->y; + if (pGC->miTranslate) { + xorg += pDraw->x; + yorg += pDraw->y; } slw = pGC->lineWidth; - if (slw == 1) - { - tpts->x = xorg; - tpts->y = yorg; - *twids = 1; - return 1; + if (slw == 1) { + tpts->x = xorg; + tpts->y = yorg; + *twids = 1; + return 1; } bpts = tpts + slw; bwids = twids + slw; y = (slw >> 1) + 1; if (slw & 1) - e = - ((y << 2) + 3); + e = -((y << 2) + 3); else - e = - (y << 3); + e = -(y << 3); ex = -4; x = 0; - while (y) - { - e += (y << 3) - 4; - while (e >= 0) - { - x++; - e += (ex = -((x << 3) + 4)); - } - y--; - slw = (x << 1) + 1; - if ((e == ex) && (slw > 1)) - slw--; - tpts->x = xorg - x; - tpts->y = yorg - y; - tpts++; - *twids++ = slw; - if ((y != 0) && ((slw > 1) || (e != ex))) - { - bpts--; - bpts->x = xorg - x; - bpts->y = yorg + y; - *--bwids = slw; - } + while (y) { + e += (y << 3) - 4; + while (e >= 0) { + x++; + e += (ex = -((x << 3) + 4)); + } + y--; + slw = (x << 1) + 1; + if ((e == ex) && (slw > 1)) + slw--; + tpts->x = xorg - x; + tpts->y = yorg - y; + tpts++; + *twids++ = slw; + if ((y != 0) && ((slw > 1) || (e != ex))) { + bpts--; + bpts->x = xorg - x; + bpts->y = yorg + y; + *--bwids = slw; + } } return pGC->lineWidth; } @@ -748,19 +677,15 @@ miLineArcI ( } static int -miLineArcD ( - DrawablePtr pDraw, - GCPtr pGC, - double xorg, - double yorg, - DDXPointPtr points, - int *widths, - PolyEdgePtr edge1, - int edgey1, - Bool edgeleft1, - PolyEdgePtr edge2, - int edgey2, - Bool edgeleft2) +miLineArcD(DrawablePtr pDraw, + GCPtr pGC, + double xorg, + double yorg, + DDXPointPtr points, + int *widths, + PolyEdgePtr edge1, + int edgey1, + Bool edgeleft1, PolyEdgePtr edge2, int edgey2, Bool edgeleft2) { DDXPointPtr pts; int *wids; @@ -774,226 +699,204 @@ miLineArcD ( wids = widths; xbase = floor(xorg); x0 = xorg - xbase; - ybase = ICEIL (yorg); + ybase = ICEIL(yorg); y0 = yorg - ybase; - if (pGC->miTranslate) - { - xbase += pDraw->x; - ybase += pDraw->y; - edge1->x += pDraw->x; - edge2->x += pDraw->x; - edgey1 += pDraw->y; - edgey2 += pDraw->y; + if (pGC->miTranslate) { + xbase += pDraw->x; + ybase += pDraw->y; + edge1->x += pDraw->x; + edge2->x += pDraw->x; + edgey1 += pDraw->y; + edgey2 += pDraw->y; } xlk = x0 + x0 + 1.0; xrk = x0 + x0 - 1.0; yk = y0 + y0 - 1.0; - radius = ((double)pGC->lineWidth) / 2.0; + radius = ((double) pGC->lineWidth) / 2.0; y = floor(radius - y0 + 1.0); ybase -= y; ymin = ybase; ymax = 65536; edge1IsMin = FALSE; ymin1 = edgey1; - if (edge1->dy >= 0) - { - if (!edge1->dy) - { - if (edgeleft1) - edge1IsMin = TRUE; - else - ymax = edgey1; - edgey1 = 65536; - } - else - { - if ((edge1->signdx < 0) == edgeleft1) - edge1IsMin = TRUE; - } + if (edge1->dy >= 0) { + if (!edge1->dy) { + if (edgeleft1) + edge1IsMin = TRUE; + else + ymax = edgey1; + edgey1 = 65536; + } + else { + if ((edge1->signdx < 0) == edgeleft1) + edge1IsMin = TRUE; + } } edge2IsMin = FALSE; ymin2 = edgey2; - if (edge2->dy >= 0) - { - if (!edge2->dy) - { - if (edgeleft2) - edge2IsMin = TRUE; - else - ymax = edgey2; - edgey2 = 65536; - } - else - { - if ((edge2->signdx < 0) == edgeleft2) - edge2IsMin = TRUE; - } - } - if (edge1IsMin) - { - ymin = ymin1; - if (edge2IsMin && ymin1 > ymin2) - ymin = ymin2; - } else if (edge2IsMin) - ymin = ymin2; + if (edge2->dy >= 0) { + if (!edge2->dy) { + if (edgeleft2) + edge2IsMin = TRUE; + else + ymax = edgey2; + edgey2 = 65536; + } + else { + if ((edge2->signdx < 0) == edgeleft2) + edge2IsMin = TRUE; + } + } + if (edge1IsMin) { + ymin = ymin1; + if (edge2IsMin && ymin1 > ymin2) + ymin = ymin2; + } + else if (edge2IsMin) + ymin = ymin2; el = radius * radius - ((y + y0) * (y + y0)) - (x0 * x0); er = el + xrk; xl = 1; xr = 0; - if (x0 < 0.5) - { - xl = 0; - el -= xlk; + if (x0 < 0.5) { + xl = 0; + el -= xlk; } boty = (y0 < -0.5) ? 1 : 0; if (ybase + y - boty > ymax) - boty = ymax - ybase - y; - while (y > boty) - { - k = (y << 1) + yk; - er += k; - while (er > 0.0) - { - xr++; - er += xrk - (xr << 1); - } - el += k; - while (el >= 0.0) - { - xl--; - el += (xl << 1) - xlk; - } - y--; - ybase++; - if (ybase < ymin) - continue; - xcl = xl + xbase; - xcr = xr + xbase; - CLIPSTEPEDGE(edgey1, edge1, edgeleft1); - CLIPSTEPEDGE(edgey2, edge2, edgeleft2); - if (xcr >= xcl) - { - pts->x = xcl; - pts->y = ybase; - pts++; - *wids++ = xcr - xcl + 1; - } + boty = ymax - ybase - y; + while (y > boty) { + k = (y << 1) + yk; + er += k; + while (er > 0.0) { + xr++; + er += xrk - (xr << 1); + } + el += k; + while (el >= 0.0) { + xl--; + el += (xl << 1) - xlk; + } + y--; + ybase++; + if (ybase < ymin) + continue; + xcl = xl + xbase; + xcr = xr + xbase; + CLIPSTEPEDGE(edgey1, edge1, edgeleft1); + CLIPSTEPEDGE(edgey2, edge2, edgeleft2); + if (xcr >= xcl) { + pts->x = xcl; + pts->y = ybase; + pts++; + *wids++ = xcr - xcl + 1; + } } er = xrk - (xr << 1) - er; el = (xl << 1) - xlk - el; boty = floor(-y0 - radius + 1.0); if (ybase + y - boty > ymax) - boty = ymax - ybase - y; - while (y > boty) - { - k = (y << 1) + yk; - er -= k; - while ((er >= 0.0) && (xr >= 0)) - { - xr--; - er += xrk - (xr << 1); - } - el -= k; - while ((el > 0.0) && (xl <= 0)) - { - xl++; - el += (xl << 1) - xlk; - } - y--; - ybase++; - if (ybase < ymin) - continue; - xcl = xl + xbase; - xcr = xr + xbase; - CLIPSTEPEDGE(edgey1, edge1, edgeleft1); - CLIPSTEPEDGE(edgey2, edge2, edgeleft2); - if (xcr >= xcl) - { - pts->x = xcl; - pts->y = ybase; - pts++; - *wids++ = xcr - xcl + 1; - } + boty = ymax - ybase - y; + while (y > boty) { + k = (y << 1) + yk; + er -= k; + while ((er >= 0.0) && (xr >= 0)) { + xr--; + er += xrk - (xr << 1); + } + el -= k; + while ((el > 0.0) && (xl <= 0)) { + xl++; + el += (xl << 1) - xlk; + } + y--; + ybase++; + if (ybase < ymin) + continue; + xcl = xl + xbase; + xcr = xr + xbase; + CLIPSTEPEDGE(edgey1, edge1, edgeleft1); + CLIPSTEPEDGE(edgey2, edge2, edgeleft2); + if (xcr >= xcl) { + pts->x = xcl; + pts->y = ybase; + pts++; + *wids++ = xcr - xcl + 1; + } } return pts - points; } static int -miRoundJoinFace (LineFacePtr face, PolyEdgePtr edge, Bool *leftEdge) +miRoundJoinFace(LineFacePtr face, PolyEdgePtr edge, Bool *leftEdge) { - int y; - int dx, dy; - double xa, ya; - Bool left; + int y; + int dx, dy; + double xa, ya; + Bool left; dx = -face->dy; dy = face->dx; xa = face->xa; ya = face->ya; left = 1; - if (ya > 0) - { - ya = 0.0; - xa = 0.0; + if (ya > 0) { + ya = 0.0; + xa = 0.0; } - if (dy < 0 || (dy == 0 && dx > 0)) - { - dx = -dx; - dy = -dy; - left = !left; + if (dy < 0 || (dy == 0 && dx > 0)) { + dx = -dx; + dy = -dy; + left = !left; } if (dx == 0 && dy == 0) - dy = 1; - if (dy == 0) - { - y = ICEIL (face->ya) + face->y; - edge->x = -32767; - edge->stepx = 0; - edge->signdx = 0; - edge->e = -1; - edge->dy = 0; - edge->dx = 0; - edge->height = 0; - } - else - { - y = miPolyBuildEdge (xa, ya, 0.0, dx, dy, face->x, face->y, !left, edge); - edge->height = 32767; + dy = 1; + if (dy == 0) { + y = ICEIL(face->ya) + face->y; + edge->x = -32767; + edge->stepx = 0; + edge->signdx = 0; + edge->e = -1; + edge->dy = 0; + edge->dx = 0; + edge->height = 0; + } + else { + y = miPolyBuildEdge(xa, ya, 0.0, dx, dy, face->x, face->y, !left, edge); + edge->height = 32767; } *leftEdge = !left; return y; } void -miRoundJoinClip (LineFacePtr pLeft, LineFacePtr pRight, - PolyEdgePtr edge1, PolyEdgePtr edge2, - int *y1, int *y2, Bool *left1, Bool *left2) +miRoundJoinClip(LineFacePtr pLeft, LineFacePtr pRight, + PolyEdgePtr edge1, PolyEdgePtr edge2, + int *y1, int *y2, Bool *left1, Bool *left2) { - double denom; + double denom; - denom = - pLeft->dx * (double)pRight->dy + pRight->dx * (double)pLeft->dy; + denom = -pLeft->dx * (double) pRight->dy + pRight->dx * (double) pLeft->dy; - if (denom >= 0) - { - pLeft->xa = -pLeft->xa; - pLeft->ya = -pLeft->ya; + if (denom >= 0) { + pLeft->xa = -pLeft->xa; + pLeft->ya = -pLeft->ya; } - else - { - pRight->xa = -pRight->xa; - pRight->ya = -pRight->ya; + else { + pRight->xa = -pRight->xa; + pRight->ya = -pRight->ya; } - *y1 = miRoundJoinFace (pLeft, edge1, left1); - *y2 = miRoundJoinFace (pRight, edge2, left2); + *y1 = miRoundJoinFace(pLeft, edge1, left1); + *y2 = miRoundJoinFace(pRight, edge2, left2); } int -miRoundCapClip (LineFacePtr face, Bool isInt, PolyEdgePtr edge, Bool *leftEdge) +miRoundCapClip(LineFacePtr face, Bool isInt, PolyEdgePtr edge, Bool *leftEdge) { - int y; - int dx, dy; - double xa, ya, k; - Bool left; + int y; + int dx, dy; + double xa, ya, k; + Bool left; dx = -face->dy; dy = face->dx; @@ -1001,326 +904,300 @@ miRoundCapClip (LineFacePtr face, Bool isInt, PolyEdgePtr edge, Bool *leftEdge) ya = face->ya; k = 0.0; if (!isInt) - k = face->k; + k = face->k; left = 1; - if (dy < 0 || (dy == 0 && dx > 0)) - { - dx = -dx; - dy = -dy; - xa = -xa; - ya = -ya; - left = !left; + if (dy < 0 || (dy == 0 && dx > 0)) { + dx = -dx; + dy = -dy; + xa = -xa; + ya = -ya; + left = !left; } if (dx == 0 && dy == 0) - dy = 1; - if (dy == 0) - { - y = ICEIL (face->ya) + face->y; - edge->x = -32767; - edge->stepx = 0; - edge->signdx = 0; - edge->e = -1; - edge->dy = 0; - edge->dx = 0; - edge->height = 0; - } - else - { - y = miPolyBuildEdge (xa, ya, k, dx, dy, face->x, face->y, !left, edge); - edge->height = 32767; + dy = 1; + if (dy == 0) { + y = ICEIL(face->ya) + face->y; + edge->x = -32767; + edge->stepx = 0; + edge->signdx = 0; + edge->e = -1; + edge->dy = 0; + edge->dx = 0; + edge->height = 0; + } + else { + y = miPolyBuildEdge(xa, ya, k, dx, dy, face->x, face->y, !left, edge); + edge->height = 32767; } *leftEdge = !left; return y; } static void -miLineArc ( - DrawablePtr pDraw, - GCPtr pGC, - unsigned long pixel, - SpanDataPtr spanData, - LineFacePtr leftFace, - LineFacePtr rightFace, - double xorg, - double yorg, - Bool isInt) +miLineArc(DrawablePtr pDraw, + GCPtr pGC, + unsigned long pixel, + SpanDataPtr spanData, + LineFacePtr leftFace, + LineFacePtr rightFace, double xorg, double yorg, Bool isInt) { int xorgi = 0, yorgi = 0; Spans spanRec; int n; - PolyEdgeRec edge1, edge2; - int edgey1, edgey2; - Bool edgeleft1, edgeleft2; + PolyEdgeRec edge1, edge2; + int edgey1, edgey2; + Bool edgeleft1, edgeleft2; - if (isInt) - { - xorgi = leftFace ? leftFace->x : rightFace->x; - yorgi = leftFace ? leftFace->y : rightFace->y; + if (isInt) { + xorgi = leftFace ? leftFace->x : rightFace->x; + yorgi = leftFace ? leftFace->y : rightFace->y; } edgey1 = 65536; edgey2 = 65536; - edge1.x = 0; /* not used, keep memory checkers happy */ + edge1.x = 0; /* not used, keep memory checkers happy */ edge1.dy = -1; - edge2.x = 0; /* not used, keep memory checkers happy */ + edge2.x = 0; /* not used, keep memory checkers happy */ edge2.dy = -1; edgeleft1 = FALSE; edgeleft2 = FALSE; if ((pGC->lineStyle != LineSolid || pGC->lineWidth > 2) && - ((pGC->capStyle == CapRound && pGC->joinStyle != JoinRound) || - (pGC->joinStyle == JoinRound && pGC->capStyle == CapButt))) - { - if (isInt) - { - xorg = (double) xorgi; - yorg = (double) yorgi; - } - if (leftFace && rightFace) - { - miRoundJoinClip (leftFace, rightFace, &edge1, &edge2, - &edgey1, &edgey2, &edgeleft1, &edgeleft2); - } - else if (leftFace) - { - edgey1 = miRoundCapClip (leftFace, isInt, &edge1, &edgeleft1); - } - else if (rightFace) - { - edgey2 = miRoundCapClip (rightFace, isInt, &edge2, &edgeleft2); - } - isInt = FALSE; + ((pGC->capStyle == CapRound && pGC->joinStyle != JoinRound) || + (pGC->joinStyle == JoinRound && pGC->capStyle == CapButt))) { + if (isInt) { + xorg = (double) xorgi; + yorg = (double) yorgi; + } + if (leftFace && rightFace) { + miRoundJoinClip(leftFace, rightFace, &edge1, &edge2, + &edgey1, &edgey2, &edgeleft1, &edgeleft2); + } + else if (leftFace) { + edgey1 = miRoundCapClip(leftFace, isInt, &edge1, &edgeleft1); + } + else if (rightFace) { + edgey2 = miRoundCapClip(rightFace, isInt, &edge2, &edgeleft2); + } + isInt = FALSE; } if (!InitSpans(&spanRec, pGC->lineWidth)) - return; + return; if (isInt) - n = miLineArcI(pDraw, pGC, xorgi, yorgi, spanRec.points, spanRec.widths); + n = miLineArcI(pDraw, pGC, xorgi, yorgi, spanRec.points, + spanRec.widths); else - n = miLineArcD(pDraw, pGC, xorg, yorg, spanRec.points, spanRec.widths, - &edge1, edgey1, edgeleft1, - &edge2, edgey2, edgeleft2); + n = miLineArcD(pDraw, pGC, xorg, yorg, spanRec.points, spanRec.widths, + &edge1, edgey1, edgeleft1, &edge2, edgey2, edgeleft2); spanRec.count = n; - fillSpans (pDraw, pGC, pixel, &spanRec, spanData); + fillSpans(pDraw, pGC, pixel, &spanRec, spanData); } static void -miLineProjectingCap (DrawablePtr pDrawable, GCPtr pGC, unsigned long pixel, - SpanDataPtr spanData, LineFacePtr face, Bool isLeft, - double xorg, double yorg, Bool isInt) +miLineProjectingCap(DrawablePtr pDrawable, GCPtr pGC, unsigned long pixel, + SpanDataPtr spanData, LineFacePtr face, Bool isLeft, + double xorg, double yorg, Bool isInt) { - int xorgi = 0, yorgi = 0; - int lw; - PolyEdgeRec lefts[2], rights[2]; - int lefty, righty, topy, bottomy; + int xorgi = 0, yorgi = 0; + int lw; + PolyEdgeRec lefts[2], rights[2]; + int lefty, righty, topy, bottomy; PolyEdgePtr left, right; - PolyEdgePtr top, bottom; - double xa,ya; - double k; - double xap, yap; - int dx, dy; - double projectXoff, projectYoff; - double maxy; - int finaly; - - if (isInt) - { - xorgi = face->x; - yorgi = face->y; + PolyEdgePtr top, bottom; + double xa, ya; + double k; + double xap, yap; + int dx, dy; + double projectXoff, projectYoff; + double maxy; + int finaly; + + if (isInt) { + xorgi = face->x; + yorgi = face->y; } lw = pGC->lineWidth; dx = face->dx; dy = face->dy; k = face->k; - if (dy == 0) - { - lefts[0].height = lw; - lefts[0].x = xorgi; - if (isLeft) - lefts[0].x -= (lw >> 1); - lefts[0].stepx = 0; - lefts[0].signdx = 1; - lefts[0].e = -lw; - lefts[0].dx = 0; - lefts[0].dy = lw; - rights[0].height = lw; - rights[0].x = xorgi; - if (!isLeft) - rights[0].x += ((lw + 1) >> 1); - rights[0].stepx = 0; - rights[0].signdx = 1; - rights[0].e = -lw; - rights[0].dx = 0; - rights[0].dy = lw; - miFillPolyHelper (pDrawable, pGC, pixel, spanData, yorgi - (lw >> 1), lw, - lefts, rights, 1, 1); - } - else if (dx == 0) - { - if (dy < 0) { - dy = -dy; - isLeft = !isLeft; - } - topy = yorgi; - bottomy = yorgi + dy; - if (isLeft) - topy -= (lw >> 1); - else - bottomy += (lw >> 1); - lefts[0].height = bottomy - topy; - lefts[0].x = xorgi - (lw >> 1); - lefts[0].stepx = 0; - lefts[0].signdx = 1; - lefts[0].e = -dy; - lefts[0].dx = dx; - lefts[0].dy = dy; - - rights[0].height = bottomy - topy; - rights[0].x = lefts[0].x + (lw-1); - rights[0].stepx = 0; - rights[0].signdx = 1; - rights[0].e = -dy; - rights[0].dx = dx; - rights[0].dy = dy; - miFillPolyHelper (pDrawable, pGC, pixel, spanData, topy, bottomy - topy, lefts, rights, 1, 1); - } - else - { - xa = face->xa; - ya = face->ya; - projectXoff = -ya; - projectYoff = xa; - if (dx < 0) - { - right = &rights[1]; - left = &lefts[0]; - top = &rights[0]; - bottom = &lefts[1]; - } - else - { - right = &rights[0]; - left = &lefts[1]; - top = &lefts[0]; - bottom = &rights[1]; - } - if (isLeft) - { - righty = miPolyBuildEdge (xa, ya, - k, dx, dy, xorgi, yorgi, 0, right); - - xa = -xa; - ya = -ya; - k = -k; - lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff, - k, dx, dy, xorgi, yorgi, 1, left); - if (dx > 0) - { - ya = -ya; - xa = -xa; - } - xap = xa - projectXoff; - yap = ya - projectYoff; - topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy, - -dy, dx, xorgi, yorgi, dx > 0, top); - bottomy = miPolyBuildEdge (xa, ya, - 0.0, -dy, dx, xorgi, yorgi, dx < 0, bottom); - maxy = -ya; - } - else - { - righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff, - k, dx, dy, xorgi, yorgi, 0, right); - - xa = -xa; - ya = -ya; - k = -k; - lefty = miPolyBuildEdge (xa, ya, - k, dx, dy, xorgi, yorgi, 1, left); - if (dx > 0) - { - ya = -ya; - xa = -xa; - } - xap = xa - projectXoff; - yap = ya - projectYoff; - topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, xorgi, xorgi, dx > 0, top); - bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy, - -dy, dx, xorgi, xorgi, dx < 0, bottom); - maxy = -ya + projectYoff; - } - finaly = ICEIL(maxy) + yorgi; - if (dx < 0) - { - left->height = bottomy - lefty; - right->height = finaly - righty; - top->height = righty - topy; - } - else - { - right->height = bottomy - righty; - left->height = finaly - lefty; - top->height = lefty - topy; - } - bottom->height = finaly - bottomy; - miFillPolyHelper (pDrawable, pGC, pixel, spanData, topy, - bottom->height + bottomy - topy, lefts, rights, 2, 2); + if (dy == 0) { + lefts[0].height = lw; + lefts[0].x = xorgi; + if (isLeft) + lefts[0].x -= (lw >> 1); + lefts[0].stepx = 0; + lefts[0].signdx = 1; + lefts[0].e = -lw; + lefts[0].dx = 0; + lefts[0].dy = lw; + rights[0].height = lw; + rights[0].x = xorgi; + if (!isLeft) + rights[0].x += ((lw + 1) >> 1); + rights[0].stepx = 0; + rights[0].signdx = 1; + rights[0].e = -lw; + rights[0].dx = 0; + rights[0].dy = lw; + miFillPolyHelper(pDrawable, pGC, pixel, spanData, yorgi - (lw >> 1), lw, + lefts, rights, 1, 1); + } + else if (dx == 0) { + if (dy < 0) { + dy = -dy; + isLeft = !isLeft; + } + topy = yorgi; + bottomy = yorgi + dy; + if (isLeft) + topy -= (lw >> 1); + else + bottomy += (lw >> 1); + lefts[0].height = bottomy - topy; + lefts[0].x = xorgi - (lw >> 1); + lefts[0].stepx = 0; + lefts[0].signdx = 1; + lefts[0].e = -dy; + lefts[0].dx = dx; + lefts[0].dy = dy; + + rights[0].height = bottomy - topy; + rights[0].x = lefts[0].x + (lw - 1); + rights[0].stepx = 0; + rights[0].signdx = 1; + rights[0].e = -dy; + rights[0].dx = dx; + rights[0].dy = dy; + miFillPolyHelper(pDrawable, pGC, pixel, spanData, topy, bottomy - topy, + lefts, rights, 1, 1); + } + else { + xa = face->xa; + ya = face->ya; + projectXoff = -ya; + projectYoff = xa; + if (dx < 0) { + right = &rights[1]; + left = &lefts[0]; + top = &rights[0]; + bottom = &lefts[1]; + } + else { + right = &rights[0]; + left = &lefts[1]; + top = &lefts[0]; + bottom = &rights[1]; + } + if (isLeft) { + righty = miPolyBuildEdge(xa, ya, k, dx, dy, xorgi, yorgi, 0, right); + + xa = -xa; + ya = -ya; + k = -k; + lefty = miPolyBuildEdge(xa - projectXoff, ya - projectYoff, + k, dx, dy, xorgi, yorgi, 1, left); + if (dx > 0) { + ya = -ya; + xa = -xa; + } + xap = xa - projectXoff; + yap = ya - projectYoff; + topy = miPolyBuildEdge(xap, yap, xap * dx + yap * dy, + -dy, dx, xorgi, yorgi, dx > 0, top); + bottomy = miPolyBuildEdge(xa, ya, + 0.0, -dy, dx, xorgi, yorgi, dx < 0, + bottom); + maxy = -ya; + } + else { + righty = miPolyBuildEdge(xa - projectXoff, ya - projectYoff, + k, dx, dy, xorgi, yorgi, 0, right); + + xa = -xa; + ya = -ya; + k = -k; + lefty = miPolyBuildEdge(xa, ya, k, dx, dy, xorgi, yorgi, 1, left); + if (dx > 0) { + ya = -ya; + xa = -xa; + } + xap = xa - projectXoff; + yap = ya - projectYoff; + topy = + miPolyBuildEdge(xa, ya, 0.0, -dy, dx, xorgi, xorgi, dx > 0, + top); + bottomy = + miPolyBuildEdge(xap, yap, xap * dx + yap * dy, -dy, dx, xorgi, + xorgi, dx < 0, bottom); + maxy = -ya + projectYoff; + } + finaly = ICEIL(maxy) + yorgi; + if (dx < 0) { + left->height = bottomy - lefty; + right->height = finaly - righty; + top->height = righty - topy; + } + else { + right->height = bottomy - righty; + left->height = finaly - lefty; + top->height = lefty - topy; + } + bottom->height = finaly - bottomy; + miFillPolyHelper(pDrawable, pGC, pixel, spanData, topy, + bottom->height + bottomy - topy, lefts, rights, 2, 2); } } static void -miWideSegment ( - DrawablePtr pDrawable, - GCPtr pGC, - unsigned long pixel, - SpanDataPtr spanData, - int x1, - int y1, - int x2, - int y2, - Bool projectLeft, - Bool projectRight, - LineFacePtr leftFace, - LineFacePtr rightFace) +miWideSegment(DrawablePtr pDrawable, + GCPtr pGC, + unsigned long pixel, + SpanDataPtr spanData, + int x1, + int y1, + int x2, + int y2, + Bool projectLeft, + Bool projectRight, LineFacePtr leftFace, LineFacePtr rightFace) { - double l, L, r; - double xa, ya; - double projectXoff = 0.0, projectYoff = 0.0; - double k; - double maxy; - int x, y; - int dx, dy; - int finaly; + double l, L, r; + double xa, ya; + double projectXoff = 0.0, projectYoff = 0.0; + double k; + double maxy; + int x, y; + int dx, dy; + int finaly; PolyEdgePtr left, right; - PolyEdgePtr top, bottom; - int lefty, righty, topy, bottomy; - int signdx; - PolyEdgeRec lefts[2], rights[2]; - LineFacePtr tface; - int lw = pGC->lineWidth; + PolyEdgePtr top, bottom; + int lefty, righty, topy, bottomy; + int signdx; + PolyEdgeRec lefts[2], rights[2]; + LineFacePtr tface; + int lw = pGC->lineWidth; /* draw top-to-bottom always */ - if (y2 < y1 || (y2 == y1 && x2 < x1)) - { - x = x1; - x1 = x2; - x2 = x; + if (y2 < y1 || (y2 == y1 && x2 < x1)) { + x = x1; + x1 = x2; + x2 = x; - y = y1; - y1 = y2; - y2 = y; + y = y1; + y1 = y2; + y2 = y; - x = projectLeft; - projectLeft = projectRight; - projectRight = x; + x = projectLeft; + projectLeft = projectRight; + projectRight = x; - tface = leftFace; - leftFace = rightFace; - rightFace = tface; + tface = leftFace; + leftFace = rightFace; + rightFace = tface; } dy = y2 - y1; signdx = 1; dx = x2 - x1; if (dx < 0) - signdx = -1; + signdx = -1; leftFace->x = x1; leftFace->y = y1; @@ -1332,327 +1209,293 @@ miWideSegment ( rightFace->dx = -dx; rightFace->dy = -dy; - if (dy == 0) - { - rightFace->xa = 0; - rightFace->ya = (double) lw / 2.0; - rightFace->k = -(double) (lw * dx) / 2.0; - leftFace->xa = 0; - leftFace->ya = -rightFace->ya; - leftFace->k = rightFace->k; - x = x1; - if (projectLeft) - x -= (lw >> 1); - y = y1 - (lw >> 1); - dx = x2 - x; - if (projectRight) - dx += ((lw + 1) >> 1); - dy = lw; - miFillRectPolyHelper (pDrawable, pGC, pixel, spanData, - x, y, dx, dy); - } - else if (dx == 0) - { - leftFace->xa = (double) lw / 2.0; - leftFace->ya = 0; - leftFace->k = (double) (lw * dy) / 2.0; - rightFace->xa = -leftFace->xa; - rightFace->ya = 0; - rightFace->k = leftFace->k; - y = y1; - if (projectLeft) - y -= lw >> 1; - x = x1 - (lw >> 1); - dy = y2 - y; - if (projectRight) - dy += ((lw + 1) >> 1); - dx = lw; - miFillRectPolyHelper (pDrawable, pGC, pixel, spanData, - x, y, dx, dy); - } - else - { - l = ((double) lw) / 2.0; - L = hypot ((double) dx, (double) dy); - - if (dx < 0) - { - right = &rights[1]; - left = &lefts[0]; - top = &rights[0]; - bottom = &lefts[1]; - } - else - { - right = &rights[0]; - left = &lefts[1]; - top = &lefts[0]; - bottom = &rights[1]; - } - r = l / L; - - /* coord of upper bound at integral y */ - ya = -r * dx; - xa = r * dy; - - if (projectLeft | projectRight) - { - projectXoff = -ya; - projectYoff = xa; - } - - /* xa * dy - ya * dx */ - k = l * L; - - leftFace->xa = xa; - leftFace->ya = ya; - leftFace->k = k; - rightFace->xa = -xa; - rightFace->ya = -ya; - rightFace->k = k; - - if (projectLeft) - righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff, - k, dx, dy, x1, y1, 0, right); - else - righty = miPolyBuildEdge (xa, ya, - k, dx, dy, x1, y1, 0, right); - - /* coord of lower bound at integral y */ - ya = -ya; - xa = -xa; - - /* xa * dy - ya * dx */ - k = - k; - - if (projectLeft) - lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff, - k, dx, dy, x1, y1, 1, left); - else - lefty = miPolyBuildEdge (xa, ya, - k, dx, dy, x1, y1, 1, left); - - /* coord of top face at integral y */ - - if (signdx > 0) - { - ya = -ya; - xa = -xa; - } - - if (projectLeft) - { - double xap = xa - projectXoff; - double yap = ya - projectYoff; - topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy, - -dy, dx, x1, y1, dx > 0, top); - } - else - topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, x1, y1, dx > 0, top); - - /* coord of bottom face at integral y */ - - if (projectRight) - { - double xap = xa + projectXoff; - double yap = ya + projectYoff; - bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy, - -dy, dx, x2, y2, dx < 0, bottom); - maxy = -ya + projectYoff; - } - else - { - bottomy = miPolyBuildEdge (xa, ya, - 0.0, -dy, dx, x2, y2, dx < 0, bottom); - maxy = -ya; - } - - finaly = ICEIL (maxy) + y2; - - if (dx < 0) - { - left->height = bottomy - lefty; - right->height = finaly - righty; - top->height = righty - topy; - } - else - { - right->height = bottomy - righty; - left->height = finaly - lefty; - top->height = lefty - topy; - } - bottom->height = finaly - bottomy; - miFillPolyHelper (pDrawable, pGC, pixel, spanData, topy, - bottom->height + bottomy - topy, lefts, rights, 2, 2); + if (dy == 0) { + rightFace->xa = 0; + rightFace->ya = (double) lw / 2.0; + rightFace->k = -(double) (lw * dx) / 2.0; + leftFace->xa = 0; + leftFace->ya = -rightFace->ya; + leftFace->k = rightFace->k; + x = x1; + if (projectLeft) + x -= (lw >> 1); + y = y1 - (lw >> 1); + dx = x2 - x; + if (projectRight) + dx += ((lw + 1) >> 1); + dy = lw; + miFillRectPolyHelper(pDrawable, pGC, pixel, spanData, x, y, dx, dy); + } + else if (dx == 0) { + leftFace->xa = (double) lw / 2.0; + leftFace->ya = 0; + leftFace->k = (double) (lw * dy) / 2.0; + rightFace->xa = -leftFace->xa; + rightFace->ya = 0; + rightFace->k = leftFace->k; + y = y1; + if (projectLeft) + y -= lw >> 1; + x = x1 - (lw >> 1); + dy = y2 - y; + if (projectRight) + dy += ((lw + 1) >> 1); + dx = lw; + miFillRectPolyHelper(pDrawable, pGC, pixel, spanData, x, y, dx, dy); + } + else { + l = ((double) lw) / 2.0; + L = hypot((double) dx, (double) dy); + + if (dx < 0) { + right = &rights[1]; + left = &lefts[0]; + top = &rights[0]; + bottom = &lefts[1]; + } + else { + right = &rights[0]; + left = &lefts[1]; + top = &lefts[0]; + bottom = &rights[1]; + } + r = l / L; + + /* coord of upper bound at integral y */ + ya = -r * dx; + xa = r * dy; + + if (projectLeft | projectRight) { + projectXoff = -ya; + projectYoff = xa; + } + + /* xa * dy - ya * dx */ + k = l * L; + + leftFace->xa = xa; + leftFace->ya = ya; + leftFace->k = k; + rightFace->xa = -xa; + rightFace->ya = -ya; + rightFace->k = k; + + if (projectLeft) + righty = miPolyBuildEdge(xa - projectXoff, ya - projectYoff, + k, dx, dy, x1, y1, 0, right); + else + righty = miPolyBuildEdge(xa, ya, k, dx, dy, x1, y1, 0, right); + + /* coord of lower bound at integral y */ + ya = -ya; + xa = -xa; + + /* xa * dy - ya * dx */ + k = -k; + + if (projectLeft) + lefty = miPolyBuildEdge(xa - projectXoff, ya - projectYoff, + k, dx, dy, x1, y1, 1, left); + else + lefty = miPolyBuildEdge(xa, ya, k, dx, dy, x1, y1, 1, left); + + /* coord of top face at integral y */ + + if (signdx > 0) { + ya = -ya; + xa = -xa; + } + + if (projectLeft) { + double xap = xa - projectXoff; + double yap = ya - projectYoff; + + topy = miPolyBuildEdge(xap, yap, xap * dx + yap * dy, + -dy, dx, x1, y1, dx > 0, top); + } + else + topy = miPolyBuildEdge(xa, ya, 0.0, -dy, dx, x1, y1, dx > 0, top); + + /* coord of bottom face at integral y */ + + if (projectRight) { + double xap = xa + projectXoff; + double yap = ya + projectYoff; + + bottomy = miPolyBuildEdge(xap, yap, xap * dx + yap * dy, + -dy, dx, x2, y2, dx < 0, bottom); + maxy = -ya + projectYoff; + } + else { + bottomy = miPolyBuildEdge(xa, ya, + 0.0, -dy, dx, x2, y2, dx < 0, bottom); + maxy = -ya; + } + + finaly = ICEIL(maxy) + y2; + + if (dx < 0) { + left->height = bottomy - lefty; + right->height = finaly - righty; + top->height = righty - topy; + } + else { + right->height = bottomy - righty; + left->height = finaly - lefty; + top->height = lefty - topy; + } + bottom->height = finaly - bottomy; + miFillPolyHelper(pDrawable, pGC, pixel, spanData, topy, + bottom->height + bottomy - topy, lefts, rights, 2, 2); } } static SpanDataPtr -miSetupSpanData (GCPtr pGC, SpanDataPtr spanData, int npt) +miSetupSpanData(GCPtr pGC, SpanDataPtr spanData, int npt) { if ((npt < 3 && pGC->capStyle != CapRound) || miSpansEasyRop(pGC->alu)) - return (SpanDataPtr) NULL; + return (SpanDataPtr) NULL; if (pGC->lineStyle == LineDoubleDash) - miInitSpanGroup (&spanData->bgGroup); - miInitSpanGroup (&spanData->fgGroup); + miInitSpanGroup(&spanData->bgGroup); + miInitSpanGroup(&spanData->fgGroup); return spanData; } static void -miCleanupSpanData (DrawablePtr pDrawable, GCPtr pGC, SpanDataPtr spanData) +miCleanupSpanData(DrawablePtr pDrawable, GCPtr pGC, SpanDataPtr spanData) { - if (pGC->lineStyle == LineDoubleDash) - { - ChangeGCVal oldPixel, pixel; - pixel.val = pGC->bgPixel; - oldPixel.val = pGC->fgPixel; - if (pixel.val != oldPixel.val) - { - ChangeGC (NullClient, pGC, GCForeground, &pixel); - ValidateGC (pDrawable, pGC); - } - miFillUniqueSpanGroup (pDrawable, pGC, &spanData->bgGroup); - miFreeSpanGroup (&spanData->bgGroup); - if (pixel.val != oldPixel.val) - { - ChangeGC (NullClient, pGC, GCForeground, &oldPixel); - ValidateGC (pDrawable, pGC); - } - } - miFillUniqueSpanGroup (pDrawable, pGC, &spanData->fgGroup); - miFreeSpanGroup (&spanData->fgGroup); + if (pGC->lineStyle == LineDoubleDash) { + ChangeGCVal oldPixel, pixel; + + pixel.val = pGC->bgPixel; + oldPixel.val = pGC->fgPixel; + if (pixel.val != oldPixel.val) { + ChangeGC(NullClient, pGC, GCForeground, &pixel); + ValidateGC(pDrawable, pGC); + } + miFillUniqueSpanGroup(pDrawable, pGC, &spanData->bgGroup); + miFreeSpanGroup(&spanData->bgGroup); + if (pixel.val != oldPixel.val) { + ChangeGC(NullClient, pGC, GCForeground, &oldPixel); + ValidateGC(pDrawable, pGC); + } + } + miFillUniqueSpanGroup(pDrawable, pGC, &spanData->fgGroup); + miFreeSpanGroup(&spanData->fgGroup); } void -miWideLine (DrawablePtr pDrawable, GCPtr pGC, - int mode, int npt, DDXPointPtr pPts) +miWideLine(DrawablePtr pDrawable, GCPtr pGC, + int mode, int npt, DDXPointPtr pPts) { - int x1, y1, x2, y2; - SpanDataRec spanDataRec; - SpanDataPtr spanData; - long pixel; - Bool projectLeft, projectRight; - LineFaceRec leftFace, rightFace, prevRightFace; - LineFaceRec firstFace; - int first; - Bool somethingDrawn = FALSE; - Bool selfJoin; - - spanData = miSetupSpanData (pGC, &spanDataRec, npt); + int x1, y1, x2, y2; + SpanDataRec spanDataRec; + SpanDataPtr spanData; + long pixel; + Bool projectLeft, projectRight; + LineFaceRec leftFace, rightFace, prevRightFace; + LineFaceRec firstFace; + int first; + Bool somethingDrawn = FALSE; + Bool selfJoin; + + spanData = miSetupSpanData(pGC, &spanDataRec, npt); pixel = pGC->fgPixel; x2 = pPts->x; y2 = pPts->y; first = TRUE; selfJoin = FALSE; - if (npt > 1) - { - if (mode == CoordModePrevious) - { - int nptTmp; - DDXPointPtr pPtsTmp; - - x1 = x2; - y1 = y2; - nptTmp = npt; - pPtsTmp = pPts + 1; - while (--nptTmp) - { - x1 += pPtsTmp->x; - y1 += pPtsTmp->y; - ++pPtsTmp; - } - if (x2 == x1 && y2 == y1) - selfJoin = TRUE; - } - else if (x2 == pPts[npt-1].x && y2 == pPts[npt-1].y) - { - selfJoin = TRUE; - } + if (npt > 1) { + if (mode == CoordModePrevious) { + int nptTmp; + DDXPointPtr pPtsTmp; + + x1 = x2; + y1 = y2; + nptTmp = npt; + pPtsTmp = pPts + 1; + while (--nptTmp) { + x1 += pPtsTmp->x; + y1 += pPtsTmp->y; + ++pPtsTmp; + } + if (x2 == x1 && y2 == y1) + selfJoin = TRUE; + } + else if (x2 == pPts[npt - 1].x && y2 == pPts[npt - 1].y) { + selfJoin = TRUE; + } } projectLeft = pGC->capStyle == CapProjecting && !selfJoin; projectRight = FALSE; - while (--npt) - { - x1 = x2; - y1 = y2; - ++pPts; - x2 = pPts->x; - y2 = pPts->y; - if (mode == CoordModePrevious) - { - x2 += x1; - y2 += y1; - } - if (x1 != x2 || y1 != y2) - { - somethingDrawn = TRUE; - if (npt == 1 && pGC->capStyle == CapProjecting && !selfJoin) - projectRight = TRUE; - miWideSegment (pDrawable, pGC, pixel, spanData, x1, y1, x2, y2, - projectLeft, projectRight, &leftFace, &rightFace); - if (first) - { - if (selfJoin) - firstFace = leftFace; - else if (pGC->capStyle == CapRound) - { - if (pGC->lineWidth == 1 && !spanData) - miLineOnePoint (pDrawable, pGC, pixel, spanData, x1, y1); - else - miLineArc (pDrawable, pGC, pixel, spanData, - &leftFace, (LineFacePtr) NULL, - (double)0.0, (double)0.0, - TRUE); - } - } - else - { - miLineJoin (pDrawable, pGC, pixel, spanData, &leftFace, - &prevRightFace); - } - prevRightFace = rightFace; - first = FALSE; - projectLeft = FALSE; - } - if (npt == 1 && somethingDrawn) - { - if (selfJoin) - miLineJoin (pDrawable, pGC, pixel, spanData, &firstFace, - &rightFace); - else if (pGC->capStyle == CapRound) - { - if (pGC->lineWidth == 1 && !spanData) - miLineOnePoint (pDrawable, pGC, pixel, spanData, x2, y2); - else - miLineArc (pDrawable, pGC, pixel, spanData, - (LineFacePtr) NULL, &rightFace, - (double)0.0, (double)0.0, - TRUE); - } - } + while (--npt) { + x1 = x2; + y1 = y2; + ++pPts; + x2 = pPts->x; + y2 = pPts->y; + if (mode == CoordModePrevious) { + x2 += x1; + y2 += y1; + } + if (x1 != x2 || y1 != y2) { + somethingDrawn = TRUE; + if (npt == 1 && pGC->capStyle == CapProjecting && !selfJoin) + projectRight = TRUE; + miWideSegment(pDrawable, pGC, pixel, spanData, x1, y1, x2, y2, + projectLeft, projectRight, &leftFace, &rightFace); + if (first) { + if (selfJoin) + firstFace = leftFace; + else if (pGC->capStyle == CapRound) { + if (pGC->lineWidth == 1 && !spanData) + miLineOnePoint(pDrawable, pGC, pixel, spanData, x1, y1); + else + miLineArc(pDrawable, pGC, pixel, spanData, + &leftFace, (LineFacePtr) NULL, + (double) 0.0, (double) 0.0, TRUE); + } + } + else { + miLineJoin(pDrawable, pGC, pixel, spanData, &leftFace, + &prevRightFace); + } + prevRightFace = rightFace; + first = FALSE; + projectLeft = FALSE; + } + if (npt == 1 && somethingDrawn) { + if (selfJoin) + miLineJoin(pDrawable, pGC, pixel, spanData, &firstFace, + &rightFace); + else if (pGC->capStyle == CapRound) { + if (pGC->lineWidth == 1 && !spanData) + miLineOnePoint(pDrawable, pGC, pixel, spanData, x2, y2); + else + miLineArc(pDrawable, pGC, pixel, spanData, + (LineFacePtr) NULL, &rightFace, + (double) 0.0, (double) 0.0, TRUE); + } + } } /* handle crock where all points are coincedent */ - if (!somethingDrawn) - { - projectLeft = pGC->capStyle == CapProjecting; - miWideSegment (pDrawable, pGC, pixel, spanData, - x2, y2, x2, y2, projectLeft, projectLeft, - &leftFace, &rightFace); - if (pGC->capStyle == CapRound) - { - miLineArc (pDrawable, pGC, pixel, spanData, - &leftFace, (LineFacePtr) NULL, - (double)0.0, (double)0.0, - TRUE); - rightFace.dx = -1; /* sleezy hack to make it work */ - miLineArc (pDrawable, pGC, pixel, spanData, - (LineFacePtr) NULL, &rightFace, - (double)0.0, (double)0.0, - TRUE); - } + if (!somethingDrawn) { + projectLeft = pGC->capStyle == CapProjecting; + miWideSegment(pDrawable, pGC, pixel, spanData, + x2, y2, x2, y2, projectLeft, projectLeft, + &leftFace, &rightFace); + if (pGC->capStyle == CapRound) { + miLineArc(pDrawable, pGC, pixel, spanData, + &leftFace, (LineFacePtr) NULL, + (double) 0.0, (double) 0.0, TRUE); + rightFace.dx = -1; /* sleezy hack to make it work */ + miLineArc(pDrawable, pGC, pixel, spanData, + (LineFacePtr) NULL, &rightFace, + (double) 0.0, (double) 0.0, TRUE); + } } if (spanData) - miCleanupSpanData (pDrawable, pGC, spanData); + miCleanupSpanData(pDrawable, pGC, spanData); } #define V_TOP 0 @@ -1661,44 +1504,42 @@ miWideLine (DrawablePtr pDrawable, GCPtr pGC, #define V_LEFT 3 static void -miWideDashSegment ( - DrawablePtr pDrawable, - GCPtr pGC, - SpanDataPtr spanData, - int *pDashOffset, - int *pDashIndex, - int x1, - int y1, - int x2, - int y2, - Bool projectLeft, - Bool projectRight, - LineFacePtr leftFace, - LineFacePtr rightFace) +miWideDashSegment(DrawablePtr pDrawable, + GCPtr pGC, + SpanDataPtr spanData, + int *pDashOffset, + int *pDashIndex, + int x1, + int y1, + int x2, + int y2, + Bool projectLeft, + Bool projectRight, + LineFacePtr leftFace, LineFacePtr rightFace) { - int dashIndex, dashRemain; - unsigned char *pDash; - double L, l; - double k; - PolyVertexRec vertices[4]; - PolyVertexRec saveRight, saveBottom; - PolySlopeRec slopes[4]; - PolyEdgeRec left[2], right[2]; - LineFaceRec lcapFace, rcapFace; - int nleft, nright; - int h; - int y; - int dy, dx; - unsigned long pixel; - double LRemain; - double r; - double rdx, rdy; - double dashDx, dashDy; - double saveK = 0.0; - Bool first = TRUE; - double lcenterx, lcentery, rcenterx = 0.0, rcentery = 0.0; - unsigned long fgPixel, bgPixel; - + int dashIndex, dashRemain; + unsigned char *pDash; + double L, l; + double k; + PolyVertexRec vertices[4]; + PolyVertexRec saveRight, saveBottom; + PolySlopeRec slopes[4]; + PolyEdgeRec left[2], right[2]; + LineFaceRec lcapFace, rcapFace; + int nleft, nright; + int h; + int y; + int dy, dx; + unsigned long pixel; + double LRemain; + double r; + double rdx, rdy; + double dashDx, dashDy; + double saveK = 0.0; + Bool first = TRUE; + double lcenterx, lcentery, rcenterx = 0.0, rcentery = 0.0; + unsigned long fgPixel, bgPixel; + dx = x2 - x1; dy = y2 - y1; dashIndex = *pDashIndex; @@ -1706,42 +1547,35 @@ miWideDashSegment ( dashRemain = pDash[dashIndex] - *pDashOffset; fgPixel = pGC->fgPixel; bgPixel = pGC->bgPixel; - if (pGC->fillStyle == FillOpaqueStippled || - pGC->fillStyle == FillTiled) - { - bgPixel = fgPixel; + if (pGC->fillStyle == FillOpaqueStippled || pGC->fillStyle == FillTiled) { + bgPixel = fgPixel; } l = ((double) pGC->lineWidth) / 2.0; - if (dx == 0) - { - L = dy; - rdx = 0; - rdy = l; - if (dy < 0) - { - L = -dy; - rdy = -l; - } - } - else if (dy == 0) - { - L = dx; - rdx = l; - rdy = 0; - if (dx < 0) - { - L = -dx; - rdx = -l; - } - } - else - { - L = hypot ((double) dx, (double) dy); - r = l / L; - - rdx = r * dx; - rdy = r * dy; + if (dx == 0) { + L = dy; + rdx = 0; + rdy = l; + if (dy < 0) { + L = -dy; + rdy = -l; + } + } + else if (dy == 0) { + L = dx; + rdx = l; + rdy = 0; + if (dx < 0) { + L = -dx; + rdx = -l; + } + } + else { + L = hypot((double) dx, (double) dy); + r = l / L; + + rdx = r * dx; + rdy = r * dy; } k = l * L; LRemain = L; @@ -1771,230 +1605,203 @@ miWideDashSegment ( vertices[V_BOTTOM].x = vertices[V_LEFT].x = -rdy; vertices[V_BOTTOM].y = vertices[V_LEFT].y = rdx; - if (projectLeft) - { - vertices[V_TOP].x -= rdx; - vertices[V_TOP].y -= rdy; + if (projectLeft) { + vertices[V_TOP].x -= rdx; + vertices[V_TOP].y -= rdy; - vertices[V_LEFT].x -= rdx; - vertices[V_LEFT].y -= rdy; + vertices[V_LEFT].x -= rdx; + vertices[V_LEFT].y -= rdy; - slopes[V_LEFT].k = rdx * dx + rdy * dy; + slopes[V_LEFT].k = rdx * dx + rdy * dy; } lcenterx = x1; lcentery = y1; - if (pGC->capStyle == CapRound) - { - lcapFace.dx = dx; - lcapFace.dy = dy; - lcapFace.x = x1; - lcapFace.y = y1; - - rcapFace.dx = -dx; - rcapFace.dy = -dy; - rcapFace.x = x1; - rcapFace.y = y1; - } - while (LRemain > dashRemain) - { - dashDx = (dashRemain * dx) / L; - dashDy = (dashRemain * dy) / L; - - rcenterx = lcenterx + dashDx; - rcentery = lcentery + dashDy; - - vertices[V_RIGHT].x += dashDx; - vertices[V_RIGHT].y += dashDy; - - vertices[V_BOTTOM].x += dashDx; - vertices[V_BOTTOM].y += dashDy; - - slopes[V_RIGHT].k = vertices[V_RIGHT].x * dx + vertices[V_RIGHT].y * dy; - - if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1)) - { - if (pGC->lineStyle == LineOnOffDash && - pGC->capStyle == CapProjecting) - { - saveRight = vertices[V_RIGHT]; - saveBottom = vertices[V_BOTTOM]; - saveK = slopes[V_RIGHT].k; - - if (!first) - { - vertices[V_TOP].x -= rdx; - vertices[V_TOP].y -= rdy; - - vertices[V_LEFT].x -= rdx; - vertices[V_LEFT].y -= rdy; - - slopes[V_LEFT].k = vertices[V_LEFT].x * - slopes[V_LEFT].dy - - vertices[V_LEFT].y * - slopes[V_LEFT].dx; - } - - vertices[V_RIGHT].x += rdx; - vertices[V_RIGHT].y += rdy; - - vertices[V_BOTTOM].x += rdx; - vertices[V_BOTTOM].y += rdy; - - slopes[V_RIGHT].k = vertices[V_RIGHT].x * - slopes[V_RIGHT].dy - - vertices[V_RIGHT].y * - slopes[V_RIGHT].dx; - } - y = miPolyBuildPoly (vertices, slopes, 4, x1, y1, - left, right, &nleft, &nright, &h); - pixel = (dashIndex & 1) ? bgPixel : fgPixel; - miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, h, left, right, nleft, nright); - - if (pGC->lineStyle == LineOnOffDash) - { - switch (pGC->capStyle) - { - case CapProjecting: - vertices[V_BOTTOM] = saveBottom; - vertices[V_RIGHT] = saveRight; - slopes[V_RIGHT].k = saveK; - break; - case CapRound: - if (!first) - { - if (dx < 0) - { - lcapFace.xa = -vertices[V_LEFT].x; - lcapFace.ya = -vertices[V_LEFT].y; - lcapFace.k = slopes[V_LEFT].k; - } - else - { - lcapFace.xa = vertices[V_TOP].x; - lcapFace.ya = vertices[V_TOP].y; - lcapFace.k = -slopes[V_LEFT].k; - } - miLineArc (pDrawable, pGC, pixel, spanData, - &lcapFace, (LineFacePtr) NULL, - lcenterx, lcentery, FALSE); - } - if (dx < 0) - { - rcapFace.xa = vertices[V_BOTTOM].x; - rcapFace.ya = vertices[V_BOTTOM].y; - rcapFace.k = slopes[V_RIGHT].k; - } - else - { - rcapFace.xa = -vertices[V_RIGHT].x; - rcapFace.ya = -vertices[V_RIGHT].y; - rcapFace.k = -slopes[V_RIGHT].k; - } - miLineArc (pDrawable, pGC, pixel, spanData, - (LineFacePtr) NULL, &rcapFace, - rcenterx, rcentery, FALSE); - break; - } - } - } - LRemain -= dashRemain; - ++dashIndex; - if (dashIndex == pGC->numInDashList) - dashIndex = 0; - dashRemain = pDash[dashIndex]; - - lcenterx = rcenterx; - lcentery = rcentery; - - vertices[V_TOP] = vertices[V_RIGHT]; - vertices[V_LEFT] = vertices[V_BOTTOM]; - slopes[V_LEFT].k = -slopes[V_RIGHT].k; - first = FALSE; - } - - if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1)) - { - vertices[V_TOP].x -= dx; - vertices[V_TOP].y -= dy; - - vertices[V_LEFT].x -= dx; - vertices[V_LEFT].y -= dy; - - vertices[V_RIGHT].x = rdy; - vertices[V_RIGHT].y = -rdx; - - vertices[V_BOTTOM].x = -rdy; - vertices[V_BOTTOM].y = rdx; - - - if (projectRight) - { - vertices[V_RIGHT].x += rdx; - vertices[V_RIGHT].y += rdy; - - vertices[V_BOTTOM].x += rdx; - vertices[V_BOTTOM].y += rdy; - slopes[V_RIGHT].k = vertices[V_RIGHT].x * - slopes[V_RIGHT].dy - - vertices[V_RIGHT].y * - slopes[V_RIGHT].dx; - } - else - slopes[V_RIGHT].k = 0; - - if (!first && pGC->lineStyle == LineOnOffDash && - pGC->capStyle == CapProjecting) - { - vertices[V_TOP].x -= rdx; - vertices[V_TOP].y -= rdy; - - vertices[V_LEFT].x -= rdx; - vertices[V_LEFT].y -= rdy; - slopes[V_LEFT].k = vertices[V_LEFT].x * - slopes[V_LEFT].dy - - vertices[V_LEFT].y * - slopes[V_LEFT].dx; - } - else - slopes[V_LEFT].k += dx * dx + dy * dy; - - - y = miPolyBuildPoly (vertices, slopes, 4, x2, y2, - left, right, &nleft, &nright, &h); - - pixel = (dashIndex & 1) ? pGC->bgPixel : pGC->fgPixel; - miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, h, left, right, nleft, nright); - if (!first && pGC->lineStyle == LineOnOffDash && - pGC->capStyle == CapRound) - { - lcapFace.x = x2; - lcapFace.y = y2; - if (dx < 0) - { - lcapFace.xa = -vertices[V_LEFT].x; - lcapFace.ya = -vertices[V_LEFT].y; - lcapFace.k = slopes[V_LEFT].k; - } - else - { - lcapFace.xa = vertices[V_TOP].x; - lcapFace.ya = vertices[V_TOP].y; - lcapFace.k = -slopes[V_LEFT].k; - } - miLineArc (pDrawable, pGC, pixel, spanData, - &lcapFace, (LineFacePtr) NULL, - rcenterx, rcentery, FALSE); - } + if (pGC->capStyle == CapRound) { + lcapFace.dx = dx; + lcapFace.dy = dy; + lcapFace.x = x1; + lcapFace.y = y1; + + rcapFace.dx = -dx; + rcapFace.dy = -dy; + rcapFace.x = x1; + rcapFace.y = y1; + } + while (LRemain > dashRemain) { + dashDx = (dashRemain * dx) / L; + dashDy = (dashRemain * dy) / L; + + rcenterx = lcenterx + dashDx; + rcentery = lcentery + dashDy; + + vertices[V_RIGHT].x += dashDx; + vertices[V_RIGHT].y += dashDy; + + vertices[V_BOTTOM].x += dashDx; + vertices[V_BOTTOM].y += dashDy; + + slopes[V_RIGHT].k = vertices[V_RIGHT].x * dx + vertices[V_RIGHT].y * dy; + + if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1)) { + if (pGC->lineStyle == LineOnOffDash && + pGC->capStyle == CapProjecting) { + saveRight = vertices[V_RIGHT]; + saveBottom = vertices[V_BOTTOM]; + saveK = slopes[V_RIGHT].k; + + if (!first) { + vertices[V_TOP].x -= rdx; + vertices[V_TOP].y -= rdy; + + vertices[V_LEFT].x -= rdx; + vertices[V_LEFT].y -= rdy; + + slopes[V_LEFT].k = vertices[V_LEFT].x * + slopes[V_LEFT].dy - + vertices[V_LEFT].y * slopes[V_LEFT].dx; + } + + vertices[V_RIGHT].x += rdx; + vertices[V_RIGHT].y += rdy; + + vertices[V_BOTTOM].x += rdx; + vertices[V_BOTTOM].y += rdy; + + slopes[V_RIGHT].k = vertices[V_RIGHT].x * + slopes[V_RIGHT].dy - + vertices[V_RIGHT].y * slopes[V_RIGHT].dx; + } + y = miPolyBuildPoly(vertices, slopes, 4, x1, y1, + left, right, &nleft, &nright, &h); + pixel = (dashIndex & 1) ? bgPixel : fgPixel; + miFillPolyHelper(pDrawable, pGC, pixel, spanData, y, h, left, right, + nleft, nright); + + if (pGC->lineStyle == LineOnOffDash) { + switch (pGC->capStyle) { + case CapProjecting: + vertices[V_BOTTOM] = saveBottom; + vertices[V_RIGHT] = saveRight; + slopes[V_RIGHT].k = saveK; + break; + case CapRound: + if (!first) { + if (dx < 0) { + lcapFace.xa = -vertices[V_LEFT].x; + lcapFace.ya = -vertices[V_LEFT].y; + lcapFace.k = slopes[V_LEFT].k; + } + else { + lcapFace.xa = vertices[V_TOP].x; + lcapFace.ya = vertices[V_TOP].y; + lcapFace.k = -slopes[V_LEFT].k; + } + miLineArc(pDrawable, pGC, pixel, spanData, + &lcapFace, (LineFacePtr) NULL, + lcenterx, lcentery, FALSE); + } + if (dx < 0) { + rcapFace.xa = vertices[V_BOTTOM].x; + rcapFace.ya = vertices[V_BOTTOM].y; + rcapFace.k = slopes[V_RIGHT].k; + } + else { + rcapFace.xa = -vertices[V_RIGHT].x; + rcapFace.ya = -vertices[V_RIGHT].y; + rcapFace.k = -slopes[V_RIGHT].k; + } + miLineArc(pDrawable, pGC, pixel, spanData, + (LineFacePtr) NULL, &rcapFace, + rcenterx, rcentery, FALSE); + break; + } + } + } + LRemain -= dashRemain; + ++dashIndex; + if (dashIndex == pGC->numInDashList) + dashIndex = 0; + dashRemain = pDash[dashIndex]; + + lcenterx = rcenterx; + lcentery = rcentery; + + vertices[V_TOP] = vertices[V_RIGHT]; + vertices[V_LEFT] = vertices[V_BOTTOM]; + slopes[V_LEFT].k = -slopes[V_RIGHT].k; + first = FALSE; + } + + if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1)) { + vertices[V_TOP].x -= dx; + vertices[V_TOP].y -= dy; + + vertices[V_LEFT].x -= dx; + vertices[V_LEFT].y -= dy; + + vertices[V_RIGHT].x = rdy; + vertices[V_RIGHT].y = -rdx; + + vertices[V_BOTTOM].x = -rdy; + vertices[V_BOTTOM].y = rdx; + + if (projectRight) { + vertices[V_RIGHT].x += rdx; + vertices[V_RIGHT].y += rdy; + + vertices[V_BOTTOM].x += rdx; + vertices[V_BOTTOM].y += rdy; + slopes[V_RIGHT].k = vertices[V_RIGHT].x * + slopes[V_RIGHT].dy - vertices[V_RIGHT].y * slopes[V_RIGHT].dx; + } + else + slopes[V_RIGHT].k = 0; + + if (!first && pGC->lineStyle == LineOnOffDash && + pGC->capStyle == CapProjecting) { + vertices[V_TOP].x -= rdx; + vertices[V_TOP].y -= rdy; + + vertices[V_LEFT].x -= rdx; + vertices[V_LEFT].y -= rdy; + slopes[V_LEFT].k = vertices[V_LEFT].x * + slopes[V_LEFT].dy - vertices[V_LEFT].y * slopes[V_LEFT].dx; + } + else + slopes[V_LEFT].k += dx * dx + dy * dy; + + y = miPolyBuildPoly(vertices, slopes, 4, x2, y2, + left, right, &nleft, &nright, &h); + + pixel = (dashIndex & 1) ? pGC->bgPixel : pGC->fgPixel; + miFillPolyHelper(pDrawable, pGC, pixel, spanData, y, h, left, right, + nleft, nright); + if (!first && pGC->lineStyle == LineOnOffDash && + pGC->capStyle == CapRound) { + lcapFace.x = x2; + lcapFace.y = y2; + if (dx < 0) { + lcapFace.xa = -vertices[V_LEFT].x; + lcapFace.ya = -vertices[V_LEFT].y; + lcapFace.k = slopes[V_LEFT].k; + } + else { + lcapFace.xa = vertices[V_TOP].x; + lcapFace.ya = vertices[V_TOP].y; + lcapFace.k = -slopes[V_LEFT].k; + } + miLineArc(pDrawable, pGC, pixel, spanData, + &lcapFace, (LineFacePtr) NULL, rcenterx, rcentery, FALSE); + } } dashRemain = ((double) dashRemain) - LRemain; - if (dashRemain == 0) - { - dashIndex++; - if (dashIndex == pGC->numInDashList) - dashIndex = 0; - dashRemain = pDash[dashIndex]; + if (dashRemain == 0) { + dashIndex++; + if (dashIndex == pGC->numInDashList) + dashIndex = 0; + dashRemain = pDash[dashIndex]; } leftFace->x = x1; @@ -2018,180 +1825,161 @@ miWideDashSegment ( } void -miWideDash (DrawablePtr pDrawable, GCPtr pGC, - int mode, int npt, DDXPointPtr pPts) +miWideDash(DrawablePtr pDrawable, GCPtr pGC, + int mode, int npt, DDXPointPtr pPts) { - int x1, y1, x2, y2; - unsigned long pixel; - Bool projectLeft, projectRight; - LineFaceRec leftFace, rightFace, prevRightFace; - LineFaceRec firstFace; - int first; - int dashIndex, dashOffset; - int prevDashIndex; - SpanDataRec spanDataRec; - SpanDataPtr spanData; - Bool somethingDrawn = FALSE; - Bool selfJoin; - Bool endIsFg = FALSE, startIsFg = FALSE; - Bool firstIsFg = FALSE, prevIsFg = FALSE; + int x1, y1, x2, y2; + unsigned long pixel; + Bool projectLeft, projectRight; + LineFaceRec leftFace, rightFace, prevRightFace; + LineFaceRec firstFace; + int first; + int dashIndex, dashOffset; + int prevDashIndex; + SpanDataRec spanDataRec; + SpanDataPtr spanData; + Bool somethingDrawn = FALSE; + Bool selfJoin; + Bool endIsFg = FALSE, startIsFg = FALSE; + Bool firstIsFg = FALSE, prevIsFg = FALSE; #if 0 /* XXX backward compatibility */ - if (pGC->lineWidth == 0) - { - miZeroDashLine (pDrawable, pGC, mode, npt, pPts); - return; + if (pGC->lineWidth == 0) { + miZeroDashLine(pDrawable, pGC, mode, npt, pPts); + return; } #endif - if (pGC->lineStyle == LineDoubleDash && - (pGC->fillStyle == FillOpaqueStippled || pGC->fillStyle == FillTiled)) - { - miWideLine (pDrawable, pGC, mode, npt, pPts); - return; + if (pGC->lineStyle == LineDoubleDash && + (pGC->fillStyle == FillOpaqueStippled || pGC->fillStyle == FillTiled)) { + miWideLine(pDrawable, pGC, mode, npt, pPts); + return; } if (npt == 0) - return; - spanData = miSetupSpanData (pGC, &spanDataRec, npt); + return; + spanData = miSetupSpanData(pGC, &spanDataRec, npt); x2 = pPts->x; y2 = pPts->y; first = TRUE; selfJoin = FALSE; - if (mode == CoordModePrevious) - { - int nptTmp; - DDXPointPtr pPtsTmp; - - x1 = x2; - y1 = y2; - nptTmp = npt; - pPtsTmp = pPts + 1; - while (--nptTmp) - { - x1 += pPtsTmp->x; - y1 += pPtsTmp->y; - ++pPtsTmp; - } - if (x2 == x1 && y2 == y1) - selfJoin = TRUE; - } - else if (x2 == pPts[npt-1].x && y2 == pPts[npt-1].y) - { - selfJoin = TRUE; + if (mode == CoordModePrevious) { + int nptTmp; + DDXPointPtr pPtsTmp; + + x1 = x2; + y1 = y2; + nptTmp = npt; + pPtsTmp = pPts + 1; + while (--nptTmp) { + x1 += pPtsTmp->x; + y1 += pPtsTmp->y; + ++pPtsTmp; + } + if (x2 == x1 && y2 == y1) + selfJoin = TRUE; + } + else if (x2 == pPts[npt - 1].x && y2 == pPts[npt - 1].y) { + selfJoin = TRUE; } projectLeft = pGC->capStyle == CapProjecting && !selfJoin; projectRight = FALSE; dashIndex = 0; dashOffset = 0; - miStepDash ((int)pGC->dashOffset, &dashIndex, - pGC->dash, (int)pGC->numInDashList, &dashOffset); - while (--npt) - { - x1 = x2; - y1 = y2; - ++pPts; - x2 = pPts->x; - y2 = pPts->y; - if (mode == CoordModePrevious) - { - x2 += x1; - y2 += y1; - } - if (x1 != x2 || y1 != y2) - { - somethingDrawn = TRUE; - if (npt == 1 && pGC->capStyle == CapProjecting && - (!selfJoin || !firstIsFg)) - projectRight = TRUE; - prevDashIndex = dashIndex; - miWideDashSegment (pDrawable, pGC, spanData, &dashOffset, &dashIndex, - x1, y1, x2, y2, - projectLeft, projectRight, &leftFace, &rightFace); - startIsFg = !(prevDashIndex & 1); - endIsFg = (dashIndex & 1) ^ (dashOffset != 0); - if (pGC->lineStyle == LineDoubleDash || startIsFg) - { - pixel = startIsFg ? pGC->fgPixel : pGC->bgPixel; - if (first || (pGC->lineStyle == LineOnOffDash && !prevIsFg)) - { - if (first && selfJoin) - { - firstFace = leftFace; - firstIsFg = startIsFg; - } - else if (pGC->capStyle == CapRound) - miLineArc (pDrawable, pGC, pixel, spanData, - &leftFace, (LineFacePtr) NULL, - (double)0.0, (double)0.0, TRUE); - } - else - { - miLineJoin (pDrawable, pGC, pixel, spanData, &leftFace, - &prevRightFace); - } - } - prevRightFace = rightFace; - prevIsFg = endIsFg; - first = FALSE; - projectLeft = FALSE; - } - if (npt == 1 && somethingDrawn) - { - if (pGC->lineStyle == LineDoubleDash || endIsFg) - { - pixel = endIsFg ? pGC->fgPixel : pGC->bgPixel; - if (selfJoin && (pGC->lineStyle == LineDoubleDash || firstIsFg)) - { - miLineJoin (pDrawable, pGC, pixel, spanData, &firstFace, - &rightFace); - } - else - { - if (pGC->capStyle == CapRound) - miLineArc (pDrawable, pGC, pixel, spanData, - (LineFacePtr) NULL, &rightFace, - (double)0.0, (double)0.0, TRUE); - } - } - else - { - /* glue a cap to the start of the line if - * we're OnOffDash and ended on odd dash - */ - if (selfJoin && firstIsFg) - { - pixel = pGC->fgPixel; - if (pGC->capStyle == CapProjecting) - miLineProjectingCap (pDrawable, pGC, pixel, spanData, - &firstFace, TRUE, - (double)0.0, (double)0.0, TRUE); - else if (pGC->capStyle == CapRound) - miLineArc (pDrawable, pGC, pixel, spanData, - &firstFace, (LineFacePtr) NULL, - (double)0.0, (double)0.0, TRUE); - } - } - } + miStepDash((int) pGC->dashOffset, &dashIndex, + pGC->dash, (int) pGC->numInDashList, &dashOffset); + while (--npt) { + x1 = x2; + y1 = y2; + ++pPts; + x2 = pPts->x; + y2 = pPts->y; + if (mode == CoordModePrevious) { + x2 += x1; + y2 += y1; + } + if (x1 != x2 || y1 != y2) { + somethingDrawn = TRUE; + if (npt == 1 && pGC->capStyle == CapProjecting && + (!selfJoin || !firstIsFg)) + projectRight = TRUE; + prevDashIndex = dashIndex; + miWideDashSegment(pDrawable, pGC, spanData, &dashOffset, &dashIndex, + x1, y1, x2, y2, + projectLeft, projectRight, &leftFace, &rightFace); + startIsFg = !(prevDashIndex & 1); + endIsFg = (dashIndex & 1) ^ (dashOffset != 0); + if (pGC->lineStyle == LineDoubleDash || startIsFg) { + pixel = startIsFg ? pGC->fgPixel : pGC->bgPixel; + if (first || (pGC->lineStyle == LineOnOffDash && !prevIsFg)) { + if (first && selfJoin) { + firstFace = leftFace; + firstIsFg = startIsFg; + } + else if (pGC->capStyle == CapRound) + miLineArc(pDrawable, pGC, pixel, spanData, + &leftFace, (LineFacePtr) NULL, + (double) 0.0, (double) 0.0, TRUE); + } + else { + miLineJoin(pDrawable, pGC, pixel, spanData, &leftFace, + &prevRightFace); + } + } + prevRightFace = rightFace; + prevIsFg = endIsFg; + first = FALSE; + projectLeft = FALSE; + } + if (npt == 1 && somethingDrawn) { + if (pGC->lineStyle == LineDoubleDash || endIsFg) { + pixel = endIsFg ? pGC->fgPixel : pGC->bgPixel; + if (selfJoin && (pGC->lineStyle == LineDoubleDash || firstIsFg)) { + miLineJoin(pDrawable, pGC, pixel, spanData, &firstFace, + &rightFace); + } + else { + if (pGC->capStyle == CapRound) + miLineArc(pDrawable, pGC, pixel, spanData, + (LineFacePtr) NULL, &rightFace, + (double) 0.0, (double) 0.0, TRUE); + } + } + else { + /* glue a cap to the start of the line if + * we're OnOffDash and ended on odd dash + */ + if (selfJoin && firstIsFg) { + pixel = pGC->fgPixel; + if (pGC->capStyle == CapProjecting) + miLineProjectingCap(pDrawable, pGC, pixel, spanData, + &firstFace, TRUE, + (double) 0.0, (double) 0.0, TRUE); + else if (pGC->capStyle == CapRound) + miLineArc(pDrawable, pGC, pixel, spanData, + &firstFace, (LineFacePtr) NULL, + (double) 0.0, (double) 0.0, TRUE); + } + } + } } /* handle crock where all points are coincident */ - if (!somethingDrawn && (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1))) - { - /* not the same as endIsFg computation above */ - pixel = (dashIndex & 1) ? pGC->bgPixel : pGC->fgPixel; - switch (pGC->capStyle) { - case CapRound: - miLineArc (pDrawable, pGC, pixel, spanData, - (LineFacePtr) NULL, (LineFacePtr) NULL, - (double)x2, (double)y2, - FALSE); - break; - case CapProjecting: - x1 = pGC->lineWidth; - miFillRectPolyHelper (pDrawable, pGC, pixel, spanData, - x2 - (x1 >> 1), y2 - (x1 >> 1), x1, x1); - break; - } + if (!somethingDrawn && + (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1))) { + /* not the same as endIsFg computation above */ + pixel = (dashIndex & 1) ? pGC->bgPixel : pGC->fgPixel; + switch (pGC->capStyle) { + case CapRound: + miLineArc(pDrawable, pGC, pixel, spanData, + (LineFacePtr) NULL, (LineFacePtr) NULL, + (double) x2, (double) y2, FALSE); + break; + case CapProjecting: + x1 = pGC->lineWidth; + miFillRectPolyHelper(pDrawable, pGC, pixel, spanData, + x2 - (x1 >> 1), y2 - (x1 >> 1), x1, x1); + break; + } } if (spanData) - miCleanupSpanData (pDrawable, pGC, spanData); + miCleanupSpanData(pDrawable, pGC, spanData); } diff --git a/xorg-server/mi/miwideline.h b/xorg-server/mi/miwideline.h index 05d026a38..110541120 100644 --- a/xorg-server/mi/miwideline.h +++ b/xorg-server/mi/miwideline.h @@ -1,120 +1,119 @@ -/*
-
-Copyright 1988, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-/* Author: Keith Packard, MIT X Consortium */
-
-#include "mispans.h"
-#include "mifpoly.h" /* for ICEIL */
-
-/*
- * Polygon edge description for integer wide-line routines
- */
-
-typedef struct _PolyEdge {
- int height; /* number of scanlines to process */
- int x; /* starting x coordinate */
- int stepx; /* fixed integral dx */
- int signdx; /* variable dx sign */
- int e; /* initial error term */
- int dy;
- int dx;
-} PolyEdgeRec, *PolyEdgePtr;
-
-#define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - miter limit constant */
-
-/*
- * types for general polygon routines
- */
-
-typedef struct _PolyVertex {
- double x, y;
-} PolyVertexRec, *PolyVertexPtr;
-
-typedef struct _PolySlope {
- int dx, dy;
- double k; /* x0 * dy - y0 * dx */
-} PolySlopeRec, *PolySlopePtr;
-
-/*
- * Line face description for caps/joins
- */
-
-typedef struct _LineFace {
- double xa, ya;
- int dx, dy;
- int x, y;
- double k;
-} LineFaceRec, *LineFacePtr;
-
-/*
- * macros for polygon fillers
- */
-
-#define MILINESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \
- oldPixel = pGC->fgPixel; \
- if (pixel != oldPixel) { \
- ChangeGCVal gcval; \
- gcval.val = pixel; \
- ChangeGC (NullClient, pGC, GCForeground, &gcval); \
- ValidateGC (pDrawable, pGC); \
- } \
-}
-#define MILINERESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \
- if (pixel != oldPixel) { \
- ChangeGCVal gcval; \
- gcval.val = oldPixel; \
- ChangeGC (NullClient, pGC, GCForeground, &gcval); \
- ValidateGC (pDrawable, pGC); \
- } \
-}
-
-extern _X_EXPORT void miRoundJoinClip(
- LineFacePtr /*pLeft*/,
- LineFacePtr /*pRight*/,
- PolyEdgePtr /*edge1*/,
- PolyEdgePtr /*edge2*/,
- int * /*y1*/,
- int * /*y2*/,
- Bool * /*left1*/,
- Bool * /*left2*/
-);
-
-extern _X_EXPORT int miRoundCapClip(
- LineFacePtr /*face*/,
- Bool /*isInt*/,
- PolyEdgePtr /*edge*/,
- Bool * /*leftEdge*/
-);
-
-extern _X_EXPORT int miPolyBuildEdge(double x0, double y0, double k, int dx, int dy,
- int xi, int yi, int left, PolyEdgePtr edge);
-extern _X_EXPORT int miPolyBuildPoly(PolyVertexPtr vertices, PolySlopePtr slopes,
- int count, int xi, int yi, PolyEdgePtr left,
- PolyEdgePtr right, int *pnleft, int *pnright,
- int *h);
-
+/* + +Copyright 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +/* Author: Keith Packard, MIT X Consortium */ + +#include "mispans.h" +#include "mifpoly.h" /* for ICEIL */ + +/* + * Polygon edge description for integer wide-line routines + */ + +typedef struct _PolyEdge { + int height; /* number of scanlines to process */ + int x; /* starting x coordinate */ + int stepx; /* fixed integral dx */ + int signdx; /* variable dx sign */ + int e; /* initial error term */ + int dy; + int dx; +} PolyEdgeRec, *PolyEdgePtr; + +#define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - miter limit constant */ + +/* + * types for general polygon routines + */ + +typedef struct _PolyVertex { + double x, y; +} PolyVertexRec, *PolyVertexPtr; + +typedef struct _PolySlope { + int dx, dy; + double k; /* x0 * dy - y0 * dx */ +} PolySlopeRec, *PolySlopePtr; + +/* + * Line face description for caps/joins + */ + +typedef struct _LineFace { + double xa, ya; + int dx, dy; + int x, y; + double k; +} LineFaceRec, *LineFacePtr; + +/* + * macros for polygon fillers + */ + +#define MILINESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \ + oldPixel = pGC->fgPixel; \ + if (pixel != oldPixel) { \ + ChangeGCVal gcval; \ + gcval.val = pixel; \ + ChangeGC (NullClient, pGC, GCForeground, &gcval); \ + ValidateGC (pDrawable, pGC); \ + } \ +} +#define MILINERESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \ + if (pixel != oldPixel) { \ + ChangeGCVal gcval; \ + gcval.val = oldPixel; \ + ChangeGC (NullClient, pGC, GCForeground, &gcval); \ + ValidateGC (pDrawable, pGC); \ + } \ +} + +extern _X_EXPORT void miRoundJoinClip(LineFacePtr /*pLeft */ , + LineFacePtr /*pRight */ , + PolyEdgePtr /*edge1 */ , + PolyEdgePtr /*edge2 */ , + int * /*y1 */ , + int * /*y2 */ , + Bool * /*left1 */ , + Bool * /*left2 */ + ); + +extern _X_EXPORT int miRoundCapClip(LineFacePtr /*face */ , + Bool /*isInt */ , + PolyEdgePtr /*edge */ , + Bool * /*leftEdge */ + ); + +extern _X_EXPORT int miPolyBuildEdge(double x0, double y0, double k, int dx, + int dy, int xi, int yi, int left, + PolyEdgePtr edge); +extern _X_EXPORT int miPolyBuildPoly(PolyVertexPtr vertices, + PolySlopePtr slopes, int count, int xi, + int yi, PolyEdgePtr left, + PolyEdgePtr right, int *pnleft, + int *pnright, int *h); diff --git a/xorg-server/mi/miwindow.c b/xorg-server/mi/miwindow.c index 87d474ff2..e341b79de 100644 --- a/xorg-server/mi/miwindow.c +++ b/xorg-server/mi/miwindow.c @@ -1,824 +1,760 @@ -
-/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/extensions/shapeconst.h>
-#include "regionstr.h"
-#include "region.h"
-#include "mi.h"
-#include "windowstr.h"
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "mivalidate.h"
-
-void
-miClearToBackground(WindowPtr pWin,
- int x, int y, int w, int h,
- Bool generateExposures)
-{
- BoxRec box;
- RegionRec reg;
- BoxPtr extents;
- int x1, y1, x2, y2;
-
- /* compute everything using ints to avoid overflow */
-
- x1 = pWin->drawable.x + x;
- y1 = pWin->drawable.y + y;
- if (w)
- x2 = x1 + (int) w;
- else
- x2 = x1 + (int) pWin->drawable.width - (int) x;
- if (h)
- y2 = y1 + h;
- else
- y2 = y1 + (int) pWin->drawable.height - (int) y;
-
- extents = &pWin->clipList.extents;
-
- /* clip the resulting rectangle to the window clipList extents. This
- * makes sure that the result will fit in a box, given that the
- * screen is < 32768 on a side.
- */
-
- if (x1 < extents->x1)
- x1 = extents->x1;
- if (x2 > extents->x2)
- x2 = extents->x2;
- if (y1 < extents->y1)
- y1 = extents->y1;
- if (y2 > extents->y2)
- y2 = extents->y2;
-
- if (x2 <= x1 || y2 <= y1)
- {
- x2 = x1 = 0;
- y2 = y1 = 0;
- }
-
- box.x1 = x1;
- box.x2 = x2;
- box.y1 = y1;
- box.y2 = y2;
-
- RegionInit(®, &box, 1);
-
- RegionIntersect(®, ®, &pWin->clipList);
- if (generateExposures)
- (*pWin->drawable.pScreen->WindowExposures)(pWin, ®, NULL);
- else if (pWin->backgroundState != None)
- miPaintWindow(pWin, ®, PW_BACKGROUND);
- RegionUninit(®);
-}
-
-void
-miMarkWindow(WindowPtr pWin)
-{
- ValidatePtr val;
-
- if (pWin->valdata)
- return;
- val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
- val->before.oldAbsCorner.x = pWin->drawable.x;
- val->before.oldAbsCorner.y = pWin->drawable.y;
- val->before.borderVisible = NullRegion;
- val->before.resized = FALSE;
- pWin->valdata = val;
-}
-
-Bool
-miMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin)
-{
- BoxPtr box;
- WindowPtr pChild, pLast;
- Bool anyMarked = FALSE;
- MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
-
- /* single layered systems are easy */
- if (ppLayerWin) *ppLayerWin = pWin;
-
- if (pWin == pFirst)
- {
- /* Blindly mark pWin and all of its inferiors. This is a slight
- * overkill if there are mapped windows that outside pWin's border,
- * but it's better than wasting time on RectIn checks.
- */
- pChild = pWin;
- while (1)
- {
- if (pChild->viewable)
- {
- if (RegionBroken(&pChild->winSize))
- SetWinSize (pChild);
- if (RegionBroken(&pChild->borderSize))
- SetBorderSize (pChild);
- (* MarkWindow)(pChild);
- if (pChild->firstChild)
- {
- pChild = pChild->firstChild;
- continue;
- }
- }
- while (!pChild->nextSib && (pChild != pWin))
- pChild = pChild->parent;
- if (pChild == pWin)
- break;
- pChild = pChild->nextSib;
- }
- anyMarked = TRUE;
- pFirst = pFirst->nextSib;
- }
- if ( (pChild = pFirst) )
- {
- box = RegionExtents(&pWin->borderSize);
- pLast = pChild->parent->lastChild;
- while (1)
- {
- if (pChild->viewable)
- {
- if (RegionBroken(&pChild->winSize))
- SetWinSize (pChild);
- if (RegionBroken(&pChild->borderSize))
- SetBorderSize (pChild);
- if (RegionContainsRect(&pChild->borderSize, box))
- {
- (* MarkWindow)(pChild);
- anyMarked = TRUE;
- if (pChild->firstChild)
- {
- pChild = pChild->firstChild;
- continue;
- }
- }
- }
- while (!pChild->nextSib && (pChild != pLast))
- pChild = pChild->parent;
- if (pChild == pLast)
- break;
- pChild = pChild->nextSib;
- }
- }
- if (anyMarked)
- (* MarkWindow)(pWin->parent);
- return anyMarked;
-}
-
-/*****
- * miHandleValidateExposures(pWin)
- * starting at pWin, draw background in any windows that have exposure
- * regions, translate the regions, restore any backing store,
- * and then send any regions still exposed to the client
- *****/
-void
-miHandleValidateExposures(WindowPtr pWin)
-{
- WindowPtr pChild;
- ValidatePtr val;
- WindowExposuresProcPtr WindowExposures;
-
- pChild = pWin;
- WindowExposures = pChild->drawable.pScreen->WindowExposures;
- while (1)
- {
- if ( (val = pChild->valdata) && val!=UnmapValData)
- {
- if (RegionNotEmpty(&val->after.borderExposed))
- miPaintWindow(pChild, &val->after.borderExposed, PW_BORDER);
- RegionUninit(&val->after.borderExposed);
- (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
- RegionUninit(&val->after.exposed);
- free(val);
- pChild->valdata = NULL;
- if (pChild->firstChild)
- {
- pChild = pChild->firstChild;
- continue;
- }
- }
- while (!pChild->nextSib && (pChild != pWin))
- pChild = pChild->parent;
- if (pChild == pWin)
- break;
- pChild = pChild->nextSib;
- }
-}
-
-void
-miMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind)
-{
- WindowPtr pParent;
- Bool WasViewable = (Bool)(pWin->viewable);
- short bw;
- RegionPtr oldRegion = NULL;
- DDXPointRec oldpt;
- Bool anyMarked = FALSE;
- ScreenPtr pScreen;
- WindowPtr windowToValidate;
- WindowPtr pLayerWin;
-
- /* if this is a root window, can't be moved */
- if (!(pParent = pWin->parent))
- return ;
- pScreen = pWin->drawable.pScreen;
- bw = wBorderWidth (pWin);
-
- oldpt.x = pWin->drawable.x;
- oldpt.y = pWin->drawable.y;
- if (WasViewable)
- {
- oldRegion = RegionCreate(NullBox, 1);
- RegionCopy(oldRegion, &pWin->borderClip);
- anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
- }
- pWin->origin.x = x + (int)bw;
- pWin->origin.y = y + (int)bw;
- x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
- y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
-
- SetWinSize (pWin);
- SetBorderSize (pWin);
-
- (*pScreen->PositionWindow)(pWin, x, y);
-
- windowToValidate = MoveWindowInStack(pWin, pNextSib);
-
- ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
-
- if (WasViewable)
- {
- if (pLayerWin == pWin)
- anyMarked |= (*pScreen->MarkOverlappedWindows)
- (pWin, windowToValidate, NULL);
- else
- anyMarked |= (*pScreen->MarkOverlappedWindows)
- (pWin, pLayerWin, NULL);
-
-
- if (anyMarked)
- {
- (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
- (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
- RegionDestroy(oldRegion);
- /* XXX need to retile border if ParentRelative origin */
- (*pScreen->HandleExposures)(pLayerWin->parent);
- }
- if (anyMarked && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
- }
- if (pWin->realized)
- WindowsRestructured ();
-}
-
-
-/*
- * pValid is a region of the screen which has been
- * successfully copied -- recomputed exposed regions for affected windows
- */
-
-static int
-miRecomputeExposures (
- WindowPtr pWin,
- pointer value) /* must conform to VisitWindowProcPtr */
-{
- RegionPtr pValid = (RegionPtr)value;
-
- if (pWin->valdata)
- {
-#ifdef COMPOSITE
- /*
- * Redirected windows are not affected by parent window
- * gravity manipulations, so don't recompute their
- * exposed areas here.
- */
- if (pWin->redirectDraw != RedirectDrawNone)
- return WT_DONTWALKCHILDREN;
-#endif
- /*
- * compute exposed regions of this window
- */
- RegionSubtract(&pWin->valdata->after.exposed,
- &pWin->clipList, pValid);
- /*
- * compute exposed regions of the border
- */
- RegionSubtract(&pWin->valdata->after.borderExposed,
- &pWin->borderClip, &pWin->winSize);
- RegionSubtract(&pWin->valdata->after.borderExposed,
- &pWin->valdata->after.borderExposed, pValid);
- return WT_WALKCHILDREN;
- }
- return WT_NOMATCH;
-}
-
-void
-miSlideAndSizeWindow(WindowPtr pWin,
- int x, int y,
- unsigned int w, unsigned int h,
- WindowPtr pSib)
-{
- WindowPtr pParent;
- Bool WasViewable = (Bool)(pWin->viewable);
- unsigned short width = pWin->drawable.width,
- height = pWin->drawable.height;
- short oldx = pWin->drawable.x,
- oldy = pWin->drawable.y;
- int bw = wBorderWidth (pWin);
- short dw, dh;
- DDXPointRec oldpt;
- RegionPtr oldRegion = NULL;
- Bool anyMarked = FALSE;
- ScreenPtr pScreen;
- WindowPtr pFirstChange;
- WindowPtr pChild;
- RegionPtr gravitate[StaticGravity + 1];
- unsigned g;
- int nx, ny; /* destination x,y */
- int newx, newy; /* new inner window position */
- RegionPtr pRegion = NULL;
- RegionPtr destClip; /* portions of destination already written */
- RegionPtr oldWinClip = NULL; /* old clip list for window */
- RegionPtr borderVisible = NullRegion; /* visible area of the border */
- Bool shrunk = FALSE; /* shrunk in an inner dimension */
- Bool moved = FALSE; /* window position changed */
- WindowPtr pLayerWin;
-
- /* if this is a root window, can't be resized */
- if (!(pParent = pWin->parent))
- return ;
-
- pScreen = pWin->drawable.pScreen;
- newx = pParent->drawable.x + x + bw;
- newy = pParent->drawable.y + y + bw;
- if (WasViewable)
- {
- anyMarked = FALSE;
- /*
- * save the visible region of the window
- */
- oldRegion = RegionCreate(NullBox, 1);
- RegionCopy(oldRegion, &pWin->winSize);
-
- /*
- * categorize child windows into regions to be moved
- */
- for (g = 0; g <= StaticGravity; g++)
- gravitate[g] = (RegionPtr) NULL;
- for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
- {
- g = pChild->winGravity;
- if (g != UnmapGravity)
- {
- if (!gravitate[g])
- gravitate[g] = RegionCreate(NullBox, 1);
- RegionUnion(gravitate[g],
- gravitate[g], &pChild->borderClip);
- }
- else
- {
- UnmapWindow(pChild, TRUE);
- anyMarked = TRUE;
- }
- }
- anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
- &pLayerWin);
-
- oldWinClip = NULL;
- if (pWin->bitGravity != ForgetGravity)
- {
- oldWinClip = RegionCreate(NullBox, 1);
- RegionCopy(oldWinClip, &pWin->clipList);
- }
- /*
- * if the window is changing size, borderExposed
- * can't be computed correctly without some help.
- */
- if (pWin->drawable.height > h || pWin->drawable.width > w)
- shrunk = TRUE;
-
- if (newx != oldx || newy != oldy)
- moved = TRUE;
-
- if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
- HasBorder (pWin))
- {
- borderVisible = RegionCreate(NullBox, 1);
- /* for tiled borders, we punt and draw the whole thing */
- if (pWin->borderIsPixel || !moved)
- {
- if (shrunk || moved)
- RegionSubtract(borderVisible,
- &pWin->borderClip,
- &pWin->winSize);
- else
- RegionCopy(borderVisible,
- &pWin->borderClip);
- }
- }
- }
- pWin->origin.x = x + bw;
- pWin->origin.y = y + bw;
- pWin->drawable.height = h;
- pWin->drawable.width = w;
-
- x = pWin->drawable.x = newx;
- y = pWin->drawable.y = newy;
-
- SetWinSize (pWin);
- SetBorderSize (pWin);
-
- dw = (int)w - (int)width;
- dh = (int)h - (int)height;
- ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
-
- /* let the hardware adjust background and border pixmaps, if any */
- (*pScreen->PositionWindow)(pWin, x, y);
-
- pFirstChange = MoveWindowInStack(pWin, pSib);
-
- if (WasViewable)
- {
- pRegion = RegionCreate(NullBox, 1);
-
- if (pLayerWin == pWin)
- anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
- NULL);
- else
- anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
- NULL);
-
- if (pWin->valdata)
- {
- pWin->valdata->before.resized = TRUE;
- pWin->valdata->before.borderVisible = borderVisible;
- }
-
-
- if (anyMarked)
- (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
- /*
- * the entire window is trashed unless bitGravity
- * recovers portions of it
- */
- RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList);
- }
-
- GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
-
- if (WasViewable)
- {
- /* avoid the border */
- if (HasBorder (pWin))
- {
- int offx, offy, dx, dy;
-
- /* kruft to avoid double translates for each gravity */
- offx = 0;
- offy = 0;
- for (g = 0; g <= StaticGravity; g++)
- {
- if (!gravitate[g])
- continue;
-
- /* align winSize to gravitate[g].
- * winSize is in new coordinates,
- * gravitate[g] is still in old coordinates */
- GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
-
- dx = (oldx - nx) - offx;
- dy = (oldy - ny) - offy;
- if (dx || dy)
- {
- RegionTranslate(&pWin->winSize, dx, dy);
- offx += dx;
- offy += dy;
- }
- RegionIntersect(gravitate[g], gravitate[g],
- &pWin->winSize);
- }
- /* get winSize back where it belongs */
- if (offx || offy)
- RegionTranslate(&pWin->winSize, -offx, -offy);
- }
- /*
- * add screen bits to the appropriate bucket
- */
-
- if (oldWinClip)
- {
- /*
- * clip to new clipList
- */
- RegionCopy(pRegion, oldWinClip);
- RegionTranslate(pRegion, nx - oldx, ny - oldy);
- RegionIntersect(oldWinClip, pRegion, &pWin->clipList);
- /*
- * don't step on any gravity bits which will be copied after this
- * region. Note -- this assumes that the regions will be copied
- * in gravity order.
- */
- for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
- {
- if (gravitate[g])
- RegionSubtract(oldWinClip, oldWinClip,
- gravitate[g]);
- }
- RegionTranslate(oldWinClip, oldx - nx, oldy - ny);
- g = pWin->bitGravity;
- if (!gravitate[g])
- gravitate[g] = oldWinClip;
- else
- {
- RegionUnion(gravitate[g], gravitate[g], oldWinClip);
- RegionDestroy(oldWinClip);
- }
- }
-
- /*
- * move the bits on the screen
- */
-
- destClip = NULL;
-
- for (g = 0; g <= StaticGravity; g++)
- {
- if (!gravitate[g])
- continue;
-
- GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
-
- oldpt.x = oldx + (x - nx);
- oldpt.y = oldy + (y - ny);
-
- /* Note that gravitate[g] is *translated* by CopyWindow */
-
- /* only copy the remaining useful bits */
-
- RegionIntersect(gravitate[g], gravitate[g], oldRegion);
-
- /* clip to not overwrite already copied areas */
-
- if (destClip) {
- RegionTranslate(destClip, oldpt.x - x, oldpt.y - y);
- RegionSubtract(gravitate[g], gravitate[g], destClip);
- RegionTranslate(destClip, x - oldpt.x, y - oldpt.y);
- }
-
- /* and move those bits */
-
- if (oldpt.x != x || oldpt.y != y
-#ifdef COMPOSITE
- || pWin->redirectDraw
-#endif
- )
- {
- (*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
- }
-
- /* remove any overwritten bits from the remaining useful bits */
-
- RegionSubtract(oldRegion, oldRegion, gravitate[g]);
-
- /*
- * recompute exposed regions of child windows
- */
-
- for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
- {
- if (pChild->winGravity != g)
- continue;
- RegionIntersect(pRegion,
- &pChild->borderClip, gravitate[g]);
- TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
- }
-
- /*
- * remove the successfully copied regions of the
- * window from its exposed region
- */
-
- if (g == pWin->bitGravity)
- RegionSubtract(&pWin->valdata->after.exposed,
- &pWin->valdata->after.exposed, gravitate[g]);
- if (!destClip)
- destClip = gravitate[g];
- else
- {
- RegionUnion(destClip, destClip, gravitate[g]);
- RegionDestroy(gravitate[g]);
- }
- }
-
- RegionDestroy(oldRegion);
- RegionDestroy(pRegion);
- if (destClip)
- RegionDestroy(destClip);
- if (anyMarked)
- (*pScreen->HandleExposures)(pLayerWin->parent);
- if (anyMarked && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
- VTOther);
- }
- if (pWin->realized)
- WindowsRestructured ();
-}
-
-WindowPtr
-miGetLayerWindow(WindowPtr pWin)
-{
- return pWin->firstChild;
-}
-
-/******
- *
- * miSetShape
- * The border/window shape has changed. Recompute winSize/borderSize
- * and send appropriate exposure events
- */
-
-void
-miSetShape(WindowPtr pWin, int kind)
-{
- Bool WasViewable = (Bool)(pWin->viewable);
- ScreenPtr pScreen = pWin->drawable.pScreen;
- Bool anyMarked = FALSE;
- WindowPtr pLayerWin;
-
- if (kind != ShapeInput) {
- if (WasViewable)
- {
- anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
- &pLayerWin);
- if (pWin->valdata)
- {
- if (HasBorder (pWin))
- {
- RegionPtr borderVisible;
-
- borderVisible = RegionCreate(NullBox, 1);
- RegionSubtract(borderVisible,
- &pWin->borderClip, &pWin->winSize);
- pWin->valdata->before.borderVisible = borderVisible;
- }
- pWin->valdata->before.resized = TRUE;
- }
- }
-
- SetWinSize (pWin);
- SetBorderSize (pWin);
-
- ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
-
- if (WasViewable)
- {
- anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
- NULL);
-
- if (anyMarked)
- (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow,
- VTOther);
- }
-
- if (WasViewable)
- {
- if (anyMarked)
- (*pScreen->HandleExposures)(pLayerWin->parent);
- if (anyMarked && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow,
- VTOther);
- }
- }
- if (pWin->realized)
- WindowsRestructured ();
- CheckCursorConfinement(pWin);
-}
-
-/* Keeps the same inside(!) origin */
-
-void
-miChangeBorderWidth(WindowPtr pWin, unsigned int width)
-{
- int oldwidth;
- Bool anyMarked = FALSE;
- ScreenPtr pScreen;
- Bool WasViewable = (Bool)(pWin->viewable);
- Bool HadBorder;
- WindowPtr pLayerWin;
-
- oldwidth = wBorderWidth (pWin);
- if (oldwidth == width)
- return;
- HadBorder = HasBorder(pWin);
- pScreen = pWin->drawable.pScreen;
- if (WasViewable && width < oldwidth)
- anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
-
- pWin->borderWidth = width;
- SetBorderSize (pWin);
-
- if (WasViewable)
- {
- if (width > oldwidth)
- {
- anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
- &pLayerWin);
- /*
- * save the old border visible region to correctly compute
- * borderExposed.
- */
- if (pWin->valdata && HadBorder)
- {
- RegionPtr borderVisible;
- borderVisible = RegionCreate(NULL, 1);
- RegionSubtract(borderVisible,
- &pWin->borderClip, &pWin->winSize);
- pWin->valdata->before.borderVisible = borderVisible;
- }
- }
-
- if (anyMarked)
- {
- (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
- (*pScreen->HandleExposures)(pLayerWin->parent);
- }
- if (anyMarked && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
- VTOther);
- }
- if (pWin->realized)
- WindowsRestructured ();
-}
-
-void
-miMarkUnrealizedWindow(WindowPtr pChild, WindowPtr pWin, Bool fromConfigure)
-{
- if ((pChild != pWin) || fromConfigure)
- {
- RegionEmpty(&pChild->clipList);
- if (pChild->drawable.pScreen->ClipNotify)
- (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
- RegionEmpty(&pChild->borderClip);
- }
-}
-
-void
-miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
-{
- WindowPtr pChild;
-
- for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
- {
- if (pChild->drawable.depth == depth)
- RegionUnion(pReg, pReg, &pChild->borderClip);
-
- if (pChild->firstChild)
- miSegregateChildren(pChild, pReg, depth);
- }
-}
+ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include <X11/extensions/shapeconst.h> +#include "regionstr.h" +#include "region.h" +#include "mi.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "mivalidate.h" + +void +miClearToBackground(WindowPtr pWin, + int x, int y, int w, int h, Bool generateExposures) +{ + BoxRec box; + RegionRec reg; + BoxPtr extents; + int x1, y1, x2, y2; + + /* compute everything using ints to avoid overflow */ + + x1 = pWin->drawable.x + x; + y1 = pWin->drawable.y + y; + if (w) + x2 = x1 + (int) w; + else + x2 = x1 + (int) pWin->drawable.width - (int) x; + if (h) + y2 = y1 + h; + else + y2 = y1 + (int) pWin->drawable.height - (int) y; + + extents = &pWin->clipList.extents; + + /* clip the resulting rectangle to the window clipList extents. This + * makes sure that the result will fit in a box, given that the + * screen is < 32768 on a side. + */ + + if (x1 < extents->x1) + x1 = extents->x1; + if (x2 > extents->x2) + x2 = extents->x2; + if (y1 < extents->y1) + y1 = extents->y1; + if (y2 > extents->y2) + y2 = extents->y2; + + if (x2 <= x1 || y2 <= y1) { + x2 = x1 = 0; + y2 = y1 = 0; + } + + box.x1 = x1; + box.x2 = x2; + box.y1 = y1; + box.y2 = y2; + + RegionInit(®, &box, 1); + + RegionIntersect(®, ®, &pWin->clipList); + if (generateExposures) + (*pWin->drawable.pScreen->WindowExposures) (pWin, ®, NULL); + else if (pWin->backgroundState != None) + miPaintWindow(pWin, ®, PW_BACKGROUND); + RegionUninit(®); +} + +void +miMarkWindow(WindowPtr pWin) +{ + ValidatePtr val; + + if (pWin->valdata) + return; + val = (ValidatePtr) xnfalloc(sizeof(ValidateRec)); + val->before.oldAbsCorner.x = pWin->drawable.x; + val->before.oldAbsCorner.y = pWin->drawable.y; + val->before.borderVisible = NullRegion; + val->before.resized = FALSE; + pWin->valdata = val; +} + +Bool +miMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin) +{ + BoxPtr box; + WindowPtr pChild, pLast; + Bool anyMarked = FALSE; + MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow; + + /* single layered systems are easy */ + if (ppLayerWin) + *ppLayerWin = pWin; + + if (pWin == pFirst) { + /* Blindly mark pWin and all of its inferiors. This is a slight + * overkill if there are mapped windows that outside pWin's border, + * but it's better than wasting time on RectIn checks. + */ + pChild = pWin; + while (1) { + if (pChild->viewable) { + if (RegionBroken(&pChild->winSize)) + SetWinSize(pChild); + if (RegionBroken(&pChild->borderSize)) + SetBorderSize(pChild); + (*MarkWindow) (pChild); + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + } + while (!pChild->nextSib && (pChild != pWin)) + pChild = pChild->parent; + if (pChild == pWin) + break; + pChild = pChild->nextSib; + } + anyMarked = TRUE; + pFirst = pFirst->nextSib; + } + if ((pChild = pFirst)) { + box = RegionExtents(&pWin->borderSize); + pLast = pChild->parent->lastChild; + while (1) { + if (pChild->viewable) { + if (RegionBroken(&pChild->winSize)) + SetWinSize(pChild); + if (RegionBroken(&pChild->borderSize)) + SetBorderSize(pChild); + if (RegionContainsRect(&pChild->borderSize, box)) { + (*MarkWindow) (pChild); + anyMarked = TRUE; + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + } + } + while (!pChild->nextSib && (pChild != pLast)) + pChild = pChild->parent; + if (pChild == pLast) + break; + pChild = pChild->nextSib; + } + } + if (anyMarked) + (*MarkWindow) (pWin->parent); + return anyMarked; +} + +/***** + * miHandleValidateExposures(pWin) + * starting at pWin, draw background in any windows that have exposure + * regions, translate the regions, restore any backing store, + * and then send any regions still exposed to the client + *****/ +void +miHandleValidateExposures(WindowPtr pWin) +{ + WindowPtr pChild; + ValidatePtr val; + WindowExposuresProcPtr WindowExposures; + + pChild = pWin; + WindowExposures = pChild->drawable.pScreen->WindowExposures; + while (1) { + if ( (val = pChild->valdata) && val!=UnmapValData) { + if (RegionNotEmpty(&val->after.borderExposed)) + miPaintWindow(pChild, &val->after.borderExposed, PW_BORDER); + RegionUninit(&val->after.borderExposed); + (*WindowExposures) (pChild, &val->after.exposed, NullRegion); + RegionUninit(&val->after.exposed); + free(val); + pChild->valdata = NULL; + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + } + while (!pChild->nextSib && (pChild != pWin)) + pChild = pChild->parent; + if (pChild == pWin) + break; + pChild = pChild->nextSib; + } +} + +void +miMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind) +{ + WindowPtr pParent; + Bool WasViewable = (Bool) (pWin->viewable); + short bw; + RegionPtr oldRegion = NULL; + DDXPointRec oldpt; + Bool anyMarked = FALSE; + ScreenPtr pScreen; + WindowPtr windowToValidate; + WindowPtr pLayerWin; + + /* if this is a root window, can't be moved */ + if (!(pParent = pWin->parent)) + return; + pScreen = pWin->drawable.pScreen; + bw = wBorderWidth(pWin); + + oldpt.x = pWin->drawable.x; + oldpt.y = pWin->drawable.y; + if (WasViewable) { + oldRegion = RegionCreate(NullBox, 1); + RegionCopy(oldRegion, &pWin->borderClip); + anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin); + } + pWin->origin.x = x + (int) bw; + pWin->origin.y = y + (int) bw; + x = pWin->drawable.x = pParent->drawable.x + x + (int) bw; + y = pWin->drawable.y = pParent->drawable.y + y + (int) bw; + + SetWinSize(pWin); + SetBorderSize(pWin); + + (*pScreen->PositionWindow) (pWin, x, y); + + windowToValidate = MoveWindowInStack(pWin, pNextSib); + + ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0); + + if (WasViewable) { + if (pLayerWin == pWin) + anyMarked |= (*pScreen->MarkOverlappedWindows) + (pWin, windowToValidate, NULL); + else + anyMarked |= (*pScreen->MarkOverlappedWindows) + (pWin, pLayerWin, NULL); + + if (anyMarked) { + (*pScreen->ValidateTree) (pLayerWin->parent, NullWindow, kind); + (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, oldRegion); + RegionDestroy(oldRegion); + /* XXX need to retile border if ParentRelative origin */ + (*pScreen->HandleExposures) (pLayerWin->parent); + } + if (anyMarked && pScreen->PostValidateTree) + (*pScreen->PostValidateTree) (pLayerWin->parent, NullWindow, kind); + } + if (pWin->realized) + WindowsRestructured(); +} + +/* + * pValid is a region of the screen which has been + * successfully copied -- recomputed exposed regions for affected windows + */ + +static int +miRecomputeExposures(WindowPtr pWin, pointer value) +{ /* must conform to VisitWindowProcPtr */ + RegionPtr pValid = (RegionPtr) value; + + if (pWin->valdata) { +#ifdef COMPOSITE + /* + * Redirected windows are not affected by parent window + * gravity manipulations, so don't recompute their + * exposed areas here. + */ + if (pWin->redirectDraw != RedirectDrawNone) + return WT_DONTWALKCHILDREN; +#endif + /* + * compute exposed regions of this window + */ + RegionSubtract(&pWin->valdata->after.exposed, &pWin->clipList, pValid); + /* + * compute exposed regions of the border + */ + RegionSubtract(&pWin->valdata->after.borderExposed, + &pWin->borderClip, &pWin->winSize); + RegionSubtract(&pWin->valdata->after.borderExposed, + &pWin->valdata->after.borderExposed, pValid); + return WT_WALKCHILDREN; + } + return WT_NOMATCH; +} + +void +miSlideAndSizeWindow(WindowPtr pWin, + int x, int y, + unsigned int w, unsigned int h, WindowPtr pSib) +{ + WindowPtr pParent; + Bool WasViewable = (Bool) (pWin->viewable); + unsigned short width = pWin->drawable.width, height = pWin->drawable.height; + short oldx = pWin->drawable.x, oldy = pWin->drawable.y; + int bw = wBorderWidth(pWin); + short dw, dh; + DDXPointRec oldpt; + RegionPtr oldRegion = NULL; + Bool anyMarked = FALSE; + ScreenPtr pScreen; + WindowPtr pFirstChange; + WindowPtr pChild; + RegionPtr gravitate[StaticGravity + 1]; + unsigned g; + int nx, ny; /* destination x,y */ + int newx, newy; /* new inner window position */ + RegionPtr pRegion = NULL; + RegionPtr destClip; /* portions of destination already written */ + RegionPtr oldWinClip = NULL; /* old clip list for window */ + RegionPtr borderVisible = NullRegion; /* visible area of the border */ + Bool shrunk = FALSE; /* shrunk in an inner dimension */ + Bool moved = FALSE; /* window position changed */ + WindowPtr pLayerWin; + + /* if this is a root window, can't be resized */ + if (!(pParent = pWin->parent)) + return; + + pScreen = pWin->drawable.pScreen; + newx = pParent->drawable.x + x + bw; + newy = pParent->drawable.y + y + bw; + if (WasViewable) { + anyMarked = FALSE; + /* + * save the visible region of the window + */ + oldRegion = RegionCreate(NullBox, 1); + RegionCopy(oldRegion, &pWin->winSize); + + /* + * categorize child windows into regions to be moved + */ + for (g = 0; g <= StaticGravity; g++) + gravitate[g] = (RegionPtr) NULL; + for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { + g = pChild->winGravity; + if (g != UnmapGravity) { + if (!gravitate[g]) + gravitate[g] = RegionCreate(NullBox, 1); + RegionUnion(gravitate[g], gravitate[g], &pChild->borderClip); + } + else { + UnmapWindow(pChild, TRUE); + anyMarked = TRUE; + } + } + anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin); + + oldWinClip = NULL; + if (pWin->bitGravity != ForgetGravity) { + oldWinClip = RegionCreate(NullBox, 1); + RegionCopy(oldWinClip, &pWin->clipList); + } + /* + * if the window is changing size, borderExposed + * can't be computed correctly without some help. + */ + if (pWin->drawable.height > h || pWin->drawable.width > w) + shrunk = TRUE; + + if (newx != oldx || newy != oldy) + moved = TRUE; + + if ((pWin->drawable.height != h || pWin->drawable.width != w) && + HasBorder(pWin)) { + borderVisible = RegionCreate(NullBox, 1); + /* for tiled borders, we punt and draw the whole thing */ + if (pWin->borderIsPixel || !moved) { + if (shrunk || moved) + RegionSubtract(borderVisible, + &pWin->borderClip, &pWin->winSize); + else + RegionCopy(borderVisible, &pWin->borderClip); + } + } + } + pWin->origin.x = x + bw; + pWin->origin.y = y + bw; + pWin->drawable.height = h; + pWin->drawable.width = w; + + x = pWin->drawable.x = newx; + y = pWin->drawable.y = newy; + + SetWinSize(pWin); + SetBorderSize(pWin); + + dw = (int) w - (int) width; + dh = (int) h - (int) height; + ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh); + + /* let the hardware adjust background and border pixmaps, if any */ + (*pScreen->PositionWindow) (pWin, x, y); + + pFirstChange = MoveWindowInStack(pWin, pSib); + + if (WasViewable) { + pRegion = RegionCreate(NullBox, 1); + + if (pLayerWin == pWin) + anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange, + NULL); + else + anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin, + NULL); + + if (pWin->valdata) { + pWin->valdata->before.resized = TRUE; + pWin->valdata->before.borderVisible = borderVisible; + } + + if (anyMarked) + (*pScreen->ValidateTree) (pLayerWin->parent, pFirstChange, VTOther); + /* + * the entire window is trashed unless bitGravity + * recovers portions of it + */ + RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList); + } + + GravityTranslate(x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny); + + if (WasViewable) { + /* avoid the border */ + if (HasBorder(pWin)) { + int offx, offy, dx, dy; + + /* kruft to avoid double translates for each gravity */ + offx = 0; + offy = 0; + for (g = 0; g <= StaticGravity; g++) { + if (!gravitate[g]) + continue; + + /* align winSize to gravitate[g]. + * winSize is in new coordinates, + * gravitate[g] is still in old coordinates */ + GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny); + + dx = (oldx - nx) - offx; + dy = (oldy - ny) - offy; + if (dx || dy) { + RegionTranslate(&pWin->winSize, dx, dy); + offx += dx; + offy += dy; + } + RegionIntersect(gravitate[g], gravitate[g], &pWin->winSize); + } + /* get winSize back where it belongs */ + if (offx || offy) + RegionTranslate(&pWin->winSize, -offx, -offy); + } + /* + * add screen bits to the appropriate bucket + */ + + if (oldWinClip) { + /* + * clip to new clipList + */ + RegionCopy(pRegion, oldWinClip); + RegionTranslate(pRegion, nx - oldx, ny - oldy); + RegionIntersect(oldWinClip, pRegion, &pWin->clipList); + /* + * don't step on any gravity bits which will be copied after this + * region. Note -- this assumes that the regions will be copied + * in gravity order. + */ + for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) { + if (gravitate[g]) + RegionSubtract(oldWinClip, oldWinClip, gravitate[g]); + } + RegionTranslate(oldWinClip, oldx - nx, oldy - ny); + g = pWin->bitGravity; + if (!gravitate[g]) + gravitate[g] = oldWinClip; + else { + RegionUnion(gravitate[g], gravitate[g], oldWinClip); + RegionDestroy(oldWinClip); + } + } + + /* + * move the bits on the screen + */ + + destClip = NULL; + + for (g = 0; g <= StaticGravity; g++) { + if (!gravitate[g]) + continue; + + GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny); + + oldpt.x = oldx + (x - nx); + oldpt.y = oldy + (y - ny); + + /* Note that gravitate[g] is *translated* by CopyWindow */ + + /* only copy the remaining useful bits */ + + RegionIntersect(gravitate[g], gravitate[g], oldRegion); + + /* clip to not overwrite already copied areas */ + + if (destClip) { + RegionTranslate(destClip, oldpt.x - x, oldpt.y - y); + RegionSubtract(gravitate[g], gravitate[g], destClip); + RegionTranslate(destClip, x - oldpt.x, y - oldpt.y); + } + + /* and move those bits */ + + if (oldpt.x != x || oldpt.y != y +#ifdef COMPOSITE + || pWin->redirectDraw +#endif + ) { + (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, + gravitate[g]); + } + + /* remove any overwritten bits from the remaining useful bits */ + + RegionSubtract(oldRegion, oldRegion, gravitate[g]); + + /* + * recompute exposed regions of child windows + */ + + for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { + if (pChild->winGravity != g) + continue; + RegionIntersect(pRegion, &pChild->borderClip, gravitate[g]); + TraverseTree(pChild, miRecomputeExposures, (pointer) pRegion); + } + + /* + * remove the successfully copied regions of the + * window from its exposed region + */ + + if (g == pWin->bitGravity) + RegionSubtract(&pWin->valdata->after.exposed, + &pWin->valdata->after.exposed, gravitate[g]); + if (!destClip) + destClip = gravitate[g]; + else { + RegionUnion(destClip, destClip, gravitate[g]); + RegionDestroy(gravitate[g]); + } + } + + RegionDestroy(oldRegion); + RegionDestroy(pRegion); + if (destClip) + RegionDestroy(destClip); + if (anyMarked) + (*pScreen->HandleExposures) (pLayerWin->parent); + if (anyMarked && pScreen->PostValidateTree) + (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstChange, + VTOther); + } + if (pWin->realized) + WindowsRestructured(); +} + +WindowPtr +miGetLayerWindow(WindowPtr pWin) +{ + return pWin->firstChild; +} + +/****** + * + * miSetShape + * The border/window shape has changed. Recompute winSize/borderSize + * and send appropriate exposure events + */ + +void +miSetShape(WindowPtr pWin, int kind) +{ + Bool WasViewable = (Bool) (pWin->viewable); + ScreenPtr pScreen = pWin->drawable.pScreen; + Bool anyMarked = FALSE; + WindowPtr pLayerWin; + + if (kind != ShapeInput) { + if (WasViewable) { + anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, + &pLayerWin); + if (pWin->valdata) { + if (HasBorder(pWin)) { + RegionPtr borderVisible; + + borderVisible = RegionCreate(NullBox, 1); + RegionSubtract(borderVisible, + &pWin->borderClip, &pWin->winSize); + pWin->valdata->before.borderVisible = borderVisible; + } + pWin->valdata->before.resized = TRUE; + } + } + + SetWinSize(pWin); + SetBorderSize(pWin); + + ResizeChildrenWinSize(pWin, 0, 0, 0, 0); + + if (WasViewable) { + anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL); + + if (anyMarked) + (*pScreen->ValidateTree) (pLayerWin->parent, NullWindow, + VTOther); + } + + if (WasViewable) { + if (anyMarked) + (*pScreen->HandleExposures) (pLayerWin->parent); + if (anyMarked && pScreen->PostValidateTree) + (*pScreen->PostValidateTree) (pLayerWin->parent, NullWindow, + VTOther); + } + } + if (pWin->realized) + WindowsRestructured(); + CheckCursorConfinement(pWin); +} + +/* Keeps the same inside(!) origin */ + +void +miChangeBorderWidth(WindowPtr pWin, unsigned int width) +{ + int oldwidth; + Bool anyMarked = FALSE; + ScreenPtr pScreen; + Bool WasViewable = (Bool) (pWin->viewable); + Bool HadBorder; + WindowPtr pLayerWin; + + oldwidth = wBorderWidth(pWin); + if (oldwidth == width) + return; + HadBorder = HasBorder(pWin); + pScreen = pWin->drawable.pScreen; + if (WasViewable && width < oldwidth) + anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin); + + pWin->borderWidth = width; + SetBorderSize(pWin); + + if (WasViewable) { + if (width > oldwidth) { + anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, + &pLayerWin); + /* + * save the old border visible region to correctly compute + * borderExposed. + */ + if (pWin->valdata && HadBorder) { + RegionPtr borderVisible; + + borderVisible = RegionCreate(NULL, 1); + RegionSubtract(borderVisible, + &pWin->borderClip, &pWin->winSize); + pWin->valdata->before.borderVisible = borderVisible; + } + } + + if (anyMarked) { + (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTOther); + (*pScreen->HandleExposures) (pLayerWin->parent); + } + if (anyMarked && pScreen->PostValidateTree) + (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin, + VTOther); + } + if (pWin->realized) + WindowsRestructured(); +} + +void +miMarkUnrealizedWindow(WindowPtr pChild, WindowPtr pWin, Bool fromConfigure) +{ + if ((pChild != pWin) || fromConfigure) { + RegionEmpty(&pChild->clipList); + if (pChild->drawable.pScreen->ClipNotify) + (*pChild->drawable.pScreen->ClipNotify) (pChild, 0, 0); + RegionEmpty(&pChild->borderClip); + } +} + +void +miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth) +{ + WindowPtr pChild; + + for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { + if (pChild->drawable.depth == depth) + RegionUnion(pReg, pReg, &pChild->borderClip); + + if (pChild->firstChild) + miSegregateChildren(pChild, pReg, depth); + } +} diff --git a/xorg-server/mi/mizerarc.c b/xorg-server/mi/mizerarc.c index 713d0bd04..9dac180d1 100644 --- a/xorg-server/mi/mizerarc.c +++ b/xorg-server/mi/mizerarc.c @@ -1,848 +1,767 @@ -/************************************************************
-
-Copyright 1989, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-Author: Bob Scheifler, MIT X Consortium
-
-********************************************************/
-
-
-/* Derived from:
- * "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
- * by M. L. V. Pitteway
- * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <math.h>
-#include <X11/X.h>
-#include <X11/Xprotostr.h>
-#include "regionstr.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "mi.h"
-#include "mizerarc.h"
-
-#define FULLCIRCLE (360 * 64)
-#define OCTANT (45 * 64)
-#define QUADRANT (90 * 64)
-#define HALFCIRCLE (180 * 64)
-#define QUADRANT3 (270 * 64)
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#define Dsin(d) ((d) == 0 ? 0.0 : ((d) == QUADRANT ? 1.0 : \
- ((d) == HALFCIRCLE ? 0.0 : \
- ((d) == QUADRANT3 ? -1.0 : sin((double)d*(M_PI/11520.0))))))
-
-#define Dcos(d) ((d) == 0 ? 1.0 : ((d) == QUADRANT ? 0.0 : \
- ((d) == HALFCIRCLE ? -1.0 : \
- ((d) == QUADRANT3 ? 0.0 : cos((double)d*(M_PI/11520.0))))))
-
-#define EPSILON45 64
-
-typedef struct {
- int skipStart;
- int haveStart;
- DDXPointRec startPt;
- int haveLast;
- int skipLast;
- DDXPointRec endPt;
- int dashIndex;
- int dashOffset;
- int dashIndexInit;
- int dashOffsetInit;
-} DashInfo;
-
-static miZeroArcPtRec oob = {65536, 65536, 0};
-
-/*
- * (x - l)^2 / (W/2)^2 + (y + H/2)^2 / (H/2)^2 = 1
- *
- * where l is either 0 or .5
- *
- * alpha = 4(W^2)
- * beta = 4(H^2)
- * gamma = 0
- * u = 2(W^2)H
- * v = 4(H^2)l
- * k = -4(H^2)(l^2)
- *
- */
-
-Bool
-miZeroArcSetup(xArc *arc, miZeroArcRec *info, Bool ok360)
-{
- int l;
- int angle1, angle2;
- int startseg, endseg;
- int startAngle, endAngle;
- int i, overlap;
- miZeroArcPtRec start, end;
-
- l = arc->width & 1;
- if (arc->width == arc->height)
- {
- info->alpha = 4;
- info->beta = 4;
- info->k1 = -8;
- info->k3 = -16;
- info->b = 12;
- info->a = (arc->width << 2) - 12;
- info->d = 17 - (arc->width << 1);
- if (l)
- {
- info->b -= 4;
- info->a += 4;
- info->d -= 7;
- }
- }
- else if (!arc->width || !arc->height)
- {
- info->alpha = 0;
- info->beta = 0;
- info->k1 = 0;
- info->k3 = 0;
- info->a = -(int)arc->height;
- info->b = 0;
- info->d = -1;
- }
- else
- {
- /* initial conditions */
- info->alpha = (arc->width * arc->width) << 2;
- info->beta = (arc->height * arc->height) << 2;
- info->k1 = info->beta << 1;
- info->k3 = info->k1 + (info->alpha << 1);
- info->b = l ? 0 : -info->beta;
- info->a = info->alpha * arc->height;
- info->d = info->b - (info->a >> 1) - (info->alpha >> 2);
- if (l)
- info->d -= info->beta >> 2;
- info->a -= info->b;
- /* take first step, d < 0 always */
- info->b -= info->k1;
- info->a += info->k1;
- info->d += info->b;
- /* octant change, b < 0 always */
- info->k1 = -info->k1;
- info->k3 = -info->k3;
- info->b = -info->b;
- info->d = info->b - info->a - info->d;
- info->a = info->a - (info->b << 1);
- }
- info->dx = 1;
- info->dy = 0;
- info->w = (arc->width + 1) >> 1;
- info->h = arc->height >> 1;
- info->xorg = arc->x + (arc->width >> 1);
- info->yorg = arc->y;
- info->xorgo = info->xorg + l;
- info->yorgo = info->yorg + arc->height;
- if (!arc->width)
- {
- if (!arc->height)
- {
- info->x = 0;
- info->y = 0;
- info->initialMask = 0;
- info->startAngle = 0;
- info->endAngle = 0;
- info->start = oob;
- info->end = oob;
- return FALSE;
- }
- info->x = 0;
- info->y = 1;
- }
- else
- {
- info->x = 1;
- info->y = 0;
- }
- angle1 = arc->angle1;
- angle2 = arc->angle2;
- if ((angle1 == 0) && (angle2 >= FULLCIRCLE))
- {
- startAngle = 0;
- endAngle = 0;
- }
- else
- {
- if (angle2 > FULLCIRCLE)
- angle2 = FULLCIRCLE;
- else if (angle2 < -FULLCIRCLE)
- angle2 = -FULLCIRCLE;
- if (angle2 < 0)
- {
- startAngle = angle1 + angle2;
- endAngle = angle1;
- }
- else
- {
- startAngle = angle1;
- endAngle = angle1 + angle2;
- }
- if (startAngle < 0)
- startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE;
- if (startAngle >= FULLCIRCLE)
- startAngle = startAngle % FULLCIRCLE;
- if (endAngle < 0)
- endAngle = FULLCIRCLE - (-endAngle) % FULLCIRCLE;
- if (endAngle >= FULLCIRCLE)
- endAngle = endAngle % FULLCIRCLE;
- }
- info->startAngle = startAngle;
- info->endAngle = endAngle;
- if (ok360 && (startAngle == endAngle) && arc->angle2 &&
- arc->width && arc->height)
- {
- info->initialMask = 0xf;
- info->start = oob;
- info->end = oob;
- return TRUE;
- }
- startseg = startAngle / OCTANT;
- if (!arc->height || (((startseg + 1) & 2) && arc->width))
- {
- start.x = Dcos(startAngle) * ((arc->width + 1) / 2.0);
- if (start.x < 0)
- start.x = -start.x;
- start.y = -1;
- }
- else
- {
- start.y = Dsin(startAngle) * (arc->height / 2.0);
- if (start.y < 0)
- start.y = -start.y;
- start.y = info->h - start.y;
- start.x = 65536;
- }
- endseg = endAngle / OCTANT;
- if (!arc->height || (((endseg + 1) & 2) && arc->width))
- {
- end.x = Dcos(endAngle) * ((arc->width + 1) / 2.0);
- if (end.x < 0)
- end.x = -end.x;
- end.y = -1;
- }
- else
- {
- end.y = Dsin(endAngle) * (arc->height / 2.0);
- if (end.y < 0)
- end.y = -end.y;
- end.y = info->h - end.y;
- end.x = 65536;
- }
- info->firstx = start.x;
- info->firsty = start.y;
- info->initialMask = 0;
- overlap = arc->angle2 && (endAngle <= startAngle);
- for (i = 0; i < 4; i++)
- {
- if (overlap ?
- ((i * QUADRANT <= endAngle) || ((i + 1) * QUADRANT > startAngle)) :
- ((i * QUADRANT <= endAngle) && ((i + 1) * QUADRANT > startAngle)))
- info->initialMask |= (1 << i);
- }
- start.mask = info->initialMask;
- end.mask = info->initialMask;
- startseg >>= 1;
- endseg >>= 1;
- overlap = overlap && (endseg == startseg);
- if (start.x != end.x || start.y != end.y || !overlap)
- {
- if (startseg & 1)
- {
- if (!overlap)
- info->initialMask &= ~(1 << startseg);
- if (start.x > end.x || start.y > end.y)
- end.mask &= ~(1 << startseg);
- }
- else
- {
- start.mask &= ~(1 << startseg);
- if (((start.x < end.x || start.y < end.y) ||
- (start.x == end.x && start.y == end.y && (endseg & 1))) &&
- !overlap)
- end.mask &= ~(1 << startseg);
- }
- if (endseg & 1)
- {
- end.mask &= ~(1 << endseg);
- if (((start.x > end.x || start.y > end.y) ||
- (start.x == end.x && start.y == end.y && !(startseg & 1))) &&
- !overlap)
- start.mask &= ~(1 << endseg);
- }
- else
- {
- if (!overlap)
- info->initialMask &= ~(1 << endseg);
- if (start.x < end.x || start.y < end.y)
- start.mask &= ~(1 << endseg);
- }
- }
- /* take care of case when start and stop are both near 45 */
- /* handle here rather than adding extra code to pixelization loops */
- if (startAngle &&
- ((start.y < 0 && end.y >= 0) || (start.y >= 0 && end.y < 0)))
- {
- i = (startAngle + OCTANT) % OCTANT;
- if (i < EPSILON45 || i > OCTANT - EPSILON45)
- {
- i = (endAngle + OCTANT) % OCTANT;
- if (i < EPSILON45 || i > OCTANT - EPSILON45)
- {
- if (start.y < 0)
- {
- i = Dsin(startAngle) * (arc->height / 2.0);
- if (i < 0)
- i = -i;
- if (info->h - i == end.y)
- start.mask = end.mask;
- }
- else
- {
- i = Dsin(endAngle) * (arc->height / 2.0);
- if (i < 0)
- i = -i;
- if (info->h - i == start.y)
- end.mask = start.mask;
- }
- }
- }
- }
- if (startseg & 1)
- {
- info->start = start;
- info->end = oob;
- }
- else
- {
- info->end = start;
- info->start = oob;
- }
- if (endseg & 1)
- {
- info->altend = end;
- if (info->altend.x < info->end.x || info->altend.y < info->end.y)
- {
- miZeroArcPtRec tmp;
- tmp = info->altend;
- info->altend = info->end;
- info->end = tmp;
- }
- info->altstart = oob;
- }
- else
- {
- info->altstart = end;
- if (info->altstart.x < info->start.x ||
- info->altstart.y < info->start.y)
- {
- miZeroArcPtRec tmp;
- tmp = info->altstart;
- info->altstart = info->start;
- info->start = tmp;
- }
- info->altend = oob;
- }
- if (!info->start.x || !info->start.y)
- {
- info->initialMask = info->start.mask;
- info->start = info->altstart;
- }
- if (!arc->width && (arc->height == 1))
- {
- /* kludge! */
- info->initialMask |= info->end.mask;
- info->initialMask |= info->initialMask << 1;
- info->end.x = 0;
- info->end.mask = 0;
- }
- return FALSE;
-}
-
-#define Pixelate(xval,yval) \
- { \
- pts->x = xval; \
- pts->y = yval; \
- pts++; \
- }
-
-#define DoPix(idx,xval,yval) if (mask & (1 << idx)) Pixelate(xval, yval);
-
-static DDXPointPtr
-miZeroArcPts(xArc *arc, DDXPointPtr pts)
-{
- miZeroArcRec info;
- int x, y, a, b, d, mask;
- int k1, k3, dx, dy;
- Bool do360;
-
- do360 = miZeroArcSetup(arc, &info, TRUE);
- MIARCSETUP();
- mask = info.initialMask;
- if (!(arc->width & 1))
- {
- DoPix(1, info.xorgo, info.yorg);
- DoPix(3, info.xorgo, info.yorgo);
- }
- if (!info.end.x || !info.end.y)
- {
- mask = info.end.mask;
- info.end = info.altend;
- }
- if (do360 && (arc->width == arc->height) && !(arc->width & 1))
- {
- int yorgh = info.yorg + info.h;
- int xorghp = info.xorg + info.h;
- int xorghn = info.xorg - info.h;
-
- while (1)
- {
- Pixelate(info.xorg + x, info.yorg + y);
- Pixelate(info.xorg - x, info.yorg + y);
- Pixelate(info.xorg - x, info.yorgo - y);
- Pixelate(info.xorg + x, info.yorgo - y);
- if (a < 0)
- break;
- Pixelate(xorghp - y, yorgh - x);
- Pixelate(xorghn + y, yorgh - x);
- Pixelate(xorghn + y, yorgh + x);
- Pixelate(xorghp - y, yorgh + x);
- MIARCCIRCLESTEP(;);
- }
- if (x > 1 && pts[-1].x == pts[-5].x && pts[-1].y == pts[-5].y)
- pts -= 4;
- x = info.w;
- y = info.h;
- }
- else if (do360)
- {
- while (y < info.h || x < info.w)
- {
- MIARCOCTANTSHIFT(;);
- Pixelate(info.xorg + x, info.yorg + y);
- Pixelate(info.xorgo - x, info.yorg + y);
- Pixelate(info.xorgo - x, info.yorgo - y);
- Pixelate(info.xorg + x, info.yorgo - y);
- MIARCSTEP(;,;);
- }
- }
- else
- {
- while (y < info.h || x < info.w)
- {
- MIARCOCTANTSHIFT(;);
- if ((x == info.start.x) || (y == info.start.y))
- {
- mask = info.start.mask;
- info.start = info.altstart;
- }
- DoPix(0, info.xorg + x, info.yorg + y);
- DoPix(1, info.xorgo - x, info.yorg + y);
- DoPix(2, info.xorgo - x, info.yorgo - y);
- DoPix(3, info.xorg + x, info.yorgo - y);
- if ((x == info.end.x) || (y == info.end.y))
- {
- mask = info.end.mask;
- info.end = info.altend;
- }
- MIARCSTEP(;,;);
- }
- }
- if ((x == info.start.x) || (y == info.start.y))
- mask = info.start.mask;
- DoPix(0, info.xorg + x, info.yorg + y);
- DoPix(2, info.xorgo - x, info.yorgo - y);
- if (arc->height & 1)
- {
- DoPix(1, info.xorgo - x, info.yorg + y);
- DoPix(3, info.xorg + x, info.yorgo - y);
- }
- return pts;
-}
-
-#undef DoPix
-#define DoPix(idx,xval,yval) \
- if (mask & (1 << idx)) \
- { \
- arcPts[idx]->x = xval; \
- arcPts[idx]->y = yval; \
- arcPts[idx]++; \
- }
-
-static void
-miZeroArcDashPts(
- GCPtr pGC,
- xArc *arc,
- DashInfo *dinfo,
- DDXPointPtr points,
- int maxPts,
- DDXPointPtr *evenPts,
- DDXPointPtr *oddPts )
-{
- miZeroArcRec info;
- int x, y, a, b, d, mask;
- int k1, k3, dx, dy;
- int dashRemaining;
- DDXPointPtr arcPts[4];
- DDXPointPtr startPts[5], endPts[5];
- int deltas[5];
- DDXPointPtr startPt, pt, lastPt, pts;
- int i, j, delta, ptsdelta, seg, startseg;
-
- for (i = 0; i < 4; i++)
- arcPts[i] = points + (i * maxPts);
- (void)miZeroArcSetup(arc, &info, FALSE);
- MIARCSETUP();
- mask = info.initialMask;
- startseg = info.startAngle / QUADRANT;
- startPt = arcPts[startseg];
- if (!(arc->width & 1))
- {
- DoPix(1, info.xorgo, info.yorg);
- DoPix(3, info.xorgo, info.yorgo);
- }
- if (!info.end.x || !info.end.y)
- {
- mask = info.end.mask;
- info.end = info.altend;
- }
- while (y < info.h || x < info.w)
- {
- MIARCOCTANTSHIFT(;);
- if ((x == info.firstx) || (y == info.firsty))
- startPt = arcPts[startseg];
- if ((x == info.start.x) || (y == info.start.y))
- {
- mask = info.start.mask;
- info.start = info.altstart;
- }
- DoPix(0, info.xorg + x, info.yorg + y);
- DoPix(1, info.xorgo - x, info.yorg + y);
- DoPix(2, info.xorgo - x, info.yorgo - y);
- DoPix(3, info.xorg + x, info.yorgo - y);
- if ((x == info.end.x) || (y == info.end.y))
- {
- mask = info.end.mask;
- info.end = info.altend;
- }
- MIARCSTEP(;,;);
- }
- if ((x == info.firstx) || (y == info.firsty))
- startPt = arcPts[startseg];
- if ((x == info.start.x) || (y == info.start.y))
- mask = info.start.mask;
- DoPix(0, info.xorg + x, info.yorg + y);
- DoPix(2, info.xorgo - x, info.yorgo - y);
- if (arc->height & 1)
- {
- DoPix(1, info.xorgo - x, info.yorg + y);
- DoPix(3, info.xorg + x, info.yorgo - y);
- }
- for (i = 0; i < 4; i++)
- {
- seg = (startseg + i) & 3;
- pt = points + (seg * maxPts);
- if (seg & 1)
- {
- startPts[i] = pt;
- endPts[i] = arcPts[seg];
- deltas[i] = 1;
- }
- else
- {
- startPts[i] = arcPts[seg] - 1;
- endPts[i] = pt - 1;
- deltas[i] = -1;
- }
- }
- startPts[4] = startPts[0];
- endPts[4] = startPt;
- startPts[0] = startPt;
- if (startseg & 1)
- {
- if (startPts[4] != endPts[4])
- endPts[4]--;
- deltas[4] = 1;
- }
- else
- {
- if (startPts[0] > startPts[4])
- startPts[0]--;
- if (startPts[4] < endPts[4])
- endPts[4]--;
- deltas[4] = -1;
- }
- if (arc->angle2 < 0)
- {
- DDXPointPtr tmps, tmpe;
- int tmpd;
-
- tmpd = deltas[0];
- tmps = startPts[0] - tmpd;
- tmpe = endPts[0] - tmpd;
- startPts[0] = endPts[4] - deltas[4];
- endPts[0] = startPts[4] - deltas[4];
- deltas[0] = -deltas[4];
- startPts[4] = tmpe;
- endPts[4] = tmps;
- deltas[4] = -tmpd;
- tmpd = deltas[1];
- tmps = startPts[1] - tmpd;
- tmpe = endPts[1] - tmpd;
- startPts[1] = endPts[3] - deltas[3];
- endPts[1] = startPts[3] - deltas[3];
- deltas[1] = -deltas[3];
- startPts[3] = tmpe;
- endPts[3] = tmps;
- deltas[3] = -tmpd;
- tmps = startPts[2] - deltas[2];
- startPts[2] = endPts[2] - deltas[2];
- endPts[2] = tmps;
- deltas[2] = -deltas[2];
- }
- for (i = 0; i < 5 && startPts[i] == endPts[i]; i++)
- ;
- if (i == 5)
- return;
- pt = startPts[i];
- for (j = 4; startPts[j] == endPts[j]; j--)
- ;
- lastPt = endPts[j] - deltas[j];
- if (dinfo->haveLast &&
- (pt->x == dinfo->endPt.x) && (pt->y == dinfo->endPt.y))
- {
- startPts[i] += deltas[i];
- }
- else
- {
- dinfo->dashIndex = dinfo->dashIndexInit;
- dinfo->dashOffset = dinfo->dashOffsetInit;
- }
- if (!dinfo->skipStart && (info.startAngle != info.endAngle))
- {
- dinfo->startPt = *pt;
- dinfo->haveStart = TRUE;
- }
- else if (!dinfo->skipLast && dinfo->haveStart &&
- (lastPt->x == dinfo->startPt.x) &&
- (lastPt->y == dinfo->startPt.y) &&
- (lastPt != startPts[i]))
- endPts[j] = lastPt;
- if (info.startAngle != info.endAngle)
- {
- dinfo->haveLast = TRUE;
- dinfo->endPt = *lastPt;
- }
- dashRemaining = pGC->dash[dinfo->dashIndex] - dinfo->dashOffset;
- for (i = 0; i < 5; i++)
- {
- pt = startPts[i];
- lastPt = endPts[i];
- delta = deltas[i];
- while (pt != lastPt)
- {
- if (dinfo->dashIndex & 1)
- {
- pts = *oddPts;
- ptsdelta = -1;
- }
- else
- {
- pts = *evenPts;
- ptsdelta = 1;
- }
- while ((pt != lastPt) && --dashRemaining >= 0)
- {
- *pts = *pt;
- pts += ptsdelta;
- pt += delta;
- }
- if (dinfo->dashIndex & 1)
- *oddPts = pts;
- else
- *evenPts = pts;
- if (dashRemaining <= 0)
- {
- if (++(dinfo->dashIndex) == pGC->numInDashList)
- dinfo->dashIndex = 0;
- dashRemaining = pGC->dash[dinfo->dashIndex];
- }
- }
- }
- dinfo->dashOffset = pGC->dash[dinfo->dashIndex] - dashRemaining;
-}
-
-void
-miZeroPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs)
-{
- int maxPts = 0;
- int n, maxw = 0;
- xArc *arc;
- int i;
- DDXPointPtr points, pts, oddPts = NULL;
- DDXPointPtr pt;
- int numPts;
- Bool dospans;
- int *widths = NULL;
- XID fgPixel = pGC->fgPixel;
- DashInfo dinfo;
-
- for (arc = parcs, i = narcs; --i >= 0; arc++)
- {
- if (!miCanZeroArc(arc))
- miPolyArc(pDraw, pGC, 1, arc);
- else
- {
- if (arc->width > arc->height)
- n = arc->width + (arc->height >> 1);
- else
- n = arc->height + (arc->width >> 1);
- if (n > maxPts)
- maxPts = n;
- }
- }
- if (!maxPts)
- return;
- numPts = maxPts << 2;
- dospans = (pGC->fillStyle != FillSolid);
- if (dospans)
- {
- widths = malloc(sizeof(int) * numPts);
- if (!widths)
- return;
- maxw = 0;
- }
- if (pGC->lineStyle != LineSolid)
- {
- numPts <<= 1;
- dinfo.haveStart = FALSE;
- dinfo.skipStart = FALSE;
- dinfo.haveLast = FALSE;
- dinfo.dashIndexInit = 0;
- dinfo.dashOffsetInit = 0;
- miStepDash((int)pGC->dashOffset, &dinfo.dashIndexInit,
- (unsigned char *) pGC->dash, (int)pGC->numInDashList,
- &dinfo.dashOffsetInit);
- }
- points = malloc(sizeof(DDXPointRec) * numPts);
- if (!points)
- {
- if (dospans)
- {
- free(widths);
- }
- return;
- }
- for (arc = parcs, i = narcs; --i >= 0; arc++)
- {
- if (miCanZeroArc(arc))
- {
- if (pGC->lineStyle == LineSolid)
- pts = miZeroArcPts(arc, points);
- else
- {
- pts = points;
- oddPts = &points[(numPts >> 1) - 1];
- dinfo.skipLast = i;
- miZeroArcDashPts(pGC, arc, &dinfo,
- oddPts + 1, maxPts, &pts, &oddPts);
- dinfo.skipStart = TRUE;
- }
- n = pts - points;
- if (!dospans)
- (*pGC->ops->PolyPoint)(pDraw, pGC, CoordModeOrigin, n, points);
- else
- {
- if (n > maxw)
- {
- while (maxw < n)
- widths[maxw++] = 1;
- }
- if (pGC->miTranslate)
- {
- for (pt = points; pt != pts; pt++)
- {
- pt->x += pDraw->x;
- pt->y += pDraw->y;
- }
- }
- (*pGC->ops->FillSpans)(pDraw, pGC, n, points, widths, FALSE);
- }
- if (pGC->lineStyle != LineDoubleDash)
- continue;
- if ((pGC->fillStyle == FillSolid) ||
- (pGC->fillStyle == FillStippled))
- {
- ChangeGCVal gcval;
- gcval.val = pGC->bgPixel;
- ChangeGC(NullClient, pGC, GCForeground, &gcval);
- ValidateGC(pDraw, pGC);
- }
- pts = &points[numPts >> 1];
- oddPts++;
- n = pts - oddPts;
- if (!dospans)
- (*pGC->ops->PolyPoint)(pDraw, pGC, CoordModeOrigin, n, oddPts);
- else
- {
- if (n > maxw)
- {
- while (maxw < n)
- widths[maxw++] = 1;
- }
- if (pGC->miTranslate)
- {
- for (pt = oddPts; pt != pts; pt++)
- {
- pt->x += pDraw->x;
- pt->y += pDraw->y;
- }
- }
- (*pGC->ops->FillSpans)(pDraw, pGC, n, oddPts, widths, FALSE);
- }
- if ((pGC->fillStyle == FillSolid) ||
- (pGC->fillStyle == FillStippled))
- {
- ChangeGCVal gcval;
- gcval.val = fgPixel;
- ChangeGC(NullClient, pGC, GCForeground, &gcval);
- ValidateGC(pDraw, pGC);
- }
- }
- }
- free(points);
- if (dospans)
- {
- free(widths);
- }
-}
+/************************************************************ + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Author: Bob Scheifler, MIT X Consortium + +********************************************************/ + +/* Derived from: + * "Algorithm for drawing ellipses or hyperbolae with a digital plotter" + * by M. L. V. Pitteway + * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289 + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <math.h> +#include <X11/X.h> +#include <X11/Xprotostr.h> +#include "regionstr.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "mi.h" +#include "mizerarc.h" + +#define FULLCIRCLE (360 * 64) +#define OCTANT (45 * 64) +#define QUADRANT (90 * 64) +#define HALFCIRCLE (180 * 64) +#define QUADRANT3 (270 * 64) + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define Dsin(d) ((d) == 0 ? 0.0 : ((d) == QUADRANT ? 1.0 : \ + ((d) == HALFCIRCLE ? 0.0 : \ + ((d) == QUADRANT3 ? -1.0 : sin((double)d*(M_PI/11520.0)))))) + +#define Dcos(d) ((d) == 0 ? 1.0 : ((d) == QUADRANT ? 0.0 : \ + ((d) == HALFCIRCLE ? -1.0 : \ + ((d) == QUADRANT3 ? 0.0 : cos((double)d*(M_PI/11520.0)))))) + +#define EPSILON45 64 + +typedef struct { + int skipStart; + int haveStart; + DDXPointRec startPt; + int haveLast; + int skipLast; + DDXPointRec endPt; + int dashIndex; + int dashOffset; + int dashIndexInit; + int dashOffsetInit; +} DashInfo; + +static miZeroArcPtRec oob = { 65536, 65536, 0 }; + +/* + * (x - l)^2 / (W/2)^2 + (y + H/2)^2 / (H/2)^2 = 1 + * + * where l is either 0 or .5 + * + * alpha = 4(W^2) + * beta = 4(H^2) + * gamma = 0 + * u = 2(W^2)H + * v = 4(H^2)l + * k = -4(H^2)(l^2) + * + */ + +Bool +miZeroArcSetup(xArc * arc, miZeroArcRec * info, Bool ok360) +{ + int l; + int angle1, angle2; + int startseg, endseg; + int startAngle, endAngle; + int i, overlap; + miZeroArcPtRec start, end; + + l = arc->width & 1; + if (arc->width == arc->height) { + info->alpha = 4; + info->beta = 4; + info->k1 = -8; + info->k3 = -16; + info->b = 12; + info->a = (arc->width << 2) - 12; + info->d = 17 - (arc->width << 1); + if (l) { + info->b -= 4; + info->a += 4; + info->d -= 7; + } + } + else if (!arc->width || !arc->height) { + info->alpha = 0; + info->beta = 0; + info->k1 = 0; + info->k3 = 0; + info->a = -(int) arc->height; + info->b = 0; + info->d = -1; + } + else { + /* initial conditions */ + info->alpha = (arc->width * arc->width) << 2; + info->beta = (arc->height * arc->height) << 2; + info->k1 = info->beta << 1; + info->k3 = info->k1 + (info->alpha << 1); + info->b = l ? 0 : -info->beta; + info->a = info->alpha * arc->height; + info->d = info->b - (info->a >> 1) - (info->alpha >> 2); + if (l) + info->d -= info->beta >> 2; + info->a -= info->b; + /* take first step, d < 0 always */ + info->b -= info->k1; + info->a += info->k1; + info->d += info->b; + /* octant change, b < 0 always */ + info->k1 = -info->k1; + info->k3 = -info->k3; + info->b = -info->b; + info->d = info->b - info->a - info->d; + info->a = info->a - (info->b << 1); + } + info->dx = 1; + info->dy = 0; + info->w = (arc->width + 1) >> 1; + info->h = arc->height >> 1; + info->xorg = arc->x + (arc->width >> 1); + info->yorg = arc->y; + info->xorgo = info->xorg + l; + info->yorgo = info->yorg + arc->height; + if (!arc->width) { + if (!arc->height) { + info->x = 0; + info->y = 0; + info->initialMask = 0; + info->startAngle = 0; + info->endAngle = 0; + info->start = oob; + info->end = oob; + return FALSE; + } + info->x = 0; + info->y = 1; + } + else { + info->x = 1; + info->y = 0; + } + angle1 = arc->angle1; + angle2 = arc->angle2; + if ((angle1 == 0) && (angle2 >= FULLCIRCLE)) { + startAngle = 0; + endAngle = 0; + } + else { + if (angle2 > FULLCIRCLE) + angle2 = FULLCIRCLE; + else if (angle2 < -FULLCIRCLE) + angle2 = -FULLCIRCLE; + if (angle2 < 0) { + startAngle = angle1 + angle2; + endAngle = angle1; + } + else { + startAngle = angle1; + endAngle = angle1 + angle2; + } + if (startAngle < 0) + startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE; + if (startAngle >= FULLCIRCLE) + startAngle = startAngle % FULLCIRCLE; + if (endAngle < 0) + endAngle = FULLCIRCLE - (-endAngle) % FULLCIRCLE; + if (endAngle >= FULLCIRCLE) + endAngle = endAngle % FULLCIRCLE; + } + info->startAngle = startAngle; + info->endAngle = endAngle; + if (ok360 && (startAngle == endAngle) && arc->angle2 && + arc->width && arc->height) { + info->initialMask = 0xf; + info->start = oob; + info->end = oob; + return TRUE; + } + startseg = startAngle / OCTANT; + if (!arc->height || (((startseg + 1) & 2) && arc->width)) { + start.x = Dcos(startAngle) * ((arc->width + 1) / 2.0); + if (start.x < 0) + start.x = -start.x; + start.y = -1; + } + else { + start.y = Dsin(startAngle) * (arc->height / 2.0); + if (start.y < 0) + start.y = -start.y; + start.y = info->h - start.y; + start.x = 65536; + } + endseg = endAngle / OCTANT; + if (!arc->height || (((endseg + 1) & 2) && arc->width)) { + end.x = Dcos(endAngle) * ((arc->width + 1) / 2.0); + if (end.x < 0) + end.x = -end.x; + end.y = -1; + } + else { + end.y = Dsin(endAngle) * (arc->height / 2.0); + if (end.y < 0) + end.y = -end.y; + end.y = info->h - end.y; + end.x = 65536; + } + info->firstx = start.x; + info->firsty = start.y; + info->initialMask = 0; + overlap = arc->angle2 && (endAngle <= startAngle); + for (i = 0; i < 4; i++) { + if (overlap ? + ((i * QUADRANT <= endAngle) || ((i + 1) * QUADRANT > startAngle)) : + ((i * QUADRANT <= endAngle) && ((i + 1) * QUADRANT > startAngle))) + info->initialMask |= (1 << i); + } + start.mask = info->initialMask; + end.mask = info->initialMask; + startseg >>= 1; + endseg >>= 1; + overlap = overlap && (endseg == startseg); + if (start.x != end.x || start.y != end.y || !overlap) { + if (startseg & 1) { + if (!overlap) + info->initialMask &= ~(1 << startseg); + if (start.x > end.x || start.y > end.y) + end.mask &= ~(1 << startseg); + } + else { + start.mask &= ~(1 << startseg); + if (((start.x < end.x || start.y < end.y) || + (start.x == end.x && start.y == end.y && (endseg & 1))) && + !overlap) + end.mask &= ~(1 << startseg); + } + if (endseg & 1) { + end.mask &= ~(1 << endseg); + if (((start.x > end.x || start.y > end.y) || + (start.x == end.x && start.y == end.y && !(startseg & 1))) && + !overlap) + start.mask &= ~(1 << endseg); + } + else { + if (!overlap) + info->initialMask &= ~(1 << endseg); + if (start.x < end.x || start.y < end.y) + start.mask &= ~(1 << endseg); + } + } + /* take care of case when start and stop are both near 45 */ + /* handle here rather than adding extra code to pixelization loops */ + if (startAngle && + ((start.y < 0 && end.y >= 0) || (start.y >= 0 && end.y < 0))) { + i = (startAngle + OCTANT) % OCTANT; + if (i < EPSILON45 || i > OCTANT - EPSILON45) { + i = (endAngle + OCTANT) % OCTANT; + if (i < EPSILON45 || i > OCTANT - EPSILON45) { + if (start.y < 0) { + i = Dsin(startAngle) * (arc->height / 2.0); + if (i < 0) + i = -i; + if (info->h - i == end.y) + start.mask = end.mask; + } + else { + i = Dsin(endAngle) * (arc->height / 2.0); + if (i < 0) + i = -i; + if (info->h - i == start.y) + end.mask = start.mask; + } + } + } + } + if (startseg & 1) { + info->start = start; + info->end = oob; + } + else { + info->end = start; + info->start = oob; + } + if (endseg & 1) { + info->altend = end; + if (info->altend.x < info->end.x || info->altend.y < info->end.y) { + miZeroArcPtRec tmp; + + tmp = info->altend; + info->altend = info->end; + info->end = tmp; + } + info->altstart = oob; + } + else { + info->altstart = end; + if (info->altstart.x < info->start.x || + info->altstart.y < info->start.y) { + miZeroArcPtRec tmp; + + tmp = info->altstart; + info->altstart = info->start; + info->start = tmp; + } + info->altend = oob; + } + if (!info->start.x || !info->start.y) { + info->initialMask = info->start.mask; + info->start = info->altstart; + } + if (!arc->width && (arc->height == 1)) { + /* kludge! */ + info->initialMask |= info->end.mask; + info->initialMask |= info->initialMask << 1; + info->end.x = 0; + info->end.mask = 0; + } + return FALSE; +} + +#define Pixelate(xval,yval) \ + { \ + pts->x = xval; \ + pts->y = yval; \ + pts++; \ + } + +#define DoPix(idx,xval,yval) if (mask & (1 << idx)) Pixelate(xval, yval); + +static DDXPointPtr +miZeroArcPts(xArc * arc, DDXPointPtr pts) +{ + miZeroArcRec info; + int x, y, a, b, d, mask; + int k1, k3, dx, dy; + Bool do360; + + do360 = miZeroArcSetup(arc, &info, TRUE); + MIARCSETUP(); + mask = info.initialMask; + if (!(arc->width & 1)) { + DoPix(1, info.xorgo, info.yorg); + DoPix(3, info.xorgo, info.yorgo); + } + if (!info.end.x || !info.end.y) { + mask = info.end.mask; + info.end = info.altend; + } + if (do360 && (arc->width == arc->height) && !(arc->width & 1)) { + int yorgh = info.yorg + info.h; + int xorghp = info.xorg + info.h; + int xorghn = info.xorg - info.h; + + while (1) { + Pixelate(info.xorg + x, info.yorg + y); + Pixelate(info.xorg - x, info.yorg + y); + Pixelate(info.xorg - x, info.yorgo - y); + Pixelate(info.xorg + x, info.yorgo - y); + if (a < 0) + break; + Pixelate(xorghp - y, yorgh - x); + Pixelate(xorghn + y, yorgh - x); + Pixelate(xorghn + y, yorgh + x); + Pixelate(xorghp - y, yorgh + x); + MIARCCIRCLESTEP(; + ); + } + if (x > 1 && pts[-1].x == pts[-5].x && pts[-1].y == pts[-5].y) + pts -= 4; + x = info.w; + y = info.h; + } + else if (do360) { + while (y < info.h || x < info.w) { + MIARCOCTANTSHIFT(; + ); + Pixelate(info.xorg + x, info.yorg + y); + Pixelate(info.xorgo - x, info.yorg + y); + Pixelate(info.xorgo - x, info.yorgo - y); + Pixelate(info.xorg + x, info.yorgo - y); + MIARCSTEP(; + ,; + ); + } + } + else { + while (y < info.h || x < info.w) { + MIARCOCTANTSHIFT(; + ); + if ((x == info.start.x) || (y == info.start.y)) { + mask = info.start.mask; + info.start = info.altstart; + } + DoPix(0, info.xorg + x, info.yorg + y); + DoPix(1, info.xorgo - x, info.yorg + y); + DoPix(2, info.xorgo - x, info.yorgo - y); + DoPix(3, info.xorg + x, info.yorgo - y); + if ((x == info.end.x) || (y == info.end.y)) { + mask = info.end.mask; + info.end = info.altend; + } + MIARCSTEP(; + ,; + ); + } + } + if ((x == info.start.x) || (y == info.start.y)) + mask = info.start.mask; + DoPix(0, info.xorg + x, info.yorg + y); + DoPix(2, info.xorgo - x, info.yorgo - y); + if (arc->height & 1) { + DoPix(1, info.xorgo - x, info.yorg + y); + DoPix(3, info.xorg + x, info.yorgo - y); + } + return pts; +} + +#undef DoPix +#define DoPix(idx,xval,yval) \ + if (mask & (1 << idx)) \ + { \ + arcPts[idx]->x = xval; \ + arcPts[idx]->y = yval; \ + arcPts[idx]++; \ + } + +static void +miZeroArcDashPts(GCPtr pGC, + xArc * arc, + DashInfo * dinfo, + DDXPointPtr points, + int maxPts, DDXPointPtr * evenPts, DDXPointPtr * oddPts) +{ + miZeroArcRec info; + int x, y, a, b, d, mask; + int k1, k3, dx, dy; + int dashRemaining; + DDXPointPtr arcPts[4]; + DDXPointPtr startPts[5], endPts[5]; + int deltas[5]; + DDXPointPtr startPt, pt, lastPt, pts; + int i, j, delta, ptsdelta, seg, startseg; + + for (i = 0; i < 4; i++) + arcPts[i] = points + (i * maxPts); + (void) miZeroArcSetup(arc, &info, FALSE); + MIARCSETUP(); + mask = info.initialMask; + startseg = info.startAngle / QUADRANT; + startPt = arcPts[startseg]; + if (!(arc->width & 1)) { + DoPix(1, info.xorgo, info.yorg); + DoPix(3, info.xorgo, info.yorgo); + } + if (!info.end.x || !info.end.y) { + mask = info.end.mask; + info.end = info.altend; + } + while (y < info.h || x < info.w) { + MIARCOCTANTSHIFT(; + ); + if ((x == info.firstx) || (y == info.firsty)) + startPt = arcPts[startseg]; + if ((x == info.start.x) || (y == info.start.y)) { + mask = info.start.mask; + info.start = info.altstart; + } + DoPix(0, info.xorg + x, info.yorg + y); + DoPix(1, info.xorgo - x, info.yorg + y); + DoPix(2, info.xorgo - x, info.yorgo - y); + DoPix(3, info.xorg + x, info.yorgo - y); + if ((x == info.end.x) || (y == info.end.y)) { + mask = info.end.mask; + info.end = info.altend; + } + MIARCSTEP(; + ,; + ); + } + if ((x == info.firstx) || (y == info.firsty)) + startPt = arcPts[startseg]; + if ((x == info.start.x) || (y == info.start.y)) + mask = info.start.mask; + DoPix(0, info.xorg + x, info.yorg + y); + DoPix(2, info.xorgo - x, info.yorgo - y); + if (arc->height & 1) { + DoPix(1, info.xorgo - x, info.yorg + y); + DoPix(3, info.xorg + x, info.yorgo - y); + } + for (i = 0; i < 4; i++) { + seg = (startseg + i) & 3; + pt = points + (seg * maxPts); + if (seg & 1) { + startPts[i] = pt; + endPts[i] = arcPts[seg]; + deltas[i] = 1; + } + else { + startPts[i] = arcPts[seg] - 1; + endPts[i] = pt - 1; + deltas[i] = -1; + } + } + startPts[4] = startPts[0]; + endPts[4] = startPt; + startPts[0] = startPt; + if (startseg & 1) { + if (startPts[4] != endPts[4]) + endPts[4]--; + deltas[4] = 1; + } + else { + if (startPts[0] > startPts[4]) + startPts[0]--; + if (startPts[4] < endPts[4]) + endPts[4]--; + deltas[4] = -1; + } + if (arc->angle2 < 0) { + DDXPointPtr tmps, tmpe; + int tmpd; + + tmpd = deltas[0]; + tmps = startPts[0] - tmpd; + tmpe = endPts[0] - tmpd; + startPts[0] = endPts[4] - deltas[4]; + endPts[0] = startPts[4] - deltas[4]; + deltas[0] = -deltas[4]; + startPts[4] = tmpe; + endPts[4] = tmps; + deltas[4] = -tmpd; + tmpd = deltas[1]; + tmps = startPts[1] - tmpd; + tmpe = endPts[1] - tmpd; + startPts[1] = endPts[3] - deltas[3]; + endPts[1] = startPts[3] - deltas[3]; + deltas[1] = -deltas[3]; + startPts[3] = tmpe; + endPts[3] = tmps; + deltas[3] = -tmpd; + tmps = startPts[2] - deltas[2]; + startPts[2] = endPts[2] - deltas[2]; + endPts[2] = tmps; + deltas[2] = -deltas[2]; + } + for (i = 0; i < 5 && startPts[i] == endPts[i]; i++); + if (i == 5) + return; + pt = startPts[i]; + for (j = 4; startPts[j] == endPts[j]; j--); + lastPt = endPts[j] - deltas[j]; + if (dinfo->haveLast && + (pt->x == dinfo->endPt.x) && (pt->y == dinfo->endPt.y)) { + startPts[i] += deltas[i]; + } + else { + dinfo->dashIndex = dinfo->dashIndexInit; + dinfo->dashOffset = dinfo->dashOffsetInit; + } + if (!dinfo->skipStart && (info.startAngle != info.endAngle)) { + dinfo->startPt = *pt; + dinfo->haveStart = TRUE; + } + else if (!dinfo->skipLast && dinfo->haveStart && + (lastPt->x == dinfo->startPt.x) && + (lastPt->y == dinfo->startPt.y) && (lastPt != startPts[i])) + endPts[j] = lastPt; + if (info.startAngle != info.endAngle) { + dinfo->haveLast = TRUE; + dinfo->endPt = *lastPt; + } + dashRemaining = pGC->dash[dinfo->dashIndex] - dinfo->dashOffset; + for (i = 0; i < 5; i++) { + pt = startPts[i]; + lastPt = endPts[i]; + delta = deltas[i]; + while (pt != lastPt) { + if (dinfo->dashIndex & 1) { + pts = *oddPts; + ptsdelta = -1; + } + else { + pts = *evenPts; + ptsdelta = 1; + } + while ((pt != lastPt) && --dashRemaining >= 0) { + *pts = *pt; + pts += ptsdelta; + pt += delta; + } + if (dinfo->dashIndex & 1) + *oddPts = pts; + else + *evenPts = pts; + if (dashRemaining <= 0) { + if (++(dinfo->dashIndex) == pGC->numInDashList) + dinfo->dashIndex = 0; + dashRemaining = pGC->dash[dinfo->dashIndex]; + } + } + } + dinfo->dashOffset = pGC->dash[dinfo->dashIndex] - dashRemaining; +} + +void +miZeroPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs) +{ + int maxPts = 0; + int n, maxw = 0; + xArc *arc; + int i; + DDXPointPtr points, pts, oddPts = NULL; + DDXPointPtr pt; + int numPts; + Bool dospans; + int *widths = NULL; + XID fgPixel = pGC->fgPixel; + DashInfo dinfo; + + for (arc = parcs, i = narcs; --i >= 0; arc++) { + if (!miCanZeroArc(arc)) + miPolyArc(pDraw, pGC, 1, arc); + else { + if (arc->width > arc->height) + n = arc->width + (arc->height >> 1); + else + n = arc->height + (arc->width >> 1); + if (n > maxPts) + maxPts = n; + } + } + if (!maxPts) + return; + numPts = maxPts << 2; + dospans = (pGC->fillStyle != FillSolid); + if (dospans) { + widths = malloc(sizeof(int) * numPts); + if (!widths) + return; + maxw = 0; + } + if (pGC->lineStyle != LineSolid) { + numPts <<= 1; + dinfo.haveStart = FALSE; + dinfo.skipStart = FALSE; + dinfo.haveLast = FALSE; + dinfo.dashIndexInit = 0; + dinfo.dashOffsetInit = 0; + miStepDash((int) pGC->dashOffset, &dinfo.dashIndexInit, + (unsigned char *) pGC->dash, (int) pGC->numInDashList, + &dinfo.dashOffsetInit); + } + points = malloc(sizeof(DDXPointRec) * numPts); + if (!points) { + if (dospans) { + free(widths); + } + return; + } + for (arc = parcs, i = narcs; --i >= 0; arc++) { + if (miCanZeroArc(arc)) { + if (pGC->lineStyle == LineSolid) + pts = miZeroArcPts(arc, points); + else { + pts = points; + oddPts = &points[(numPts >> 1) - 1]; + dinfo.skipLast = i; + miZeroArcDashPts(pGC, arc, &dinfo, + oddPts + 1, maxPts, &pts, &oddPts); + dinfo.skipStart = TRUE; + } + n = pts - points; + if (!dospans) + (*pGC->ops->PolyPoint) (pDraw, pGC, CoordModeOrigin, n, points); + else { + if (n > maxw) { + while (maxw < n) + widths[maxw++] = 1; + } + if (pGC->miTranslate) { + for (pt = points; pt != pts; pt++) { + pt->x += pDraw->x; + pt->y += pDraw->y; + } + } + (*pGC->ops->FillSpans) (pDraw, pGC, n, points, widths, FALSE); + } + if (pGC->lineStyle != LineDoubleDash) + continue; + if ((pGC->fillStyle == FillSolid) || + (pGC->fillStyle == FillStippled)) { + ChangeGCVal gcval; + + gcval.val = pGC->bgPixel; + ChangeGC(NullClient, pGC, GCForeground, &gcval); + ValidateGC(pDraw, pGC); + } + pts = &points[numPts >> 1]; + oddPts++; + n = pts - oddPts; + if (!dospans) + (*pGC->ops->PolyPoint) (pDraw, pGC, CoordModeOrigin, n, oddPts); + else { + if (n > maxw) { + while (maxw < n) + widths[maxw++] = 1; + } + if (pGC->miTranslate) { + for (pt = oddPts; pt != pts; pt++) { + pt->x += pDraw->x; + pt->y += pDraw->y; + } + } + (*pGC->ops->FillSpans) (pDraw, pGC, n, oddPts, widths, FALSE); + } + if ((pGC->fillStyle == FillSolid) || + (pGC->fillStyle == FillStippled)) { + ChangeGCVal gcval; + + gcval.val = fgPixel; + ChangeGC(NullClient, pGC, GCForeground, &gcval); + ValidateGC(pDraw, pGC); + } + } + } + free(points); + if (dospans) { + free(widths); + } +} diff --git a/xorg-server/mi/mizerarc.h b/xorg-server/mi/mizerarc.h index 1612a525b..165e281ed 100644 --- a/xorg-server/mi/mizerarc.h +++ b/xorg-server/mi/mizerarc.h @@ -24,7 +24,6 @@ in this Software without prior written authorization from The Open Group. ********************************************************/ - typedef struct { int x; int y; @@ -119,8 +118,7 @@ typedef struct { /* mizerarc.c */ -extern _X_EXPORT Bool miZeroArcSetup( - xArc * /*arc*/, - miZeroArcRec * /*info*/, - Bool /*ok360*/ -); +extern _X_EXPORT Bool miZeroArcSetup(xArc * /*arc */ , + miZeroArcRec * /*info */ , + Bool /*ok360 */ + ); diff --git a/xorg-server/mi/mizerclip.c b/xorg-server/mi/mizerclip.c index fb1e25fe4..d05bf6788 100644 --- a/xorg-server/mi/mizerclip.c +++ b/xorg-server/mi/mizerclip.c @@ -22,7 +22,6 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved @@ -362,18 +361,18 @@ the numerator is therefore (2^32 - 1), which does not overflow an unsigned /* Bit codes for the terms of the 16 clipping equations defined below. */ #define T_2NDX (1 << 0) -#define T_2MDY (0) /* implicit term */ +#define T_2MDY (0) /* implicit term */ #define T_DXNOTY (1 << 1) -#define T_DYNOTX (0) /* implicit term */ +#define T_DYNOTX (0) /* implicit term */ #define T_SUBDXORY (1 << 2) -#define T_ADDDX (T_DXNOTY) /* composite term */ -#define T_SUBDX (T_DXNOTY | T_SUBDXORY) /* composite term */ -#define T_ADDDY (T_DYNOTX) /* composite term */ -#define T_SUBDY (T_DYNOTX | T_SUBDXORY) /* composite term */ +#define T_ADDDX (T_DXNOTY) /* composite term */ +#define T_SUBDX (T_DXNOTY | T_SUBDXORY) /* composite term */ +#define T_ADDDY (T_DYNOTX) /* composite term */ +#define T_SUBDY (T_DYNOTX | T_SUBDXORY) /* composite term */ #define T_BIASSUBONE (1 << 3) -#define T_SUBBIAS (0) /* implicit term */ +#define T_SUBBIAS (0) /* implicit term */ #define T_DIV2DX (1 << 4) -#define T_DIV2DY (0) /* implicit term */ +#define T_DIV2DY (0) /* implicit term */ #define T_ADDONE (1 << 5) /* Bit masks defining the 16 equations used in miZeroClipLine. */ @@ -409,8 +408,7 @@ miZeroClipLine(int xmin, int ymin, int xmax, int ymax, int *new_x1, int *new_y1, int *new_x2, int *new_y2, unsigned int adx, unsigned int ady, int *pt1_clipped, int *pt2_clipped, - int octant, unsigned int bias, - int oc1, int oc2) + int octant, unsigned int bias, int oc1, int oc2) { int swapped = 0; int clipDone = 0; @@ -433,188 +431,174 @@ miZeroClipLine(int xmin, int ymin, int xmax, int ymax, xmajor = IsXMajorOctant(octant); bias = ((bias >> octant) & 1); - while (1) - { - if ((oc1 & oc2) != 0) /* trivial reject */ - { - clipDone = -1; - clip1 = oc1; - clip2 = oc2; - break; - } - else if ((oc1 | oc2) == 0) /* trivial accept */ - { - clipDone = 1; - if (swapped) - { - SWAPINT_PAIR(x1, y1, x2, y2); - SWAPINT(clip1, clip2); - } - break; + while (1) { + if ((oc1 & oc2) != 0) { /* trivial reject */ + clipDone = -1; + clip1 = oc1; + clip2 = oc2; + break; + } + else if ((oc1 | oc2) == 0) { /* trivial accept */ + clipDone = 1; + if (swapped) { + SWAPINT_PAIR(x1, y1, x2, y2); + SWAPINT(clip1, clip2); + } + break; } - else /* have to clip */ - { - /* only clip one point at a time */ - if (oc1 == 0) - { - SWAPINT_PAIR(x1, y1, x2, y2); - SWAPINT_PAIR(x1_orig, y1_orig, x2_orig, y2_orig); - SWAPINT(oc1, oc2); - SWAPINT(clip1, clip2); - swapped = !swapped; - } - - clip1 |= oc1; - if (oc1 & OUT_LEFT) - { - negslope = IsYDecreasingOctant(octant); - utmp = xmin - x1_orig; - if (utmp <= 32767) /* clip based on near endpt */ - { - if (xmajor) - eqn = (swapped) ? EQN2 : EQN1; - else - eqn = (swapped) ? EQN4 : EQN3; - anchorval = y1_orig; - } - else /* clip based on far endpt */ - { - utmp = x2_orig - xmin; - if (xmajor) - eqn = (swapped) ? EQN1B : EQN2B; - else - eqn = (swapped) ? EQN3B : EQN4B; - anchorval = y2_orig; - negslope = !negslope; - } - x1 = xmin; - } - else if (oc1 & OUT_ABOVE) - { - negslope = IsXDecreasingOctant(octant); - utmp = ymin - y1_orig; - if (utmp <= 32767) /* clip based on near endpt */ - { - if (xmajor) - eqn = (swapped) ? EQN6 : EQN5; - else - eqn = (swapped) ? EQN8 : EQN7; - anchorval = x1_orig; - } - else /* clip based on far endpt */ - { - utmp = y2_orig - ymin; - if (xmajor) - eqn = (swapped) ? EQN5B : EQN6B; - else - eqn = (swapped) ? EQN7B : EQN8B; - anchorval = x2_orig; - negslope = !negslope; - } - y1 = ymin; - } - else if (oc1 & OUT_RIGHT) - { - negslope = IsYDecreasingOctant(octant); - utmp = x1_orig - xmax; - if (utmp <= 32767) /* clip based on near endpt */ - { - if (xmajor) - eqn = (swapped) ? EQN2 : EQN1; - else - eqn = (swapped) ? EQN4 : EQN3; - anchorval = y1_orig; - } - else /* clip based on far endpt */ - { - /* - * Technically since the equations can handle - * utmp == 32768, this overflow code isn't - * needed since X11 protocol can't generate - * a line which goes more than 32768 pixels - * to the right of a clip rectangle. - */ - utmp = xmax - x2_orig; - if (xmajor) - eqn = (swapped) ? EQN1B : EQN2B; - else - eqn = (swapped) ? EQN3B : EQN4B; - anchorval = y2_orig; - negslope = !negslope; - } - x1 = xmax; - } - else if (oc1 & OUT_BELOW) - { - negslope = IsXDecreasingOctant(octant); - utmp = y1_orig - ymax; - if (utmp <= 32767) /* clip based on near endpt */ - { - if (xmajor) - eqn = (swapped) ? EQN6 : EQN5; - else - eqn = (swapped) ? EQN8 : EQN7; - anchorval = x1_orig; - } - else /* clip based on far endpt */ - { - /* - * Technically since the equations can handle - * utmp == 32768, this overflow code isn't - * needed since X11 protocol can't generate - * a line which goes more than 32768 pixels - * below the bottom of a clip rectangle. - */ - utmp = ymax - y2_orig; - if (xmajor) - eqn = (swapped) ? EQN5B : EQN6B; - else - eqn = (swapped) ? EQN7B : EQN8B; - anchorval = x2_orig; - negslope = !negslope; - } - y1 = ymax; - } - - if (swapped) - negslope = !negslope; - - utmp <<= 1; /* utmp = 2N or 2M */ - if (eqn & T_2NDX) - utmp = (utmp * adx); - else /* (eqn & T_2MDY) */ - utmp = (utmp * ady); - if (eqn & T_DXNOTY) - if (eqn & T_SUBDXORY) - utmp -= adx; - else - utmp += adx; - else /* (eqn & T_DYNOTX) */ - if (eqn & T_SUBDXORY) - utmp -= ady; - else - utmp += ady; - if (eqn & T_BIASSUBONE) - utmp += bias - 1; - else /* (eqn & T_SUBBIAS) */ - utmp -= bias; - if (eqn & T_DIV2DX) - utmp /= (adx << 1); - else /* (eqn & T_DIV2DY) */ - utmp /= (ady << 1); - if (eqn & T_ADDONE) - utmp++; - - if (negslope) - utmp = -utmp; - - if (eqn & T_2NDX) /* We are calculating X steps */ - x1 = anchorval + utmp; - else /* else, Y steps */ - y1 = anchorval + utmp; - - oc1 = 0; - MIOUTCODES(oc1, x1, y1, xmin, ymin, xmax, ymax); + else { /* have to clip */ + + /* only clip one point at a time */ + if (oc1 == 0) { + SWAPINT_PAIR(x1, y1, x2, y2); + SWAPINT_PAIR(x1_orig, y1_orig, x2_orig, y2_orig); + SWAPINT(oc1, oc2); + SWAPINT(clip1, clip2); + swapped = !swapped; + } + + clip1 |= oc1; + if (oc1 & OUT_LEFT) { + negslope = IsYDecreasingOctant(octant); + utmp = xmin - x1_orig; + if (utmp <= 32767) { /* clip based on near endpt */ + if (xmajor) + eqn = (swapped) ? EQN2 : EQN1; + else + eqn = (swapped) ? EQN4 : EQN3; + anchorval = y1_orig; + } + else { /* clip based on far endpt */ + + utmp = x2_orig - xmin; + if (xmajor) + eqn = (swapped) ? EQN1B : EQN2B; + else + eqn = (swapped) ? EQN3B : EQN4B; + anchorval = y2_orig; + negslope = !negslope; + } + x1 = xmin; + } + else if (oc1 & OUT_ABOVE) { + negslope = IsXDecreasingOctant(octant); + utmp = ymin - y1_orig; + if (utmp <= 32767) { /* clip based on near endpt */ + if (xmajor) + eqn = (swapped) ? EQN6 : EQN5; + else + eqn = (swapped) ? EQN8 : EQN7; + anchorval = x1_orig; + } + else { /* clip based on far endpt */ + + utmp = y2_orig - ymin; + if (xmajor) + eqn = (swapped) ? EQN5B : EQN6B; + else + eqn = (swapped) ? EQN7B : EQN8B; + anchorval = x2_orig; + negslope = !negslope; + } + y1 = ymin; + } + else if (oc1 & OUT_RIGHT) { + negslope = IsYDecreasingOctant(octant); + utmp = x1_orig - xmax; + if (utmp <= 32767) { /* clip based on near endpt */ + if (xmajor) + eqn = (swapped) ? EQN2 : EQN1; + else + eqn = (swapped) ? EQN4 : EQN3; + anchorval = y1_orig; + } + else { /* clip based on far endpt */ + + /* + * Technically since the equations can handle + * utmp == 32768, this overflow code isn't + * needed since X11 protocol can't generate + * a line which goes more than 32768 pixels + * to the right of a clip rectangle. + */ + utmp = xmax - x2_orig; + if (xmajor) + eqn = (swapped) ? EQN1B : EQN2B; + else + eqn = (swapped) ? EQN3B : EQN4B; + anchorval = y2_orig; + negslope = !negslope; + } + x1 = xmax; + } + else if (oc1 & OUT_BELOW) { + negslope = IsXDecreasingOctant(octant); + utmp = y1_orig - ymax; + if (utmp <= 32767) { /* clip based on near endpt */ + if (xmajor) + eqn = (swapped) ? EQN6 : EQN5; + else + eqn = (swapped) ? EQN8 : EQN7; + anchorval = x1_orig; + } + else { /* clip based on far endpt */ + + /* + * Technically since the equations can handle + * utmp == 32768, this overflow code isn't + * needed since X11 protocol can't generate + * a line which goes more than 32768 pixels + * below the bottom of a clip rectangle. + */ + utmp = ymax - y2_orig; + if (xmajor) + eqn = (swapped) ? EQN5B : EQN6B; + else + eqn = (swapped) ? EQN7B : EQN8B; + anchorval = x2_orig; + negslope = !negslope; + } + y1 = ymax; + } + + if (swapped) + negslope = !negslope; + + utmp <<= 1; /* utmp = 2N or 2M */ + if (eqn & T_2NDX) + utmp = (utmp * adx); + else /* (eqn & T_2MDY) */ + utmp = (utmp * ady); + if (eqn & T_DXNOTY) + if (eqn & T_SUBDXORY) + utmp -= adx; + else + utmp += adx; + else /* (eqn & T_DYNOTX) */ if (eqn & T_SUBDXORY) + utmp -= ady; + else + utmp += ady; + if (eqn & T_BIASSUBONE) + utmp += bias - 1; + else /* (eqn & T_SUBBIAS) */ + utmp -= bias; + if (eqn & T_DIV2DX) + utmp /= (adx << 1); + else /* (eqn & T_DIV2DY) */ + utmp /= (ady << 1); + if (eqn & T_ADDONE) + utmp++; + + if (negslope) + utmp = -utmp; + + if (eqn & T_2NDX) /* We are calculating X steps */ + x1 = anchorval + utmp; + else /* else, Y steps */ + y1 = anchorval + utmp; + + oc1 = 0; + MIOUTCODES(oc1, x1, y1, xmin, ymin, xmax, ymax); } } @@ -622,7 +606,7 @@ miZeroClipLine(int xmin, int ymin, int xmax, int ymax, *new_y1 = y1; *new_x2 = x2; *new_y2 = y2; - + *pt1_clipped = clip1; *pt2_clipped = clip2; diff --git a/xorg-server/mi/mizerline.c b/xorg-server/mi/mizerline.c index 7077b5198..90798dbdf 100644 --- a/xorg-server/mi/mizerline.c +++ b/xorg-server/mi/mizerline.c @@ -22,7 +22,6 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. - Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved @@ -98,15 +97,12 @@ SOFTWARE. } void -miZeroLine( - DrawablePtr pDraw, - GCPtr pGC, - int mode, /* Origin or Previous */ - int npt, /* number of points */ - DDXPointPtr pptInit) +miZeroLine(DrawablePtr pDraw, GCPtr pGC, int mode, /* Origin or Previous */ + int npt, /* number of points */ + DDXPointPtr pptInit) { int Nspans, current_y = 0; - DDXPointPtr ppt; + DDXPointPtr ppt; DDXPointPtr pspanInit, spans; int *pwidthInit, *widths, list_len; int xleft, ytop, xright, ybottom; @@ -122,21 +118,20 @@ miZeroLine( int adx, ady; int octant; unsigned int bias = miGetZeroLineBias(pDraw->pScreen); - int e, e1, e2, e3; /* Bresenham error terms */ - int length; /* length of lines == # of pixels on major axis */ + int e, e1, e2, e3; /* Bresenham error terms */ + int length; /* length of lines == # of pixels on major axis */ - xleft = pDraw->x; - ytop = pDraw->y; - xright = pDraw->x + pDraw->width - 1; + xleft = pDraw->x; + ytop = pDraw->y; + xright = pDraw->x + pDraw->width - 1; ybottom = pDraw->y + pDraw->height - 1; - if (!pGC->miTranslate) - { - /* do everything in drawable-relative coordinates */ - xleft = 0; - ytop = 0; - xright -= pDraw->x; - ybottom -= pDraw->y; + if (!pGC->miTranslate) { + /* do everything in drawable-relative coordinates */ + xleft = 0; + ytop = 0; + xright -= pDraw->x; + ybottom -= pDraw->y; } /* it doesn't matter whether we're in drawable or screen coordinates, @@ -144,9 +139,9 @@ miZeroLine( * range of a DDXPointRec component. */ if (xright > MAX_COORDINATE) - xright = MAX_COORDINATE; + xright = MAX_COORDINATE; if (ybottom > MAX_COORDINATE) - ybottom = MAX_COORDINATE; + ybottom = MAX_COORDINATE; /* since we're clipping to the drawable's boundaries & coordinate * space boundaries, we're guaranteed that the larger of width/height @@ -158,24 +153,23 @@ miZeroLine( pspanInit = malloc(list_len * sizeof(DDXPointRec)); pwidthInit = malloc(list_len * sizeof(int)); if (!pspanInit || !pwidthInit) { - free(pspanInit); - free(pwidthInit); - return; + free(pspanInit); + free(pwidthInit); + return; } Nspans = 0; new_span = TRUE; - spans = pspanInit - 1; + spans = pspanInit - 1; widths = pwidthInit - 1; ppt = pptInit; xstart = ppt->x; ystart = ppt->y; - if (pGC->miTranslate) - { - xstart += pDraw->x; - ystart += pDraw->y; + if (pGC->miTranslate) { + xstart += pDraw->x; + ystart += pDraw->y; } - + /* x2, y2, oc2 copied to x1, y1, oc1 at top of loop to simplify * iteration logic */ @@ -184,166 +178,154 @@ miZeroLine( oc2 = 0; MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom); - while (--npt > 0) - { - if (Nspans > 0) - (*pGC->ops->FillSpans)(pDraw, pGC, Nspans, pspanInit, - pwidthInit, FALSE); - Nspans = 0; - new_span = TRUE; - spans = pspanInit - 1; - widths = pwidthInit - 1; - - x1 = x2; - y1 = y2; - oc1 = oc2; - ++ppt; - - x2 = ppt->x; - y2 = ppt->y; - if (pGC->miTranslate && (mode != CoordModePrevious)) - { - x2 += pDraw->x; - y2 += pDraw->y; - } - else if (mode == CoordModePrevious) - { - x2 += x1; - y2 += y1; - } - - oc2 = 0; - MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom); - - CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant); - - if (adx > ady) - { - e1 = ady << 1; - e2 = e1 - (adx << 1); - e = e1 - adx; - length = adx; /* don't draw endpoint in main loop */ - - FIXUP_ERROR(e, octant, bias); - - new_x1 = x1; - new_y1 = y1; - new_x2 = x2; - new_y2 = y2; - pt1_clipped = 0; - pt2_clipped = 0; - - if ((oc1 | oc2) != 0) - { - result = miZeroClipLine(xleft, ytop, xright, ybottom, - &new_x1, &new_y1, &new_x2, &new_y2, - adx, ady, - &pt1_clipped, &pt2_clipped, - octant, bias, oc1, oc2); - if (result == -1) - continue; - - length = abs(new_x2 - new_x1); - - /* if we've clipped the endpoint, always draw the full length - * of the segment, because then the capstyle doesn't matter - */ - if (pt2_clipped) - length++; - - if (pt1_clipped) - { - /* must calculate new error terms */ - clipdx = abs(new_x1 - x1); - clipdy = abs(new_y1 - y1); - e += (clipdy * e2) + ((clipdx - clipdy) * e1); - } - } - - /* draw the segment */ - - x = new_x1; - y = new_y1; - - e3 = e2 - e1; - e = e - e1; - - while (length--) - { - MI_OUTPUT_POINT(x, y); - e += e1; - if (e >= 0) - { - y += signdy; - e += e3; - } - x += signdx; - } - } - else /* Y major line */ - { - e1 = adx << 1; - e2 = e1 - (ady << 1); - e = e1 - ady; - length = ady; /* don't draw endpoint in main loop */ - - SetYMajorOctant(octant); - FIXUP_ERROR(e, octant, bias); - - new_x1 = x1; - new_y1 = y1; - new_x2 = x2; - new_y2 = y2; - pt1_clipped = 0; - pt2_clipped = 0; - - if ((oc1 | oc2) != 0) - { - result = miZeroClipLine(xleft, ytop, xright, ybottom, - &new_x1, &new_y1, &new_x2, &new_y2, - adx, ady, - &pt1_clipped, &pt2_clipped, - octant, bias, oc1, oc2); - if (result == -1) - continue; - - length = abs(new_y2 - new_y1); - - /* if we've clipped the endpoint, always draw the full length - * of the segment, because then the capstyle doesn't matter - */ - if (pt2_clipped) - length++; - - if (pt1_clipped) - { - /* must calculate new error terms */ - clipdx = abs(new_x1 - x1); - clipdy = abs(new_y1 - y1); - e += (clipdx * e2) + ((clipdy - clipdx) * e1); - } - } - - /* draw the segment */ - - x = new_x1; - y = new_y1; - - e3 = e2 - e1; - e = e - e1; - - while (length--) - { - MI_OUTPUT_POINT(x, y); - e += e1; - if (e >= 0) - { - x += signdx; - e += e3; - } - y += signdy; - } - } + while (--npt > 0) { + if (Nspans > 0) + (*pGC->ops->FillSpans) (pDraw, pGC, Nspans, pspanInit, + pwidthInit, FALSE); + Nspans = 0; + new_span = TRUE; + spans = pspanInit - 1; + widths = pwidthInit - 1; + + x1 = x2; + y1 = y2; + oc1 = oc2; + ++ppt; + + x2 = ppt->x; + y2 = ppt->y; + if (pGC->miTranslate && (mode != CoordModePrevious)) { + x2 += pDraw->x; + y2 += pDraw->y; + } + else if (mode == CoordModePrevious) { + x2 += x1; + y2 += y1; + } + + oc2 = 0; + MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom); + + CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant); + + if (adx > ady) { + e1 = ady << 1; + e2 = e1 - (adx << 1); + e = e1 - adx; + length = adx; /* don't draw endpoint in main loop */ + + FIXUP_ERROR(e, octant, bias); + + new_x1 = x1; + new_y1 = y1; + new_x2 = x2; + new_y2 = y2; + pt1_clipped = 0; + pt2_clipped = 0; + + if ((oc1 | oc2) != 0) { + result = miZeroClipLine(xleft, ytop, xright, ybottom, + &new_x1, &new_y1, &new_x2, &new_y2, + adx, ady, + &pt1_clipped, &pt2_clipped, + octant, bias, oc1, oc2); + if (result == -1) + continue; + + length = abs(new_x2 - new_x1); + + /* if we've clipped the endpoint, always draw the full length + * of the segment, because then the capstyle doesn't matter + */ + if (pt2_clipped) + length++; + + if (pt1_clipped) { + /* must calculate new error terms */ + clipdx = abs(new_x1 - x1); + clipdy = abs(new_y1 - y1); + e += (clipdy * e2) + ((clipdx - clipdy) * e1); + } + } + + /* draw the segment */ + + x = new_x1; + y = new_y1; + + e3 = e2 - e1; + e = e - e1; + + while (length--) { + MI_OUTPUT_POINT(x, y); + e += e1; + if (e >= 0) { + y += signdy; + e += e3; + } + x += signdx; + } + } + else { /* Y major line */ + + e1 = adx << 1; + e2 = e1 - (ady << 1); + e = e1 - ady; + length = ady; /* don't draw endpoint in main loop */ + + SetYMajorOctant(octant); + FIXUP_ERROR(e, octant, bias); + + new_x1 = x1; + new_y1 = y1; + new_x2 = x2; + new_y2 = y2; + pt1_clipped = 0; + pt2_clipped = 0; + + if ((oc1 | oc2) != 0) { + result = miZeroClipLine(xleft, ytop, xright, ybottom, + &new_x1, &new_y1, &new_x2, &new_y2, + adx, ady, + &pt1_clipped, &pt2_clipped, + octant, bias, oc1, oc2); + if (result == -1) + continue; + + length = abs(new_y2 - new_y1); + + /* if we've clipped the endpoint, always draw the full length + * of the segment, because then the capstyle doesn't matter + */ + if (pt2_clipped) + length++; + + if (pt1_clipped) { + /* must calculate new error terms */ + clipdx = abs(new_x1 - x1); + clipdy = abs(new_y1 - y1); + e += (clipdx * e2) + ((clipdy - clipdx) * e1); + } + } + + /* draw the segment */ + + x = new_x1; + y = new_y1; + + e3 = e2 - e1; + e = e - e1; + + while (length--) { + MI_OUTPUT_POINT(x, y); + e += e1; + if (e >= 0) { + x += signdx; + e += e3; + } + y += signdy; + } + } } /* only do the capnotlast check on the last segment @@ -351,31 +333,26 @@ miZeroLine( * point is the same as the first point, do not draw it, unless the * line is degenerate */ - if ( (! pt2_clipped) && (pGC->capStyle != CapNotLast) && - (((xstart != x2) || (ystart != y2)) || (ppt == pptInit + 1))) - { - MI_OUTPUT_POINT(x, y); - } + if ((!pt2_clipped) && (pGC->capStyle != CapNotLast) && + (((xstart != x2) || (ystart != y2)) || (ppt == pptInit + 1))) { + MI_OUTPUT_POINT(x, y); + } if (Nspans > 0) - (*pGC->ops->FillSpans)(pDraw, pGC, Nspans, pspanInit, - pwidthInit, FALSE); + (*pGC->ops->FillSpans) (pDraw, pGC, Nspans, pspanInit, + pwidthInit, FALSE); free(pwidthInit); free(pspanInit); } void -miZeroDashLine( - DrawablePtr dst, - GCPtr pgc, - int mode, - int nptInit, /* number of points in polyline */ - DDXPointRec *pptInit /* points in the polyline */ - ) +miZeroDashLine(DrawablePtr dst, GCPtr pgc, int mode, int nptInit, /* number of points in polyline */ + DDXPointRec * pptInit /* points in the polyline */ + ) { /* XXX kludge until real zero-width dash code is written */ pgc->lineWidth = 1; - miWideDash (dst, pgc, mode, nptInit, pptInit); + miWideDash(dst, pgc, mode, nptInit, pptInit); pgc->lineWidth = 0; } |