105b261ecSmrg/*
205b261ecSmrg
305b261ecSmrgCopyright 1993 by Davor Matic
405b261ecSmrg
505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software
605b261ecSmrgand its documentation for any purpose is hereby granted without fee,
705b261ecSmrgprovided that the above copyright notice appear in all copies and that
805b261ecSmrgboth that copyright notice and this permission notice appear in
905b261ecSmrgsupporting documentation.  Davor Matic makes no representations about
1005b261ecSmrgthe suitability of this software for any purpose.  It is provided "as
1105b261ecSmrgis" without express or implied warranty.
1205b261ecSmrg
1305b261ecSmrg*/
1405b261ecSmrg
1505b261ecSmrg#ifdef HAVE_XNEST_CONFIG_H
1605b261ecSmrg#include <xnest-config.h>
1705b261ecSmrg#endif
1805b261ecSmrg
1905b261ecSmrg#include <X11/X.h>
2005b261ecSmrg#include <X11/Xproto.h>
2105b261ecSmrg#include "regionstr.h"
2205b261ecSmrg#include <X11/fonts/fontstruct.h>
2305b261ecSmrg#include "gcstruct.h"
2405b261ecSmrg#include "scrnintstr.h"
2505b261ecSmrg#include "windowstr.h"
2605b261ecSmrg#include "pixmapstr.h"
2705b261ecSmrg#include "region.h"
2805b261ecSmrg#include "servermd.h"
2905b261ecSmrg
3005b261ecSmrg#include "Xnest.h"
3105b261ecSmrg
3205b261ecSmrg#include "Display.h"
3305b261ecSmrg#include "Screen.h"
3405b261ecSmrg#include "XNGC.h"
3505b261ecSmrg#include "XNFont.h"
3605b261ecSmrg#include "GCOps.h"
3705b261ecSmrg#include "Drawable.h"
3805b261ecSmrg#include "Visual.h"
3905b261ecSmrg
4005b261ecSmrgvoid
4135c4bbdfSmrgxnestFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans, xPoint * pPoints,
4235c4bbdfSmrg               int *pWidths, int fSorted)
4305b261ecSmrg{
4435c4bbdfSmrg    ErrorF("xnest warning: function xnestFillSpans not implemented\n");
4505b261ecSmrg}
4605b261ecSmrg
4705b261ecSmrgvoid
4805b261ecSmrgxnestSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *pSrc,
4935c4bbdfSmrg              xPoint * pPoints, int *pWidths, int nSpans, int fSorted)
5005b261ecSmrg{
5135c4bbdfSmrg    ErrorF("xnest warning: function xnestSetSpans not implemented\n");
5205b261ecSmrg}
5305b261ecSmrg
5405b261ecSmrgvoid
5505b261ecSmrgxnestGetSpans(DrawablePtr pDrawable, int maxWidth, DDXPointPtr pPoints,
5635c4bbdfSmrg              int *pWidths, int nSpans, char *pBuffer)
5705b261ecSmrg{
5835c4bbdfSmrg    ErrorF("xnest warning: function xnestGetSpans not implemented\n");
5905b261ecSmrg}
6005b261ecSmrg
6105b261ecSmrgvoid
6205b261ecSmrgxnestQueryBestSize(int class, unsigned short *pWidth, unsigned short *pHeight,
6335c4bbdfSmrg                   ScreenPtr pScreen)
6405b261ecSmrg{
6535c4bbdfSmrg    unsigned int width, height;
6605b261ecSmrg
6735c4bbdfSmrg    width = *pWidth;
6835c4bbdfSmrg    height = *pHeight;
6905b261ecSmrg
7035c4bbdfSmrg    XQueryBestSize(xnestDisplay, class,
7135c4bbdfSmrg                   xnestDefaultWindows[pScreen->myNum],
7235c4bbdfSmrg                   width, height, &width, &height);
7335c4bbdfSmrg
7435c4bbdfSmrg    *pWidth = width;
7535c4bbdfSmrg    *pHeight = height;
7605b261ecSmrg}
7705b261ecSmrg
7805b261ecSmrgvoid
7905b261ecSmrgxnestPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
8035c4bbdfSmrg              int w, int h, int leftPad, int format, char *pImage)
8135c4bbdfSmrg{
8235c4bbdfSmrg    XImage *ximage;
8335c4bbdfSmrg
8435c4bbdfSmrg    ximage = XCreateImage(xnestDisplay, xnestDefaultVisual(pDrawable->pScreen),
8535c4bbdfSmrg                          depth, format, leftPad, (char *) pImage,
8635c4bbdfSmrg                          w, h, BitmapPad(xnestDisplay),
8735c4bbdfSmrg                          (format == ZPixmap) ?
8835c4bbdfSmrg                          PixmapBytePad(w, depth) : BitmapBytePad(w + leftPad));
8935c4bbdfSmrg
9035c4bbdfSmrg    if (ximage) {
9135c4bbdfSmrg        XPutImage(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
9235c4bbdfSmrg                  ximage, 0, 0, x, y, w, h);
9335c4bbdfSmrg        XFree(ximage);
9435c4bbdfSmrg    }
9535c4bbdfSmrg}
9635c4bbdfSmrg
9735c4bbdfSmrgstatic int
9835c4bbdfSmrgxnestIgnoreErrorHandler (Display     *dpy,
9935c4bbdfSmrg                         XErrorEvent *event)
10005b261ecSmrg{
10135c4bbdfSmrg    return False; /* return value is ignored */
10205b261ecSmrg}
10305b261ecSmrg
10405b261ecSmrgvoid
10505b261ecSmrgxnestGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
10635c4bbdfSmrg              unsigned int format, unsigned long planeMask, char *pImage)
10705b261ecSmrg{
10835c4bbdfSmrg    XImage *ximage;
10935c4bbdfSmrg    int length;
11035c4bbdfSmrg    int (*old_handler)(Display*, XErrorEvent*);
11135c4bbdfSmrg
11235c4bbdfSmrg    /* we may get BadMatch error when xnest window is minimized */
11335c4bbdfSmrg    XSync(xnestDisplay, False);
11435c4bbdfSmrg    old_handler = XSetErrorHandler (xnestIgnoreErrorHandler);
11535c4bbdfSmrg
11635c4bbdfSmrg    ximage = XGetImage(xnestDisplay, xnestDrawable(pDrawable),
11735c4bbdfSmrg                       x, y, w, h, planeMask, format);
11835c4bbdfSmrg    XSetErrorHandler(old_handler);
11935c4bbdfSmrg
12035c4bbdfSmrg    if (ximage) {
12135c4bbdfSmrg        length = ximage->bytes_per_line * ximage->height;
12235c4bbdfSmrg
12335c4bbdfSmrg        memmove(pImage, ximage->data, length);
12435c4bbdfSmrg
12535c4bbdfSmrg        XDestroyImage(ximage);
12635c4bbdfSmrg    }
12705b261ecSmrg}
12805b261ecSmrg
12905b261ecSmrgstatic Bool
13035c4bbdfSmrgxnestBitBlitPredicate(Display * dpy, XEvent * event, char *args)
13105b261ecSmrg{
13235c4bbdfSmrg    return event->type == GraphicsExpose || event->type == NoExpose;
13305b261ecSmrg}
13405b261ecSmrg
13505b261ecSmrgstatic RegionPtr
13605b261ecSmrgxnestBitBlitHelper(GCPtr pGC)
13705b261ecSmrg{
13835c4bbdfSmrg    if (!pGC->graphicsExposures)
13935c4bbdfSmrg        return NullRegion;
14035c4bbdfSmrg    else {
14135c4bbdfSmrg        XEvent event;
14235c4bbdfSmrg        RegionPtr pReg, pTmpReg;
14335c4bbdfSmrg        BoxRec Box;
14435c4bbdfSmrg        Bool pending, overlap;
14535c4bbdfSmrg
14635c4bbdfSmrg        pReg = RegionCreate(NULL, 1);
14735c4bbdfSmrg        pTmpReg = RegionCreate(NULL, 1);
14835c4bbdfSmrg        if (!pReg || !pTmpReg)
14935c4bbdfSmrg            return NullRegion;
15035c4bbdfSmrg
15135c4bbdfSmrg        pending = True;
15235c4bbdfSmrg        while (pending) {
15335c4bbdfSmrg            XIfEvent(xnestDisplay, &event, xnestBitBlitPredicate, NULL);
15435c4bbdfSmrg
15535c4bbdfSmrg            switch (event.type) {
15635c4bbdfSmrg            case NoExpose:
15735c4bbdfSmrg                pending = False;
15835c4bbdfSmrg                break;
15935c4bbdfSmrg
16035c4bbdfSmrg            case GraphicsExpose:
16135c4bbdfSmrg                Box.x1 = event.xgraphicsexpose.x;
16235c4bbdfSmrg                Box.y1 = event.xgraphicsexpose.y;
16335c4bbdfSmrg                Box.x2 = event.xgraphicsexpose.x + event.xgraphicsexpose.width;
16435c4bbdfSmrg                Box.y2 = event.xgraphicsexpose.y + event.xgraphicsexpose.height;
16535c4bbdfSmrg                RegionReset(pTmpReg, &Box);
16635c4bbdfSmrg                RegionAppend(pReg, pTmpReg);
16735c4bbdfSmrg                pending = event.xgraphicsexpose.count;
16835c4bbdfSmrg                break;
16935c4bbdfSmrg            }
17035c4bbdfSmrg        }
17135c4bbdfSmrg
17235c4bbdfSmrg        RegionDestroy(pTmpReg);
17335c4bbdfSmrg        RegionValidate(pReg, &overlap);
17435c4bbdfSmrg        return pReg;
17505b261ecSmrg    }
17605b261ecSmrg}
17705b261ecSmrg
17805b261ecSmrgRegionPtr
17905b261ecSmrgxnestCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
18035c4bbdfSmrg              GCPtr pGC, int srcx, int srcy, int width, int height,
18135c4bbdfSmrg              int dstx, int dsty)
18205b261ecSmrg{
18335c4bbdfSmrg    XCopyArea(xnestDisplay,
18435c4bbdfSmrg              xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
18535c4bbdfSmrg              xnestGC(pGC), srcx, srcy, width, height, dstx, dsty);
18635c4bbdfSmrg
18735c4bbdfSmrg    return xnestBitBlitHelper(pGC);
18805b261ecSmrg}
18905b261ecSmrg
19005b261ecSmrgRegionPtr
19105b261ecSmrgxnestCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
19235c4bbdfSmrg               GCPtr pGC, int srcx, int srcy, int width, int height,
19335c4bbdfSmrg               int dstx, int dsty, unsigned long plane)
19405b261ecSmrg{
19535c4bbdfSmrg    XCopyPlane(xnestDisplay,
19635c4bbdfSmrg               xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
19735c4bbdfSmrg               xnestGC(pGC), srcx, srcy, width, height, dstx, dsty, plane);
19835c4bbdfSmrg
19935c4bbdfSmrg    return xnestBitBlitHelper(pGC);
20005b261ecSmrg}
20105b261ecSmrg
20205b261ecSmrgvoid
20305b261ecSmrgxnestPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
20435c4bbdfSmrg               DDXPointPtr pPoints)
20505b261ecSmrg{
20635c4bbdfSmrg    XDrawPoints(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
20735c4bbdfSmrg                (XPoint *) pPoints, nPoints, mode);
20805b261ecSmrg}
20905b261ecSmrg
21005b261ecSmrgvoid
21105b261ecSmrgxnestPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
21235c4bbdfSmrg               DDXPointPtr pPoints)
21305b261ecSmrg{
21435c4bbdfSmrg    XDrawLines(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
21535c4bbdfSmrg               (XPoint *) pPoints, nPoints, mode);
21605b261ecSmrg}
21705b261ecSmrg
21805b261ecSmrgvoid
21905b261ecSmrgxnestPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nSegments,
22035c4bbdfSmrg                 xSegment * pSegments)
22105b261ecSmrg{
22235c4bbdfSmrg    XDrawSegments(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
22335c4bbdfSmrg                  (XSegment *) pSegments, nSegments);
22405b261ecSmrg}
22505b261ecSmrg
22605b261ecSmrgvoid
22705b261ecSmrgxnestPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
22835c4bbdfSmrg                   xRectangle *pRectangles)
22905b261ecSmrg{
23035c4bbdfSmrg    XDrawRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
23135c4bbdfSmrg                    (XRectangle *) pRectangles, nRectangles);
23205b261ecSmrg}
23305b261ecSmrg
23405b261ecSmrgvoid
23535c4bbdfSmrgxnestPolyArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs)
23605b261ecSmrg{
23735c4bbdfSmrg    XDrawArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
23835c4bbdfSmrg              (XArc *) pArcs, nArcs);
23905b261ecSmrg}
24005b261ecSmrg
24105b261ecSmrgvoid
24205b261ecSmrgxnestFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode,
24335c4bbdfSmrg                 int nPoints, DDXPointPtr pPoints)
24405b261ecSmrg{
24535c4bbdfSmrg    XFillPolygon(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
24635c4bbdfSmrg                 (XPoint *) pPoints, nPoints, shape, mode);
24705b261ecSmrg}
24805b261ecSmrg
24905b261ecSmrgvoid
25005b261ecSmrgxnestPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
25135c4bbdfSmrg                  xRectangle *pRectangles)
25205b261ecSmrg{
25335c4bbdfSmrg    XFillRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
25435c4bbdfSmrg                    (XRectangle *) pRectangles, nRectangles);
25505b261ecSmrg}
25605b261ecSmrg
25705b261ecSmrgvoid
25835c4bbdfSmrgxnestPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs)
25905b261ecSmrg{
26035c4bbdfSmrg    XFillArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
26135c4bbdfSmrg              (XArc *) pArcs, nArcs);
26205b261ecSmrg}
26305b261ecSmrg
26405b261ecSmrgint
26505b261ecSmrgxnestPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
26635c4bbdfSmrg               char *string)
26705b261ecSmrg{
26835c4bbdfSmrg    int width;
26935c4bbdfSmrg
27035c4bbdfSmrg    XDrawString(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
27135c4bbdfSmrg                x, y, string, count);
27235c4bbdfSmrg
27335c4bbdfSmrg    width = XTextWidth(xnestFontStruct(pGC->font), string, count);
27435c4bbdfSmrg
27535c4bbdfSmrg    return width + x;
27605b261ecSmrg}
27705b261ecSmrg
27805b261ecSmrgint
27905b261ecSmrgxnestPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
28035c4bbdfSmrg                unsigned short *string)
28105b261ecSmrg{
28235c4bbdfSmrg    int width;
28305b261ecSmrg
28435c4bbdfSmrg    XDrawString16(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
28535c4bbdfSmrg                  x, y, (XChar2b *) string, count);
28605b261ecSmrg
28735c4bbdfSmrg    width = XTextWidth16(xnestFontStruct(pGC->font), (XChar2b *) string, count);
28805b261ecSmrg
28935c4bbdfSmrg    return width + x;
29005b261ecSmrg}
29105b261ecSmrg
29205b261ecSmrgvoid
29305b261ecSmrgxnestImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
29435c4bbdfSmrg                char *string)
29505b261ecSmrg{
29635c4bbdfSmrg    XDrawImageString(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
29735c4bbdfSmrg                     x, y, string, count);
29805b261ecSmrg}
29905b261ecSmrg
30005b261ecSmrgvoid
30105b261ecSmrgxnestImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
30235c4bbdfSmrg                 unsigned short *string)
30305b261ecSmrg{
30435c4bbdfSmrg    XDrawImageString16(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
30535c4bbdfSmrg                       x, y, (XChar2b *) string, count);
30605b261ecSmrg}
30705b261ecSmrg
30805b261ecSmrgvoid
30905b261ecSmrgxnestImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
31035c4bbdfSmrg                   unsigned int nGlyphs, CharInfoPtr * pCharInfo,
31135c4bbdfSmrg                   void *pGlyphBase)
31205b261ecSmrg{
31335c4bbdfSmrg    ErrorF("xnest warning: function xnestImageGlyphBlt not implemented\n");
31405b261ecSmrg}
31505b261ecSmrg
31605b261ecSmrgvoid
31705b261ecSmrgxnestPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
31835c4bbdfSmrg                  unsigned int nGlyphs, CharInfoPtr * pCharInfo,
31935c4bbdfSmrg                  void *pGlyphBase)
32005b261ecSmrg{
32135c4bbdfSmrg    ErrorF("xnest warning: function xnestPolyGlyphBlt not implemented\n");
32205b261ecSmrg}
32305b261ecSmrg
32405b261ecSmrgvoid
32505b261ecSmrgxnestPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDst,
32635c4bbdfSmrg                int width, int height, int x, int y)
32705b261ecSmrg{
32835c4bbdfSmrg    /* only works for solid bitmaps */
32935c4bbdfSmrg    if (pGC->fillStyle == FillSolid) {
33035c4bbdfSmrg        XSetStipple(xnestDisplay, xnestGC(pGC), xnestPixmap(pBitmap));
33135c4bbdfSmrg        XSetTSOrigin(xnestDisplay, xnestGC(pGC), x, y);
33235c4bbdfSmrg        XSetFillStyle(xnestDisplay, xnestGC(pGC), FillStippled);
33335c4bbdfSmrg        XFillRectangle(xnestDisplay, xnestDrawable(pDst),
33435c4bbdfSmrg                       xnestGC(pGC), x, y, width, height);
33535c4bbdfSmrg        XSetFillStyle(xnestDisplay, xnestGC(pGC), FillSolid);
33635c4bbdfSmrg    }
33735c4bbdfSmrg    else
33835c4bbdfSmrg        ErrorF("xnest warning: function xnestPushPixels not implemented\n");
33905b261ecSmrg}
340