1706f2543Smrg/*
2706f2543Smrg * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
3706f2543Smrg *
4706f2543Smrg * All Rights Reserved.
5706f2543Smrg *
6706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining
7706f2543Smrg * a copy of this software and associated documentation files (the
8706f2543Smrg * "Software"), to deal in the Software without restriction, including
9706f2543Smrg * without limitation on the rights to use, copy, modify, merge,
10706f2543Smrg * publish, distribute, sublicense, and/or sell copies of the Software,
11706f2543Smrg * and to permit persons to whom the Software is furnished to do so,
12706f2543Smrg * subject to the following conditions:
13706f2543Smrg *
14706f2543Smrg * The above copyright notice and this permission notice (including the
15706f2543Smrg * next paragraph) shall be included in all copies or substantial
16706f2543Smrg * portions of the Software.
17706f2543Smrg *
18706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19706f2543Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21706f2543Smrg * NON-INFRINGEMENT.  IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22706f2543Smrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23706f2543Smrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24706f2543Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25706f2543Smrg * SOFTWARE.
26706f2543Smrg */
27706f2543Smrg
28706f2543Smrg/*
29706f2543Smrg * Authors:
30706f2543Smrg *   Kevin E. Martin <kem@redhat.com>
31706f2543Smrg *
32706f2543Smrg */
33706f2543Smrg
34706f2543Smrg/** \file
35706f2543Smrg * This file provides support for GC operations. */
36706f2543Smrg
37706f2543Smrg#ifdef HAVE_DMX_CONFIG_H
38706f2543Smrg#include <dmx-config.h>
39706f2543Smrg#endif
40706f2543Smrg
41706f2543Smrg#include "dmx.h"
42706f2543Smrg#include "dmxsync.h"
43706f2543Smrg#include "dmxgc.h"
44706f2543Smrg#include "dmxgcops.h"
45706f2543Smrg#include "dmxwindow.h"
46706f2543Smrg#include "dmxpixmap.h"
47706f2543Smrg
48706f2543Smrg#include "mi.h"
49706f2543Smrg#include "gcstruct.h"
50706f2543Smrg#include "pixmapstr.h"
51706f2543Smrg#include "dixfontstr.h"
52706f2543Smrg
53706f2543Smrg#ifdef PANORAMIX
54706f2543Smrg#include "panoramiXsrv.h"
55706f2543Smrg#endif
56706f2543Smrg
57706f2543Smrg#define DMX_GCOPS_SET_DRAWABLE(_pDraw, _draw)				\
58706f2543Smrgdo {									\
59706f2543Smrg    if ((_pDraw)->type == DRAWABLE_WINDOW) {				\
60706f2543Smrg	dmxWinPrivPtr  pWinPriv =					\
61706f2543Smrg	    DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw));			\
62706f2543Smrg	(_draw) = (Drawable)pWinPriv->window;				\
63706f2543Smrg    } else {								\
64706f2543Smrg	dmxPixPrivPtr  pPixPriv =					\
65706f2543Smrg	    DMX_GET_PIXMAP_PRIV((PixmapPtr)(_pDraw));			\
66706f2543Smrg	(_draw) = (Drawable)pPixPriv->pixmap;				\
67706f2543Smrg    }									\
68706f2543Smrg} while (0)
69706f2543Smrg
70706f2543Smrg#define DMX_GCOPS_OFFSCREEN(_pDraw)					\
71706f2543Smrg    (!dmxScreens[(_pDraw)->pScreen->myNum].beDisplay ||			\
72706f2543Smrg     (dmxOffScreenOpt &&						\
73706f2543Smrg      (_pDraw)->type == DRAWABLE_WINDOW &&				\
74706f2543Smrg      (DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->offscreen ||		\
75706f2543Smrg       !DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->window)))
76706f2543Smrg
77706f2543Smrg/** Fill spans -- this function should never be called. */
78706f2543Smrgvoid dmxFillSpans(DrawablePtr pDrawable, GCPtr pGC,
79706f2543Smrg		  int nInit, DDXPointPtr pptInit, int *pwidthInit,
80706f2543Smrg		  int fSorted)
81706f2543Smrg{
82706f2543Smrg    /* Error -- this should never happen! */
83706f2543Smrg}
84706f2543Smrg
85706f2543Smrg/** Set spans -- this function should never be called. */
86706f2543Smrgvoid dmxSetSpans(DrawablePtr pDrawable, GCPtr pGC,
87706f2543Smrg		 char *psrc, DDXPointPtr ppt, int *pwidth, int nspans,
88706f2543Smrg		 int fSorted)
89706f2543Smrg{
90706f2543Smrg    /* Error -- this should never happen! */
91706f2543Smrg}
92706f2543Smrg
93706f2543Smrg/** Transfer \a pBits image to back-end server associated with \a
94706f2543Smrg *  pDrawable's screen.  If primitive subdivision optimization is
95706f2543Smrg *  enabled, then only transfer the sections of \a pBits that are
96706f2543Smrg *  visible (i.e., not-clipped) to the back-end server. */
97706f2543Smrgvoid dmxPutImage(DrawablePtr pDrawable, GCPtr pGC,
98706f2543Smrg		 int depth, int x, int y, int w, int h,
99706f2543Smrg		 int leftPad, int format, char *pBits)
100706f2543Smrg{
101706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
102706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
103706f2543Smrg    XImage        *img;
104706f2543Smrg
105706f2543Smrg    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
106706f2543Smrg
107706f2543Smrg    img = XCreateImage(dmxScreen->beDisplay,
108706f2543Smrg		       dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
109706f2543Smrg		       depth, format, leftPad, pBits, w, h,
110706f2543Smrg		       BitmapPad(dmxScreen->beDisplay),
111706f2543Smrg		       (format == ZPixmap) ?
112706f2543Smrg		       PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad));
113706f2543Smrg
114706f2543Smrg    if (img) {
115706f2543Smrg	Drawable draw;
116706f2543Smrg
117706f2543Smrg	DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
118706f2543Smrg
119706f2543Smrg	if (dmxSubdividePrimitives && pGC->pCompositeClip) {
120706f2543Smrg	    RegionPtr  pSubImages;
121706f2543Smrg	    RegionPtr  pClip;
122706f2543Smrg	    BoxRec     box;
123706f2543Smrg	    BoxPtr     pBox;
124706f2543Smrg	    int        nBox;
125706f2543Smrg
126706f2543Smrg	    box.x1 = x;
127706f2543Smrg	    box.y1 = y;
128706f2543Smrg	    box.x2 = x + w;
129706f2543Smrg	    box.y2 = y + h;
130706f2543Smrg	    pSubImages = RegionCreate(&box, 1);
131706f2543Smrg
132706f2543Smrg	    pClip = RegionCreate(NullBox, 1);
133706f2543Smrg	    RegionCopy(pClip, pGC->pCompositeClip);
134706f2543Smrg	    RegionTranslate(pClip,
135706f2543Smrg			     -pDrawable->x, -pDrawable->y);
136706f2543Smrg	    RegionIntersect(pSubImages, pSubImages, pClip);
137706f2543Smrg
138706f2543Smrg	    nBox = RegionNumRects(pSubImages);
139706f2543Smrg	    pBox = RegionRects(pSubImages);
140706f2543Smrg
141706f2543Smrg	    while (nBox--) {
142706f2543Smrg		XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img,
143706f2543Smrg			  pBox->x1 - box.x1,
144706f2543Smrg			  pBox->y1 - box.y1,
145706f2543Smrg			  pBox->x1,
146706f2543Smrg			  pBox->y1,
147706f2543Smrg			  pBox->x2 - pBox->x1,
148706f2543Smrg			  pBox->y2 - pBox->y1);
149706f2543Smrg		pBox++;
150706f2543Smrg	    }
151706f2543Smrg            RegionDestroy(pClip);
152706f2543Smrg            RegionDestroy(pSubImages);
153706f2543Smrg	} else {
154706f2543Smrg	    XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc,
155706f2543Smrg		      img, 0, 0, x, y, w, h);
156706f2543Smrg	}
157706f2543Smrg	XFree(img);             /* Use XFree instead of XDestroyImage
158706f2543Smrg                                 * because pBits is passed in from the
159706f2543Smrg                                 * caller. */
160706f2543Smrg
161706f2543Smrg	dmxSync(dmxScreen, FALSE);
162706f2543Smrg    } else {
163706f2543Smrg	/* Error -- this should not happen! */
164706f2543Smrg    }
165706f2543Smrg}
166706f2543Smrg
167706f2543Smrg/** Copy area from \a pSrc drawable to \a pDst drawable on the back-end
168706f2543Smrg *  server associated with \a pSrc drawable's screen.  If the offscreen
169706f2543Smrg *  optimization is enabled, only copy when both \a pSrc and \a pDst are
170706f2543Smrg *  at least partially visible. */
171706f2543SmrgRegionPtr dmxCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
172706f2543Smrg		      int srcx, int srcy, int w, int h, int dstx, int dsty)
173706f2543Smrg{
174706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum];
175706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
176706f2543Smrg    Drawable       srcDraw, dstDraw;
177706f2543Smrg
178706f2543Smrg    if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst))
179706f2543Smrg	return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
180706f2543Smrg				 dstx, dsty, 0L);
181706f2543Smrg
182706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
183706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
184706f2543Smrg
185706f2543Smrg    XCopyArea(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
186706f2543Smrg	      srcx, srcy, w, h, dstx, dsty);
187706f2543Smrg    dmxSync(dmxScreen, FALSE);
188706f2543Smrg
189706f2543Smrg    return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
190706f2543Smrg			     dstx, dsty, 0L);
191706f2543Smrg}
192706f2543Smrg
193706f2543Smrg/** Copy plane number \a bitPlane from \a pSrc drawable to \a pDst
194706f2543Smrg *  drawable on the back-end server associated with \a pSrc drawable's
195706f2543Smrg *  screen.  If the offscreen optimization is enabled, only copy when
196706f2543Smrg *  both \a pSrc and \a pDst are at least partially visible. */
197706f2543SmrgRegionPtr dmxCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
198706f2543Smrg		       int srcx, int srcy, int width, int height,
199706f2543Smrg		       int dstx, int dsty, unsigned long bitPlane)
200706f2543Smrg{
201706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum];
202706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
203706f2543Smrg    Drawable       srcDraw, dstDraw;
204706f2543Smrg
205706f2543Smrg    if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst))
206706f2543Smrg	return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height,
207706f2543Smrg				 dstx, dsty, bitPlane);
208706f2543Smrg
209706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
210706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
211706f2543Smrg
212706f2543Smrg    XCopyPlane(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
213706f2543Smrg	       srcx, srcy, width, height, dstx, dsty, bitPlane);
214706f2543Smrg    dmxSync(dmxScreen, FALSE);
215706f2543Smrg
216706f2543Smrg    return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height,
217706f2543Smrg			     dstx, dsty, bitPlane);
218706f2543Smrg}
219706f2543Smrg
220706f2543Smrg/** Render list of points, \a pptInit in \a pDrawable on the back-end
221706f2543Smrg *  server associated with \a pDrawable's screen.  If the offscreen
222706f2543Smrg *  optimization is enabled, only draw when \a pDrawable is at least
223706f2543Smrg *  partially visible. */
224706f2543Smrgvoid dmxPolyPoint(DrawablePtr pDrawable, GCPtr pGC,
225706f2543Smrg		  int mode, int npt, DDXPointPtr pptInit)
226706f2543Smrg{
227706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
228706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
229706f2543Smrg    Drawable       draw;
230706f2543Smrg
231706f2543Smrg    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
232706f2543Smrg
233706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
234706f2543Smrg
235706f2543Smrg    XDrawPoints(dmxScreen->beDisplay, draw, pGCPriv->gc,
236706f2543Smrg		(XPoint *)pptInit, npt, mode);
237706f2543Smrg    dmxSync(dmxScreen, FALSE);
238706f2543Smrg}
239706f2543Smrg
240706f2543Smrg/** Render list of connected lines, \a pptInit in \a pDrawable on the
241706f2543Smrg *  back-end server associated with \a pDrawable's screen.  If the
242706f2543Smrg *  offscreen optimization is enabled, only draw when \a pDrawable is at
243706f2543Smrg *  least partially visible. */
244706f2543Smrgvoid dmxPolylines(DrawablePtr pDrawable, GCPtr pGC,
245706f2543Smrg		  int mode, int npt, DDXPointPtr pptInit)
246706f2543Smrg{
247706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
248706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
249706f2543Smrg    Drawable       draw;
250706f2543Smrg
251706f2543Smrg    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
252706f2543Smrg
253706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
254706f2543Smrg
255706f2543Smrg    XDrawLines(dmxScreen->beDisplay, draw, pGCPriv->gc,
256706f2543Smrg	       (XPoint *)pptInit, npt, mode);
257706f2543Smrg    dmxSync(dmxScreen, FALSE);
258706f2543Smrg}
259706f2543Smrg
260706f2543Smrg/** Render list of disjoint segments, \a pSegs in \a pDrawable on the
261706f2543Smrg *  back-end server associated with \a pDrawable's screen.  If the
262706f2543Smrg *  offscreen optimization is enabled, only draw when \a pDrawable is at
263706f2543Smrg *  least partially visible. */
264706f2543Smrgvoid dmxPolySegment(DrawablePtr pDrawable, GCPtr pGC,
265706f2543Smrg		    int nseg, xSegment *pSegs)
266706f2543Smrg{
267706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
268706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
269706f2543Smrg    Drawable       draw;
270706f2543Smrg
271706f2543Smrg    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
272706f2543Smrg
273706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
274706f2543Smrg
275706f2543Smrg    XDrawSegments(dmxScreen->beDisplay, draw, pGCPriv->gc,
276706f2543Smrg		  (XSegment *)pSegs, nseg);
277706f2543Smrg    dmxSync(dmxScreen, FALSE);
278706f2543Smrg}
279706f2543Smrg
280706f2543Smrg/** Render list of rectangle outlines, \a pRects in \a pDrawable on the
281706f2543Smrg *  back-end server associated with \a pDrawable's screen.  If the
282706f2543Smrg *  offscreen optimization is enabled, only draw when \a pDrawable is at
283706f2543Smrg *  least partially visible. */
284706f2543Smrgvoid dmxPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
285706f2543Smrg		      int nrects, xRectangle *pRects)
286706f2543Smrg{
287706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
288706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
289706f2543Smrg    Drawable       draw;
290706f2543Smrg
291706f2543Smrg    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
292706f2543Smrg
293706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
294706f2543Smrg
295706f2543Smrg    XDrawRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
296706f2543Smrg		    (XRectangle *)pRects, nrects);
297706f2543Smrg
298706f2543Smrg    dmxSync(dmxScreen, FALSE);
299706f2543Smrg}
300706f2543Smrg
301706f2543Smrg/** Render list of arc outlines, \a parcs in \a pDrawable on the
302706f2543Smrg *  back-end server associated with \a pDrawable's screen.  If the
303706f2543Smrg *  offscreen optimization is enabled, only draw when \a pDrawable is at
304706f2543Smrg *  least partially visible. */
305706f2543Smrgvoid dmxPolyArc(DrawablePtr pDrawable, GCPtr pGC,
306706f2543Smrg		int narcs, xArc *parcs)
307706f2543Smrg{
308706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
309706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
310706f2543Smrg    Drawable       draw;
311706f2543Smrg
312706f2543Smrg    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
313706f2543Smrg
314706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
315706f2543Smrg
316706f2543Smrg    XDrawArcs(dmxScreen->beDisplay, draw, pGCPriv->gc,
317706f2543Smrg	      (XArc *)parcs, narcs);
318706f2543Smrg    dmxSync(dmxScreen, FALSE);
319706f2543Smrg}
320706f2543Smrg
321706f2543Smrg/** Render a filled polygons in \a pDrawable on the back-end server
322706f2543Smrg *  associated with \a pDrawable's screen.  If the offscreen
323706f2543Smrg *  optimization is enabled, only draw when \a pDrawable is at least
324706f2543Smrg *  partially visible. */
325706f2543Smrgvoid dmxFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
326706f2543Smrg		    int shape, int mode, int count, DDXPointPtr pPts)
327706f2543Smrg{
328706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
329706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
330706f2543Smrg    Drawable       draw;
331706f2543Smrg
332706f2543Smrg    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
333706f2543Smrg
334706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
335706f2543Smrg
336706f2543Smrg    XFillPolygon(dmxScreen->beDisplay, draw, pGCPriv->gc,
337706f2543Smrg		 (XPoint *)pPts, count, shape, mode);
338706f2543Smrg    dmxSync(dmxScreen, FALSE);
339706f2543Smrg}
340706f2543Smrg
341706f2543Smrg/** Render list of filled rectangles, \a prectInit in \a pDrawable on
342706f2543Smrg *  the back-end server associated with \a pDrawable's screen.  If the
343706f2543Smrg *  offscreen optimization is enabled, only draw when \a pDrawable is at
344706f2543Smrg *  least partially visible. */
345706f2543Smrgvoid dmxPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
346706f2543Smrg		     int nrectFill, xRectangle *prectInit)
347706f2543Smrg{
348706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
349706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
350706f2543Smrg    Drawable       draw;
351706f2543Smrg
352706f2543Smrg    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
353706f2543Smrg
354706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
355706f2543Smrg
356706f2543Smrg    XFillRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
357706f2543Smrg		    (XRectangle *)prectInit, nrectFill);
358706f2543Smrg    dmxSync(dmxScreen, FALSE);
359706f2543Smrg}
360706f2543Smrg
361706f2543Smrg/** Render list of filled arcs, \a parcs in \a pDrawable on the back-end
362706f2543Smrg *  server associated with \a pDrawable's screen.  If the offscreen
363706f2543Smrg *  optimization is enabled, only draw when \a pDrawable is at least
364706f2543Smrg *  partially visible. */
365706f2543Smrgvoid dmxPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
366706f2543Smrg		    int narcs, xArc *parcs)
367706f2543Smrg{
368706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
369706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
370706f2543Smrg    Drawable       draw;
371706f2543Smrg
372706f2543Smrg    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
373706f2543Smrg
374706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
375706f2543Smrg
376706f2543Smrg    XFillArcs(dmxScreen->beDisplay, draw, pGCPriv->gc,
377706f2543Smrg	      (XArc *)parcs, narcs);
378706f2543Smrg    dmxSync(dmxScreen, FALSE);
379706f2543Smrg}
380706f2543Smrg
381706f2543Smrg/** Render string of 8-bit \a chars (foreground only) in \a pDrawable on
382706f2543Smrg *  the back-end server associated with \a pDrawable's screen.  If the
383706f2543Smrg *  offscreen optimization is enabled, only draw when \a pDrawable is at
384706f2543Smrg *  least partially visible. */
385706f2543Smrgint dmxPolyText8(DrawablePtr pDrawable, GCPtr pGC,
386706f2543Smrg		 int x, int y, int count, char *chars)
387706f2543Smrg{
388706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
389706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
390706f2543Smrg    unsigned long  n, i;
391706f2543Smrg    int            w;
392706f2543Smrg    CharInfoPtr    charinfo[255];
393706f2543Smrg    Drawable       draw;
394706f2543Smrg
395706f2543Smrg    GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
396706f2543Smrg	      Linear8Bit, &n, charinfo);
397706f2543Smrg
398706f2543Smrg    /* Calculate text width */
399706f2543Smrg    w = 0;
400706f2543Smrg    for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
401706f2543Smrg
402706f2543Smrg    if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
403706f2543Smrg	DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
404706f2543Smrg
405706f2543Smrg	XDrawString(dmxScreen->beDisplay, draw, pGCPriv->gc,
406706f2543Smrg		    x, y, chars, count);
407706f2543Smrg	dmxSync(dmxScreen, FALSE);
408706f2543Smrg    }
409706f2543Smrg
410706f2543Smrg    return x+w;
411706f2543Smrg}
412706f2543Smrg
413706f2543Smrg/** Render string of 16-bit \a chars (foreground only) in \a pDrawable
414706f2543Smrg *  on the back-end server associated with \a pDrawable's screen.  If
415706f2543Smrg *  the offscreen optimization is enabled, only draw when \a pDrawable
416706f2543Smrg *  is at least partially visible. */
417706f2543Smrgint dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC,
418706f2543Smrg		  int x, int y, int count, unsigned short *chars)
419706f2543Smrg{
420706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
421706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
422706f2543Smrg    unsigned long  n, i;
423706f2543Smrg    int            w;
424706f2543Smrg    CharInfoPtr    charinfo[255];
425706f2543Smrg    Drawable       draw;
426706f2543Smrg
427706f2543Smrg    GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
428706f2543Smrg	      (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
429706f2543Smrg	      &n, charinfo);
430706f2543Smrg
431706f2543Smrg    /* Calculate text width */
432706f2543Smrg    w = 0;
433706f2543Smrg    for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
434706f2543Smrg
435706f2543Smrg    if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
436706f2543Smrg	DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
437706f2543Smrg
438706f2543Smrg	XDrawString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
439706f2543Smrg		      x, y, (XChar2b *)chars, count);
440706f2543Smrg	dmxSync(dmxScreen, FALSE);
441706f2543Smrg    }
442706f2543Smrg
443706f2543Smrg    return x+w;
444706f2543Smrg}
445706f2543Smrg
446706f2543Smrg/** Render string of 8-bit \a chars (both foreground and background) in
447706f2543Smrg *  \a pDrawable on the back-end server associated with \a pDrawable's
448706f2543Smrg *  screen.  If the offscreen optimization is enabled, only draw when \a
449706f2543Smrg *  pDrawable is at least partially visible. */
450706f2543Smrgvoid dmxImageText8(DrawablePtr pDrawable, GCPtr pGC,
451706f2543Smrg		   int x, int y, int count, char *chars)
452706f2543Smrg{
453706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
454706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
455706f2543Smrg    Drawable       draw;
456706f2543Smrg
457706f2543Smrg    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
458706f2543Smrg
459706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
460706f2543Smrg
461706f2543Smrg    XDrawImageString(dmxScreen->beDisplay, draw, pGCPriv->gc,
462706f2543Smrg		     x, y, chars, count);
463706f2543Smrg    dmxSync(dmxScreen, FALSE);
464706f2543Smrg}
465706f2543Smrg
466706f2543Smrg/** Render string of 16-bit \a chars (both foreground and background) in
467706f2543Smrg *  \a pDrawable on the back-end server associated with \a pDrawable's
468706f2543Smrg *  screen.  If the offscreen optimization is enabled, only draw when \a
469706f2543Smrg *  pDrawable is at least partially visible. */
470706f2543Smrgvoid dmxImageText16(DrawablePtr pDrawable, GCPtr pGC,
471706f2543Smrg		    int x, int y, int count, unsigned short *chars)
472706f2543Smrg{
473706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
474706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
475706f2543Smrg    Drawable       draw;
476706f2543Smrg
477706f2543Smrg    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
478706f2543Smrg
479706f2543Smrg    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
480706f2543Smrg
481706f2543Smrg    XDrawImageString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
482706f2543Smrg		       x, y, (XChar2b *)chars, count);
483706f2543Smrg    dmxSync(dmxScreen, FALSE);
484706f2543Smrg}
485706f2543Smrg
486706f2543Smrg/** Image Glyph Blt -- this function should never be called. */
487706f2543Smrgvoid dmxImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
488706f2543Smrg		      int x, int y, unsigned int nglyph,
489706f2543Smrg		      CharInfoPtr *ppci, pointer pglyphBase)
490706f2543Smrg{
491706f2543Smrg    /* Error -- this should never happen! */
492706f2543Smrg}
493706f2543Smrg
494706f2543Smrg/** Poly Glyph Blt -- this function should never be called. */
495706f2543Smrgvoid dmxPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
496706f2543Smrg		     int x, int y, unsigned int nglyph,
497706f2543Smrg		     CharInfoPtr *ppci, pointer pglyphBase)
498706f2543Smrg{
499706f2543Smrg    /* Error -- this should never happen! */
500706f2543Smrg}
501706f2543Smrg
502706f2543Smrg/** Push Pixels -- this function should never be called. */
503706f2543Smrgvoid dmxPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
504706f2543Smrg		   int w, int h, int x, int y)
505706f2543Smrg{
506706f2543Smrg    /* Error -- this should never happen! */
507706f2543Smrg}
508706f2543Smrg
509706f2543Smrg/**********************************************************************
510706f2543Smrg * Miscellaneous drawing commands
511706f2543Smrg */
512706f2543Smrg
513706f2543Smrg/** When Xinerama is active, the client pixmaps are always obtained from
514706f2543Smrg * screen 0.  When screen 0 is detached, the pixmaps must be obtained
515706f2543Smrg * from any other screen that is not detached.  Usually, this is screen
516706f2543Smrg * 1. */
517706f2543Smrgstatic DMXScreenInfo *dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw)
518706f2543Smrg{
519706f2543Smrg#ifdef PANORAMIX
520706f2543Smrg    PanoramiXRes  *pXinPix;
521706f2543Smrg    int           i;
522706f2543Smrg    DMXScreenInfo *dmxScreen;
523706f2543Smrg
524706f2543Smrg    if (noPanoramiXExtension)               return NULL;
525706f2543Smrg    if (pDrawable->type != DRAWABLE_PIXMAP) return NULL;
526706f2543Smrg
527706f2543Smrg    if (Success != dixLookupResourceByType((pointer*) &pXinPix,
528706f2543Smrg					   pDrawable->id, XRT_PIXMAP,
529706f2543Smrg					   NullClient, DixUnknownAccess))
530706f2543Smrg        return NULL;
531706f2543Smrg
532706f2543Smrg    for (i = 1; i < PanoramiXNumScreens; i++) {
533706f2543Smrg        dmxScreen = &dmxScreens[i];
534706f2543Smrg        if (dmxScreen->beDisplay) {
535706f2543Smrg            PixmapPtr     pSrc;
536706f2543Smrg            dmxPixPrivPtr pSrcPriv;
537706f2543Smrg
538706f2543Smrg            dixLookupResourceByType((pointer*) &pSrc, pXinPix->info[i].id,
539706f2543Smrg				    RT_PIXMAP, NullClient, DixUnknownAccess);
540706f2543Smrg            pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc);
541706f2543Smrg            if (pSrcPriv->pixmap) {
542706f2543Smrg                *draw = pSrcPriv->pixmap;
543706f2543Smrg                return dmxScreen;
544706f2543Smrg            }
545706f2543Smrg        }
546706f2543Smrg    }
547706f2543Smrg#endif
548706f2543Smrg    return NULL;
549706f2543Smrg}
550706f2543Smrg
551706f2543Smrg/** Get an image from the back-end server associated with \a pDrawable's
552706f2543Smrg *  screen.  If \a pDrawable is a window, it must be viewable to get an
553706f2543Smrg *  image from it.  If it is not viewable, then get the image from the
554706f2543Smrg *  first ancestor of \a pDrawable that is viewable.  If no viewable
555706f2543Smrg *  ancestor is found, then simply return without getting an image.  */
556706f2543Smrgvoid dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
557706f2543Smrg		 unsigned int format, unsigned long planeMask, char *pdstLine)
558706f2543Smrg{
559706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
560706f2543Smrg    XImage        *img;
561706f2543Smrg    Drawable       draw;
562706f2543Smrg
563706f2543Smrg    /* Cannot get image from unviewable window */
564706f2543Smrg    if (pDrawable->type == DRAWABLE_WINDOW) {
565706f2543Smrg	WindowPtr pWindow = (WindowPtr)pDrawable;
566706f2543Smrg	if (!pWindow->viewable) {
567706f2543Smrg	    while (!pWindow->viewable && pWindow->parent) {
568706f2543Smrg		sx += pWindow->origin.x - wBorderWidth(pWindow);
569706f2543Smrg		sx += pWindow->origin.y - wBorderWidth(pWindow);
570706f2543Smrg		pWindow = pWindow->parent;
571706f2543Smrg	    }
572706f2543Smrg	    if (!pWindow->viewable) {
573706f2543Smrg		return;
574706f2543Smrg	    }
575706f2543Smrg	}
576706f2543Smrg	DMX_GCOPS_SET_DRAWABLE(&pWindow->drawable, draw);
577706f2543Smrg	if (DMX_GCOPS_OFFSCREEN(&pWindow->drawable))
578706f2543Smrg	    return;
579706f2543Smrg    } else {
580706f2543Smrg	DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
581706f2543Smrg	if (DMX_GCOPS_OFFSCREEN(pDrawable)) {
582706f2543Smrg            /* Try to find the pixmap on a non-detached Xinerama screen */
583706f2543Smrg            dmxScreen = dmxFindAlternatePixmap(pDrawable, &draw);
584706f2543Smrg            if (!dmxScreen) return;
585706f2543Smrg        }
586706f2543Smrg    }
587706f2543Smrg
588706f2543Smrg    img = XGetImage(dmxScreen->beDisplay, draw,
589706f2543Smrg		    sx, sy, w, h, planeMask, format);
590706f2543Smrg    if (img) {
591706f2543Smrg	int len = img->bytes_per_line * img->height;
592706f2543Smrg	memmove(pdstLine, img->data, len);
593706f2543Smrg	XDestroyImage(img);
594706f2543Smrg    }
595706f2543Smrg
596706f2543Smrg    dmxSync(dmxScreen, FALSE);
597706f2543Smrg}
598706f2543Smrg
599706f2543Smrg/** Get Spans -- this function should never be called. */
600706f2543Smrgvoid dmxGetSpans(DrawablePtr pDrawable, int wMax,
601706f2543Smrg		 DDXPointPtr ppt, int *pwidth, int nspans,
602706f2543Smrg		 char *pdstStart)
603706f2543Smrg{
604706f2543Smrg    /* Error -- this should never happen! */
605706f2543Smrg}
606