diff options
Diffstat (limited to 'xorg-server/hw/dmx/dmxgcops.c')
-rw-r--r-- | xorg-server/hw/dmx/dmxgcops.c | 1210 |
1 files changed, 605 insertions, 605 deletions
diff --git a/xorg-server/hw/dmx/dmxgcops.c b/xorg-server/hw/dmx/dmxgcops.c index 500e2cdf1..07165f731 100644 --- a/xorg-server/hw/dmx/dmxgcops.c +++ b/xorg-server/hw/dmx/dmxgcops.c @@ -1,605 +1,605 @@ -/* - * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation on the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) 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 - * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS - * 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. - */ - -/* - * Authors: - * Kevin E. Martin <kem@redhat.com> - * - */ - -/** \file - * This file provides support for GC operations. */ - -#ifdef HAVE_DMX_CONFIG_H -#include <dmx-config.h> -#endif - -#include "dmx.h" -#include "dmxsync.h" -#include "dmxgc.h" -#include "dmxgcops.h" -#include "dmxwindow.h" -#include "dmxpixmap.h" - -#include "mi.h" -#include "gcstruct.h" -#include "pixmapstr.h" -#include "dixfontstr.h" - -#ifdef PANORAMIX -#include "panoramiXsrv.h" -#endif - -#define DMX_GCOPS_SET_DRAWABLE(_pDraw, _draw) \ -do { \ - if ((_pDraw)->type == DRAWABLE_WINDOW) { \ - dmxWinPrivPtr pWinPriv = \ - DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw)); \ - (_draw) = (Drawable)pWinPriv->window; \ - } else { \ - dmxPixPrivPtr pPixPriv = \ - DMX_GET_PIXMAP_PRIV((PixmapPtr)(_pDraw)); \ - (_draw) = (Drawable)pPixPriv->pixmap; \ - } \ -} while (0) - -#define DMX_GCOPS_OFFSCREEN(_pDraw) \ - (!dmxScreens[(_pDraw)->pScreen->myNum].beDisplay || \ - (dmxOffScreenOpt && \ - (_pDraw)->type == DRAWABLE_WINDOW && \ - (DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->offscreen || \ - !DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->window))) - -/** Fill spans -- this function should never be called. */ -void dmxFillSpans(DrawablePtr pDrawable, GCPtr pGC, - int nInit, DDXPointPtr pptInit, int *pwidthInit, - int fSorted) -{ - /* Error -- this should never happen! */ -} - -/** Set spans -- this function should never be called. */ -void dmxSetSpans(DrawablePtr pDrawable, GCPtr pGC, - char *psrc, DDXPointPtr ppt, int *pwidth, int nspans, - int fSorted) -{ - /* Error -- this should never happen! */ -} - -/** Transfer \a pBits image to back-end server associated with \a - * pDrawable's screen. If primitive subdivision optimization is - * enabled, then only transfer the sections of \a pBits that are - * visible (i.e., not-clipped) to the back-end server. */ -void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC, - int depth, int x, int y, int w, int h, - int leftPad, int format, char *pBits) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - XImage *img; - - if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; - - img = XCreateImage(dmxScreen->beDisplay, - dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual, - depth, format, leftPad, pBits, w, h, - BitmapPad(dmxScreen->beDisplay), - (format == ZPixmap) ? - PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad)); - - if (img) { - Drawable draw; - - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - - if (dmxSubdividePrimitives && pGC->pCompositeClip) { - RegionPtr pSubImages; - RegionPtr pClip; - BoxRec box; - BoxPtr pBox; - int nBox; - - box.x1 = x; - box.y1 = y; - box.x2 = x + w; - box.y2 = y + h; - pSubImages = RegionCreate(&box, 1); - - pClip = RegionCreate(NullBox, 1); - RegionCopy(pClip, pGC->pCompositeClip); - RegionTranslate(pClip, - -pDrawable->x, -pDrawable->y); - RegionIntersect(pSubImages, pSubImages, pClip); - - nBox = RegionNumRects(pSubImages); - pBox = RegionRects(pSubImages); - - while (nBox--) { - XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img, - pBox->x1 - box.x1, - pBox->y1 - box.y1, - pBox->x1, - pBox->y1, - pBox->x2 - pBox->x1, - pBox->y2 - pBox->y1); - pBox++; - } - RegionDestroy(pClip); - RegionDestroy(pSubImages); - } else { - XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, - img, 0, 0, x, y, w, h); - } - XFree(img); /* Use XFree instead of XDestroyImage - * because pBits is passed in from the - * caller. */ - - dmxSync(dmxScreen, FALSE); - } else { - /* Error -- this should not happen! */ - } -} - -/** Copy area from \a pSrc drawable to \a pDst drawable on the back-end - * server associated with \a pSrc drawable's screen. If the offscreen - * optimization is enabled, only copy when both \a pSrc and \a pDst are - * at least partially visible. */ -RegionPtr dmxCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - Drawable srcDraw, dstDraw; - - if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst)) - return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h, - dstx, dsty, 0L); - - DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw); - DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw); - - XCopyArea(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc, - srcx, srcy, w, h, dstx, dsty); - dmxSync(dmxScreen, FALSE); - - return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h, - dstx, dsty, 0L); -} - -/** Copy plane number \a bitPlane from \a pSrc drawable to \a pDst - * drawable on the back-end server associated with \a pSrc drawable's - * screen. If the offscreen optimization is enabled, only copy when - * both \a pSrc and \a pDst are at least partially visible. */ -RegionPtr dmxCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int width, int height, - int dstx, int dsty, unsigned long bitPlane) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - Drawable srcDraw, dstDraw; - - if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst)) - return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height, - dstx, dsty, bitPlane); - - DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw); - DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw); - - XCopyPlane(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc, - srcx, srcy, width, height, dstx, dsty, bitPlane); - dmxSync(dmxScreen, FALSE); - - return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height, - dstx, dsty, bitPlane); -} - -/** Render list of points, \a pptInit in \a pDrawable on the back-end - * server associated with \a pDrawable's screen. If the offscreen - * optimization is enabled, only draw when \a pDrawable is at least - * partially visible. */ -void dmxPolyPoint(DrawablePtr pDrawable, GCPtr pGC, - int mode, int npt, DDXPointPtr pptInit) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - Drawable draw; - - if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; - - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - - XDrawPoints(dmxScreen->beDisplay, draw, pGCPriv->gc, - (XPoint *)pptInit, npt, mode); - dmxSync(dmxScreen, FALSE); -} - -/** Render list of connected lines, \a pptInit in \a pDrawable on the - * back-end server associated with \a pDrawable's screen. If the - * offscreen optimization is enabled, only draw when \a pDrawable is at - * least partially visible. */ -void dmxPolylines(DrawablePtr pDrawable, GCPtr pGC, - int mode, int npt, DDXPointPtr pptInit) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - Drawable draw; - - if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; - - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - - XDrawLines(dmxScreen->beDisplay, draw, pGCPriv->gc, - (XPoint *)pptInit, npt, mode); - dmxSync(dmxScreen, FALSE); -} - -/** Render list of disjoint segments, \a pSegs in \a pDrawable on the - * back-end server associated with \a pDrawable's screen. If the - * offscreen optimization is enabled, only draw when \a pDrawable is at - * least partially visible. */ -void dmxPolySegment(DrawablePtr pDrawable, GCPtr pGC, - int nseg, xSegment *pSegs) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - Drawable draw; - - if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; - - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - - XDrawSegments(dmxScreen->beDisplay, draw, pGCPriv->gc, - (XSegment *)pSegs, nseg); - dmxSync(dmxScreen, FALSE); -} - -/** Render list of rectangle outlines, \a pRects in \a pDrawable on the - * back-end server associated with \a pDrawable's screen. If the - * offscreen optimization is enabled, only draw when \a pDrawable is at - * least partially visible. */ -void dmxPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, - int nrects, xRectangle *pRects) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - Drawable draw; - - if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; - - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - - XDrawRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc, - (XRectangle *)pRects, nrects); - - dmxSync(dmxScreen, FALSE); -} - -/** Render list of arc outlines, \a parcs in \a pDrawable on the - * back-end server associated with \a pDrawable's screen. If the - * offscreen optimization is enabled, only draw when \a pDrawable is at - * least partially visible. */ -void dmxPolyArc(DrawablePtr pDrawable, GCPtr pGC, - int narcs, xArc *parcs) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - Drawable draw; - - if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; - - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - - XDrawArcs(dmxScreen->beDisplay, draw, pGCPriv->gc, - (XArc *)parcs, narcs); - dmxSync(dmxScreen, FALSE); -} - -/** Render a filled polygons in \a pDrawable on the back-end server - * associated with \a pDrawable's screen. If the offscreen - * optimization is enabled, only draw when \a pDrawable is at least - * partially visible. */ -void dmxFillPolygon(DrawablePtr pDrawable, GCPtr pGC, - int shape, int mode, int count, DDXPointPtr pPts) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - Drawable draw; - - if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; - - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - - XFillPolygon(dmxScreen->beDisplay, draw, pGCPriv->gc, - (XPoint *)pPts, count, shape, mode); - dmxSync(dmxScreen, FALSE); -} - -/** Render list of filled rectangles, \a prectInit in \a pDrawable on - * the back-end server associated with \a pDrawable's screen. If the - * offscreen optimization is enabled, only draw when \a pDrawable is at - * least partially visible. */ -void dmxPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, - int nrectFill, xRectangle *prectInit) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - Drawable draw; - - if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; - - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - - XFillRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc, - (XRectangle *)prectInit, nrectFill); - dmxSync(dmxScreen, FALSE); -} - -/** Render list of filled arcs, \a parcs in \a pDrawable on the back-end - * server associated with \a pDrawable's screen. If the offscreen - * optimization is enabled, only draw when \a pDrawable is at least - * partially visible. */ -void dmxPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, - int narcs, xArc *parcs) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - Drawable draw; - - if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; - - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - - XFillArcs(dmxScreen->beDisplay, draw, pGCPriv->gc, - (XArc *)parcs, narcs); - dmxSync(dmxScreen, FALSE); -} - -/** Render string of 8-bit \a chars (foreground only) in \a pDrawable on - * the back-end server associated with \a pDrawable's screen. If the - * offscreen optimization is enabled, only draw when \a pDrawable is at - * least partially visible. */ -int dmxPolyText8(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, char *chars) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - unsigned long n, i; - int w; - CharInfoPtr charinfo[255]; - Drawable draw; - - GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars, - Linear8Bit, &n, charinfo); - - /* Calculate text width */ - w = 0; - for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth; - - if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) { - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - - XDrawString(dmxScreen->beDisplay, draw, pGCPriv->gc, - x, y, chars, count); - dmxSync(dmxScreen, FALSE); - } - - return x+w; -} - -/** Render string of 16-bit \a chars (foreground only) in \a pDrawable - * on the back-end server associated with \a pDrawable's screen. If - * the offscreen optimization is enabled, only draw when \a pDrawable - * is at least partially visible. */ -int dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, unsigned short *chars) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - unsigned long n, i; - int w; - CharInfoPtr charinfo[255]; - Drawable draw; - - GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars, - (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit, - &n, charinfo); - - /* Calculate text width */ - w = 0; - for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth; - - if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) { - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - - XDrawString16(dmxScreen->beDisplay, draw, pGCPriv->gc, - x, y, (XChar2b *)chars, count); - dmxSync(dmxScreen, FALSE); - } - - return x+w; -} - -/** Render string of 8-bit \a chars (both foreground and background) in - * \a pDrawable on the back-end server associated with \a pDrawable's - * screen. If the offscreen optimization is enabled, only draw when \a - * pDrawable is at least partially visible. */ -void dmxImageText8(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, char *chars) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - Drawable draw; - - if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; - - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - - XDrawImageString(dmxScreen->beDisplay, draw, pGCPriv->gc, - x, y, chars, count); - dmxSync(dmxScreen, FALSE); -} - -/** Render string of 16-bit \a chars (both foreground and background) in - * \a pDrawable on the back-end server associated with \a pDrawable's - * screen. If the offscreen optimization is enabled, only draw when \a - * pDrawable is at least partially visible. */ -void dmxImageText16(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, unsigned short *chars) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); - Drawable draw; - - if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; - - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - - XDrawImageString16(dmxScreen->beDisplay, draw, pGCPriv->gc, - x, y, (XChar2b *)chars, count); - dmxSync(dmxScreen, FALSE); -} - -/** Image Glyph Blt -- this function should never be called. */ -void dmxImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase) -{ - /* Error -- this should never happen! */ -} - -/** Poly Glyph Blt -- this function should never be called. */ -void dmxPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase) -{ - /* Error -- this should never happen! */ -} - -/** Push Pixels -- this function should never be called. */ -void dmxPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, - int w, int h, int x, int y) -{ - /* Error -- this should never happen! */ -} - -/********************************************************************** - * Miscellaneous drawing commands - */ - -/** When Xinerama is active, the client pixmaps are always obtained from - * screen 0. When screen 0 is detached, the pixmaps must be obtained - * from any other screen that is not detached. Usually, this is screen - * 1. */ -static DMXScreenInfo *dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw) -{ -#ifdef PANORAMIX - PanoramiXRes *pXinPix; - int i; - DMXScreenInfo *dmxScreen; - - if (noPanoramiXExtension) return NULL; - if (pDrawable->type != DRAWABLE_PIXMAP) return NULL; - - if (Success != dixLookupResourceByType((pointer*) &pXinPix, - pDrawable->id, XRT_PIXMAP, - NullClient, DixUnknownAccess)) - return NULL; - - FOR_NSCREENS_FORWARD_SKIP(i) { - dmxScreen = &dmxScreens[i]; - if (dmxScreen->beDisplay) { - PixmapPtr pSrc; - dmxPixPrivPtr pSrcPriv; - - dixLookupResourceByType((pointer*) &pSrc, pXinPix->info[i].id, - RT_PIXMAP, NullClient, DixUnknownAccess); - pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc); - if (pSrcPriv->pixmap) { - *draw = pSrcPriv->pixmap; - return dmxScreen; - } - } - } -#endif - return NULL; -} - -/** Get an image from the back-end server associated with \a pDrawable's - * screen. If \a pDrawable is a window, it must be viewable to get an - * image from it. If it is not viewable, then get the image from the - * first ancestor of \a pDrawable that is viewable. If no viewable - * ancestor is found, then simply return without getting an image. */ -void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, - unsigned int format, unsigned long planeMask, char *pdstLine) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; - XImage *img; - Drawable draw; - - /* Cannot get image from unviewable window */ - if (pDrawable->type == DRAWABLE_WINDOW) { - WindowPtr pWindow = (WindowPtr)pDrawable; - if (!pWindow->viewable) { - while (!pWindow->viewable && pWindow->parent) { - sx += pWindow->origin.x - wBorderWidth(pWindow); - sx += pWindow->origin.y - wBorderWidth(pWindow); - pWindow = pWindow->parent; - } - if (!pWindow->viewable) { - return; - } - } - DMX_GCOPS_SET_DRAWABLE(&pWindow->drawable, draw); - if (DMX_GCOPS_OFFSCREEN(&pWindow->drawable)) - return; - } else { - DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - if (DMX_GCOPS_OFFSCREEN(pDrawable)) { - /* Try to find the pixmap on a non-detached Xinerama screen */ - dmxScreen = dmxFindAlternatePixmap(pDrawable, &draw); - if (!dmxScreen) return; - } - } - - img = XGetImage(dmxScreen->beDisplay, draw, - sx, sy, w, h, planeMask, format); - if (img) { - int len = img->bytes_per_line * img->height; - memmove(pdstLine, img->data, len); - XDestroyImage(img); - } - - dmxSync(dmxScreen, FALSE); -} - -/** Get Spans -- this function should never be called. */ -void dmxGetSpans(DrawablePtr pDrawable, int wMax, - DDXPointPtr ppt, int *pwidth, int nspans, - char *pdstStart) -{ - /* Error -- this should never happen! */ -} +/*
+ * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Kevin E. Martin <kem@redhat.com>
+ *
+ */
+
+/** \file
+ * This file provides support for GC operations. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxsync.h"
+#include "dmxgc.h"
+#include "dmxgcops.h"
+#include "dmxwindow.h"
+#include "dmxpixmap.h"
+
+#include "mi.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "dixfontstr.h"
+
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#endif
+
+#define DMX_GCOPS_SET_DRAWABLE(_pDraw, _draw) \
+do { \
+ if ((_pDraw)->type == DRAWABLE_WINDOW) { \
+ dmxWinPrivPtr pWinPriv = \
+ DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw)); \
+ (_draw) = (Drawable)pWinPriv->window; \
+ } else { \
+ dmxPixPrivPtr pPixPriv = \
+ DMX_GET_PIXMAP_PRIV((PixmapPtr)(_pDraw)); \
+ (_draw) = (Drawable)pPixPriv->pixmap; \
+ } \
+} while (0)
+
+#define DMX_GCOPS_OFFSCREEN(_pDraw) \
+ (!dmxScreens[(_pDraw)->pScreen->myNum].beDisplay || \
+ (dmxOffScreenOpt && \
+ (_pDraw)->type == DRAWABLE_WINDOW && \
+ (DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->offscreen || \
+ !DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->window)))
+
+/** Fill spans -- this function should never be called. */
+void dmxFillSpans(DrawablePtr pDrawable, GCPtr pGC,
+ int nInit, DDXPointPtr pptInit, int *pwidthInit,
+ int fSorted)
+{
+ /* Error -- this should never happen! */
+}
+
+/** Set spans -- this function should never be called. */
+void dmxSetSpans(DrawablePtr pDrawable, GCPtr pGC,
+ char *psrc, DDXPointPtr ppt, int *pwidth, int nspans,
+ int fSorted)
+{
+ /* Error -- this should never happen! */
+}
+
+/** Transfer \a pBits image to back-end server associated with \a
+ * pDrawable's screen. If primitive subdivision optimization is
+ * enabled, then only transfer the sections of \a pBits that are
+ * visible (i.e., not-clipped) to the back-end server. */
+void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC,
+ int depth, int x, int y, int w, int h,
+ int leftPad, int format, char *pBits)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ XImage *img;
+
+ if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
+
+ img = XCreateImage(dmxScreen->beDisplay,
+ dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
+ depth, format, leftPad, pBits, w, h,
+ BitmapPad(dmxScreen->beDisplay),
+ (format == ZPixmap) ?
+ PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad));
+
+ if (img) {
+ Drawable draw;
+
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+
+ if (dmxSubdividePrimitives && pGC->pCompositeClip) {
+ RegionPtr pSubImages;
+ RegionPtr pClip;
+ BoxRec box;
+ BoxPtr pBox;
+ int nBox;
+
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = x + w;
+ box.y2 = y + h;
+ pSubImages = RegionCreate(&box, 1);
+
+ pClip = RegionCreate(NullBox, 1);
+ RegionCopy(pClip, pGC->pCompositeClip);
+ RegionTranslate(pClip,
+ -pDrawable->x, -pDrawable->y);
+ RegionIntersect(pSubImages, pSubImages, pClip);
+
+ nBox = RegionNumRects(pSubImages);
+ pBox = RegionRects(pSubImages);
+
+ while (nBox--) {
+ XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img,
+ pBox->x1 - box.x1,
+ pBox->y1 - box.y1,
+ pBox->x1,
+ pBox->y1,
+ pBox->x2 - pBox->x1,
+ pBox->y2 - pBox->y1);
+ pBox++;
+ }
+ RegionDestroy(pClip);
+ RegionDestroy(pSubImages);
+ } else {
+ XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc,
+ img, 0, 0, x, y, w, h);
+ }
+ XFree(img); /* Use XFree instead of XDestroyImage
+ * because pBits is passed in from the
+ * caller. */
+
+ dmxSync(dmxScreen, FALSE);
+ } else {
+ /* Error -- this should not happen! */
+ }
+}
+
+/** Copy area from \a pSrc drawable to \a pDst drawable on the back-end
+ * server associated with \a pSrc drawable's screen. If the offscreen
+ * optimization is enabled, only copy when both \a pSrc and \a pDst are
+ * at least partially visible. */
+RegionPtr dmxCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ Drawable srcDraw, dstDraw;
+
+ if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst))
+ return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
+ dstx, dsty, 0L);
+
+ DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
+ DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
+
+ XCopyArea(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
+ srcx, srcy, w, h, dstx, dsty);
+ dmxSync(dmxScreen, FALSE);
+
+ return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
+ dstx, dsty, 0L);
+}
+
+/** Copy plane number \a bitPlane from \a pSrc drawable to \a pDst
+ * drawable on the back-end server associated with \a pSrc drawable's
+ * screen. If the offscreen optimization is enabled, only copy when
+ * both \a pSrc and \a pDst are at least partially visible. */
+RegionPtr dmxCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int width, int height,
+ int dstx, int dsty, unsigned long bitPlane)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ Drawable srcDraw, dstDraw;
+
+ if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst))
+ return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height,
+ dstx, dsty, bitPlane);
+
+ DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
+ DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
+
+ XCopyPlane(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
+ srcx, srcy, width, height, dstx, dsty, bitPlane);
+ dmxSync(dmxScreen, FALSE);
+
+ return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height,
+ dstx, dsty, bitPlane);
+}
+
+/** Render list of points, \a pptInit in \a pDrawable on the back-end
+ * server associated with \a pDrawable's screen. If the offscreen
+ * optimization is enabled, only draw when \a pDrawable is at least
+ * partially visible. */
+void dmxPolyPoint(DrawablePtr pDrawable, GCPtr pGC,
+ int mode, int npt, DDXPointPtr pptInit)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ Drawable draw;
+
+ if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
+
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+
+ XDrawPoints(dmxScreen->beDisplay, draw, pGCPriv->gc,
+ (XPoint *)pptInit, npt, mode);
+ dmxSync(dmxScreen, FALSE);
+}
+
+/** Render list of connected lines, \a pptInit in \a pDrawable on the
+ * back-end server associated with \a pDrawable's screen. If the
+ * offscreen optimization is enabled, only draw when \a pDrawable is at
+ * least partially visible. */
+void dmxPolylines(DrawablePtr pDrawable, GCPtr pGC,
+ int mode, int npt, DDXPointPtr pptInit)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ Drawable draw;
+
+ if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
+
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+
+ XDrawLines(dmxScreen->beDisplay, draw, pGCPriv->gc,
+ (XPoint *)pptInit, npt, mode);
+ dmxSync(dmxScreen, FALSE);
+}
+
+/** Render list of disjoint segments, \a pSegs in \a pDrawable on the
+ * back-end server associated with \a pDrawable's screen. If the
+ * offscreen optimization is enabled, only draw when \a pDrawable is at
+ * least partially visible. */
+void dmxPolySegment(DrawablePtr pDrawable, GCPtr pGC,
+ int nseg, xSegment *pSegs)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ Drawable draw;
+
+ if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
+
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+
+ XDrawSegments(dmxScreen->beDisplay, draw, pGCPriv->gc,
+ (XSegment *)pSegs, nseg);
+ dmxSync(dmxScreen, FALSE);
+}
+
+/** Render list of rectangle outlines, \a pRects in \a pDrawable on the
+ * back-end server associated with \a pDrawable's screen. If the
+ * offscreen optimization is enabled, only draw when \a pDrawable is at
+ * least partially visible. */
+void dmxPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
+ int nrects, xRectangle *pRects)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ Drawable draw;
+
+ if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
+
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+
+ XDrawRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
+ (XRectangle *)pRects, nrects);
+
+ dmxSync(dmxScreen, FALSE);
+}
+
+/** Render list of arc outlines, \a parcs in \a pDrawable on the
+ * back-end server associated with \a pDrawable's screen. If the
+ * offscreen optimization is enabled, only draw when \a pDrawable is at
+ * least partially visible. */
+void dmxPolyArc(DrawablePtr pDrawable, GCPtr pGC,
+ int narcs, xArc *parcs)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ Drawable draw;
+
+ if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
+
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+
+ XDrawArcs(dmxScreen->beDisplay, draw, pGCPriv->gc,
+ (XArc *)parcs, narcs);
+ dmxSync(dmxScreen, FALSE);
+}
+
+/** Render a filled polygons in \a pDrawable on the back-end server
+ * associated with \a pDrawable's screen. If the offscreen
+ * optimization is enabled, only draw when \a pDrawable is at least
+ * partially visible. */
+void dmxFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
+ int shape, int mode, int count, DDXPointPtr pPts)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ Drawable draw;
+
+ if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
+
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+
+ XFillPolygon(dmxScreen->beDisplay, draw, pGCPriv->gc,
+ (XPoint *)pPts, count, shape, mode);
+ dmxSync(dmxScreen, FALSE);
+}
+
+/** Render list of filled rectangles, \a prectInit in \a pDrawable on
+ * the back-end server associated with \a pDrawable's screen. If the
+ * offscreen optimization is enabled, only draw when \a pDrawable is at
+ * least partially visible. */
+void dmxPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ Drawable draw;
+
+ if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
+
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+
+ XFillRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
+ (XRectangle *)prectInit, nrectFill);
+ dmxSync(dmxScreen, FALSE);
+}
+
+/** Render list of filled arcs, \a parcs in \a pDrawable on the back-end
+ * server associated with \a pDrawable's screen. If the offscreen
+ * optimization is enabled, only draw when \a pDrawable is at least
+ * partially visible. */
+void dmxPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
+ int narcs, xArc *parcs)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ Drawable draw;
+
+ if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
+
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+
+ XFillArcs(dmxScreen->beDisplay, draw, pGCPriv->gc,
+ (XArc *)parcs, narcs);
+ dmxSync(dmxScreen, FALSE);
+}
+
+/** Render string of 8-bit \a chars (foreground only) in \a pDrawable on
+ * the back-end server associated with \a pDrawable's screen. If the
+ * offscreen optimization is enabled, only draw when \a pDrawable is at
+ * least partially visible. */
+int dmxPolyText8(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, char *chars)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ unsigned long n, i;
+ int w;
+ CharInfoPtr charinfo[255];
+ Drawable draw;
+
+ GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
+ Linear8Bit, &n, charinfo);
+
+ /* Calculate text width */
+ w = 0;
+ for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
+
+ if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+
+ XDrawString(dmxScreen->beDisplay, draw, pGCPriv->gc,
+ x, y, chars, count);
+ dmxSync(dmxScreen, FALSE);
+ }
+
+ return x+w;
+}
+
+/** Render string of 16-bit \a chars (foreground only) in \a pDrawable
+ * on the back-end server associated with \a pDrawable's screen. If
+ * the offscreen optimization is enabled, only draw when \a pDrawable
+ * is at least partially visible. */
+int dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, unsigned short *chars)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ unsigned long n, i;
+ int w;
+ CharInfoPtr charinfo[255];
+ Drawable draw;
+
+ GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, charinfo);
+
+ /* Calculate text width */
+ w = 0;
+ for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
+
+ if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+
+ XDrawString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
+ x, y, (XChar2b *)chars, count);
+ dmxSync(dmxScreen, FALSE);
+ }
+
+ return x+w;
+}
+
+/** Render string of 8-bit \a chars (both foreground and background) in
+ * \a pDrawable on the back-end server associated with \a pDrawable's
+ * screen. If the offscreen optimization is enabled, only draw when \a
+ * pDrawable is at least partially visible. */
+void dmxImageText8(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, char *chars)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ Drawable draw;
+
+ if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
+
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+
+ XDrawImageString(dmxScreen->beDisplay, draw, pGCPriv->gc,
+ x, y, chars, count);
+ dmxSync(dmxScreen, FALSE);
+}
+
+/** Render string of 16-bit \a chars (both foreground and background) in
+ * \a pDrawable on the back-end server associated with \a pDrawable's
+ * screen. If the offscreen optimization is enabled, only draw when \a
+ * pDrawable is at least partially visible. */
+void dmxImageText16(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, unsigned short *chars)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ Drawable draw;
+
+ if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
+
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+
+ XDrawImageString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
+ x, y, (XChar2b *)chars, count);
+ dmxSync(dmxScreen, FALSE);
+}
+
+/** Image Glyph Blt -- this function should never be called. */
+void dmxImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ /* Error -- this should never happen! */
+}
+
+/** Poly Glyph Blt -- this function should never be called. */
+void dmxPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ /* Error -- this should never happen! */
+}
+
+/** Push Pixels -- this function should never be called. */
+void dmxPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
+ int w, int h, int x, int y)
+{
+ /* Error -- this should never happen! */
+}
+
+/**********************************************************************
+ * Miscellaneous drawing commands
+ */
+
+/** When Xinerama is active, the client pixmaps are always obtained from
+ * screen 0. When screen 0 is detached, the pixmaps must be obtained
+ * from any other screen that is not detached. Usually, this is screen
+ * 1. */
+static DMXScreenInfo *dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw)
+{
+#ifdef PANORAMIX
+ PanoramiXRes *pXinPix;
+ int i;
+ DMXScreenInfo *dmxScreen;
+
+ if (noPanoramiXExtension) return NULL;
+ if (pDrawable->type != DRAWABLE_PIXMAP) return NULL;
+
+ if (Success != dixLookupResourceByType((pointer*) &pXinPix,
+ pDrawable->id, XRT_PIXMAP,
+ NullClient, DixUnknownAccess))
+ return NULL;
+
+ FOR_NSCREENS_FORWARD_SKIP(i) {
+ dmxScreen = &dmxScreens[i];
+ if (dmxScreen->beDisplay) {
+ PixmapPtr pSrc;
+ dmxPixPrivPtr pSrcPriv;
+
+ dixLookupResourceByType((pointer*) &pSrc, pXinPix->info[i].id,
+ RT_PIXMAP, NullClient, DixUnknownAccess);
+ pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc);
+ if (pSrcPriv->pixmap) {
+ *draw = pSrcPriv->pixmap;
+ return dmxScreen;
+ }
+ }
+ }
+#endif
+ return NULL;
+}
+
+/** Get an image from the back-end server associated with \a pDrawable's
+ * screen. If \a pDrawable is a window, it must be viewable to get an
+ * image from it. If it is not viewable, then get the image from the
+ * first ancestor of \a pDrawable that is viewable. If no viewable
+ * ancestor is found, then simply return without getting an image. */
+void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
+ unsigned int format, unsigned long planeMask, char *pdstLine)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ XImage *img;
+ Drawable draw;
+
+ /* Cannot get image from unviewable window */
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ WindowPtr pWindow = (WindowPtr)pDrawable;
+ if (!pWindow->viewable) {
+ while (!pWindow->viewable && pWindow->parent) {
+ sx += pWindow->origin.x - wBorderWidth(pWindow);
+ sx += pWindow->origin.y - wBorderWidth(pWindow);
+ pWindow = pWindow->parent;
+ }
+ if (!pWindow->viewable) {
+ return;
+ }
+ }
+ DMX_GCOPS_SET_DRAWABLE(&pWindow->drawable, draw);
+ if (DMX_GCOPS_OFFSCREEN(&pWindow->drawable))
+ return;
+ } else {
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
+ if (DMX_GCOPS_OFFSCREEN(pDrawable)) {
+ /* Try to find the pixmap on a non-detached Xinerama screen */
+ dmxScreen = dmxFindAlternatePixmap(pDrawable, &draw);
+ if (!dmxScreen) return;
+ }
+ }
+
+ img = XGetImage(dmxScreen->beDisplay, draw,
+ sx, sy, w, h, planeMask, format);
+ if (img) {
+ int len = img->bytes_per_line * img->height;
+ memmove(pdstLine, img->data, len);
+ XDestroyImage(img);
+ }
+
+ dmxSync(dmxScreen, FALSE);
+}
+
+/** Get Spans -- this function should never be called. */
+void dmxGetSpans(DrawablePtr pDrawable, int wMax,
+ DDXPointPtr ppt, int *pwidth, int nspans,
+ char *pdstStart)
+{
+ /* Error -- this should never happen! */
+}
|