1 /*
2 * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
3 *
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation on the rights to use, copy, modify, merge,
10 * publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27
28 /*
29 * Authors:
30 * Kevin E. Martin <kem@redhat.com>
31 *
32 */
33
34 /** \file
35 * This file provides support for GC operations. */
36
37 #ifdef HAVE_DMX_CONFIG_H
38 #include <dmx-config.h>
39 #endif
40
41 #include "dmx.h"
42 #include "dmxsync.h"
43 #include "dmxgc.h"
44 #include "dmxgcops.h"
45 #include "dmxwindow.h"
46 #include "dmxpixmap.h"
47
48 #include "mi.h"
49 #include "gcstruct.h"
50 #include "pixmapstr.h"
51 #include "dixfontstr.h"
52
53 #ifdef PANORAMIX
54 #include "panoramiXsrv.h"
55 #endif
56
57 #define DMX_GCOPS_SET_DRAWABLE(_pDraw, _draw) \
58 do { \
59 if ((_pDraw)->type == DRAWABLE_WINDOW) { \
60 dmxWinPrivPtr pWinPriv = \
61 DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw)); \
62 (_draw) = (Drawable)pWinPriv->window; \
63 } else { \
64 dmxPixPrivPtr pPixPriv = \
65 DMX_GET_PIXMAP_PRIV((PixmapPtr)(_pDraw)); \
66 (_draw) = (Drawable)pPixPriv->pixmap; \
67 } \
68 } while (0)
69
70 #define DMX_GCOPS_OFFSCREEN(_pDraw) \
71 (!dmxScreens[(_pDraw)->pScreen->myNum].beDisplay || \
72 (dmxOffScreenOpt && \
73 (_pDraw)->type == DRAWABLE_WINDOW && \
74 (DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->offscreen || \
75 !DMX_GET_WINDOW_PRIV((WindowPtr)(_pDraw))->window)))
76
77 /** Fill spans -- this function should never be called. */
78 void
dmxFillSpans(DrawablePtr pDrawable,GCPtr pGC,int nInit,DDXPointPtr pptInit,int * pwidthInit,int fSorted)79 dmxFillSpans(DrawablePtr pDrawable, GCPtr pGC,
80 int nInit, DDXPointPtr pptInit, int *pwidthInit, int fSorted)
81 {
82 /* Error -- this should never happen! */
83 }
84
85 /** Set spans -- this function should never be called. */
86 void
dmxSetSpans(DrawablePtr pDrawable,GCPtr pGC,char * psrc,DDXPointPtr ppt,int * pwidth,int nspans,int fSorted)87 dmxSetSpans(DrawablePtr pDrawable, GCPtr pGC,
88 char *psrc, DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
89 {
90 /* Error -- this should never happen! */
91 }
92
93 /** Transfer \a pBits image to back-end server associated with \a
94 * pDrawable's screen. If primitive subdivision optimization is
95 * enabled, then only transfer the sections of \a pBits that are
96 * visible (i.e., not-clipped) to the back-end server. */
97 void
dmxPutImage(DrawablePtr pDrawable,GCPtr pGC,int depth,int x,int y,int w,int h,int leftPad,int format,char * pBits)98 dmxPutImage(DrawablePtr pDrawable, GCPtr pGC,
99 int depth, int x, int y, int w, int h,
100 int leftPad, int format, char *pBits)
101 {
102 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
103 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
104 XImage *img;
105
106 if (DMX_GCOPS_OFFSCREEN(pDrawable))
107 return;
108
109 img = XCreateImage(dmxScreen->beDisplay,
110 dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
111 depth, format, leftPad, pBits, w, h,
112 BitmapPad(dmxScreen->beDisplay),
113 (format == ZPixmap) ?
114 PixmapBytePad(w, depth) : BitmapBytePad(w + leftPad));
115
116 if (img) {
117 Drawable draw;
118
119 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
120
121 if (dmxSubdividePrimitives && pGC->pCompositeClip) {
122 RegionPtr pSubImages;
123 RegionPtr pClip;
124 BoxRec box;
125 BoxPtr pBox;
126 int nBox;
127
128 box.x1 = x;
129 box.y1 = y;
130 box.x2 = x + w;
131 box.y2 = y + h;
132 pSubImages = RegionCreate(&box, 1);
133
134 pClip = RegionCreate(NullBox, 1);
135 RegionCopy(pClip, pGC->pCompositeClip);
136 RegionTranslate(pClip, -pDrawable->x, -pDrawable->y);
137 RegionIntersect(pSubImages, pSubImages, pClip);
138
139 nBox = RegionNumRects(pSubImages);
140 pBox = RegionRects(pSubImages);
141
142 while (nBox--) {
143 XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img,
144 pBox->x1 - box.x1,
145 pBox->y1 - box.y1,
146 pBox->x1,
147 pBox->y1, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
148 pBox++;
149 }
150 RegionDestroy(pClip);
151 RegionDestroy(pSubImages);
152 }
153 else {
154 XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc,
155 img, 0, 0, x, y, w, h);
156 }
157 XFree(img); /* Use XFree instead of XDestroyImage
158 * because pBits is passed in from the
159 * caller. */
160
161 dmxSync(dmxScreen, FALSE);
162 }
163 else {
164 /* Error -- this should not happen! */
165 }
166 }
167
168 /** Copy area from \a pSrc drawable to \a pDst drawable on the back-end
169 * server associated with \a pSrc drawable's screen. If the offscreen
170 * optimization is enabled, only copy when both \a pSrc and \a pDst are
171 * at least partially visible. */
172 RegionPtr
dmxCopyArea(DrawablePtr pSrc,DrawablePtr pDst,GCPtr pGC,int srcx,int srcy,int w,int h,int dstx,int dsty)173 dmxCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
174 int srcx, int srcy, int w, int h, int dstx, int dsty)
175 {
176 DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum];
177 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
178 Drawable srcDraw, dstDraw;
179
180 if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst))
181 return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
182 dstx, dsty);
183
184 DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
185 DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
186
187 XCopyArea(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
188 srcx, srcy, w, h, dstx, dsty);
189 dmxSync(dmxScreen, FALSE);
190
191 return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
192 }
193
194 /** Copy plane number \a bitPlane from \a pSrc drawable to \a pDst
195 * drawable on the back-end server associated with \a pSrc drawable's
196 * screen. If the offscreen optimization is enabled, only copy when
197 * both \a pSrc and \a pDst are at least partially visible. */
198 RegionPtr
dmxCopyPlane(DrawablePtr pSrc,DrawablePtr pDst,GCPtr pGC,int srcx,int srcy,int width,int height,int dstx,int dsty,unsigned long bitPlane)199 dmxCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
200 int srcx, int srcy, int width, int height,
201 int dstx, int dsty, unsigned long bitPlane)
202 {
203 DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum];
204 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
205 Drawable srcDraw, dstDraw;
206
207 if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst))
208 return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height,
209 dstx, dsty);
210
211 DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
212 DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
213
214 XCopyPlane(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
215 srcx, srcy, width, height, dstx, dsty, bitPlane);
216 dmxSync(dmxScreen, FALSE);
217
218 return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height,
219 dstx, dsty);
220 }
221
222 /** Render list of points, \a pptInit in \a pDrawable on the back-end
223 * server associated with \a pDrawable's screen. If the offscreen
224 * optimization is enabled, only draw when \a pDrawable is at least
225 * partially visible. */
226 void
dmxPolyPoint(DrawablePtr pDrawable,GCPtr pGC,int mode,int npt,DDXPointPtr pptInit)227 dmxPolyPoint(DrawablePtr pDrawable, GCPtr pGC,
228 int mode, int npt, DDXPointPtr pptInit)
229 {
230 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
231 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
232 Drawable draw;
233
234 if (DMX_GCOPS_OFFSCREEN(pDrawable))
235 return;
236
237 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
238
239 XDrawPoints(dmxScreen->beDisplay, draw, pGCPriv->gc,
240 (XPoint *) pptInit, npt, mode);
241 dmxSync(dmxScreen, FALSE);
242 }
243
244 /** Render list of connected lines, \a pptInit in \a pDrawable on the
245 * back-end server associated with \a pDrawable's screen. If the
246 * offscreen optimization is enabled, only draw when \a pDrawable is at
247 * least partially visible. */
248 void
dmxPolylines(DrawablePtr pDrawable,GCPtr pGC,int mode,int npt,DDXPointPtr pptInit)249 dmxPolylines(DrawablePtr pDrawable, GCPtr pGC,
250 int mode, int npt, DDXPointPtr pptInit)
251 {
252 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
253 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
254 Drawable draw;
255
256 if (DMX_GCOPS_OFFSCREEN(pDrawable))
257 return;
258
259 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
260
261 XDrawLines(dmxScreen->beDisplay, draw, pGCPriv->gc,
262 (XPoint *) pptInit, npt, mode);
263 dmxSync(dmxScreen, FALSE);
264 }
265
266 /** Render list of disjoint segments, \a pSegs in \a pDrawable on the
267 * back-end server associated with \a pDrawable's screen. If the
268 * offscreen optimization is enabled, only draw when \a pDrawable is at
269 * least partially visible. */
270 void
dmxPolySegment(DrawablePtr pDrawable,GCPtr pGC,int nseg,xSegment * pSegs)271 dmxPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSegs)
272 {
273 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
274 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
275 Drawable draw;
276
277 if (DMX_GCOPS_OFFSCREEN(pDrawable))
278 return;
279
280 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
281
282 XDrawSegments(dmxScreen->beDisplay, draw, pGCPriv->gc,
283 (XSegment *) pSegs, nseg);
284 dmxSync(dmxScreen, FALSE);
285 }
286
287 /** Render list of rectangle outlines, \a pRects in \a pDrawable on the
288 * back-end server associated with \a pDrawable's screen. If the
289 * offscreen optimization is enabled, only draw when \a pDrawable is at
290 * least partially visible. */
291 void
dmxPolyRectangle(DrawablePtr pDrawable,GCPtr pGC,int nrects,xRectangle * pRects)292 dmxPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
293 int nrects, xRectangle *pRects)
294 {
295 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
296 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
297 Drawable draw;
298
299 if (DMX_GCOPS_OFFSCREEN(pDrawable))
300 return;
301
302 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
303
304 XDrawRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
305 (XRectangle *) pRects, nrects);
306
307 dmxSync(dmxScreen, FALSE);
308 }
309
310 /** Render list of arc outlines, \a parcs in \a pDrawable on the
311 * back-end server associated with \a pDrawable's screen. If the
312 * offscreen optimization is enabled, only draw when \a pDrawable is at
313 * least partially visible. */
314 void
dmxPolyArc(DrawablePtr pDrawable,GCPtr pGC,int narcs,xArc * parcs)315 dmxPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * parcs)
316 {
317 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
318 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
319 Drawable draw;
320
321 if (DMX_GCOPS_OFFSCREEN(pDrawable))
322 return;
323
324 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
325
326 XDrawArcs(dmxScreen->beDisplay, draw, pGCPriv->gc, (XArc *) parcs, narcs);
327 dmxSync(dmxScreen, FALSE);
328 }
329
330 /** Render a filled polygons in \a pDrawable on the back-end server
331 * associated with \a pDrawable's screen. If the offscreen
332 * optimization is enabled, only draw when \a pDrawable is at least
333 * partially visible. */
334 void
dmxFillPolygon(DrawablePtr pDrawable,GCPtr pGC,int shape,int mode,int count,DDXPointPtr pPts)335 dmxFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
336 int shape, int mode, int count, DDXPointPtr pPts)
337 {
338 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
339 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
340 Drawable draw;
341
342 if (DMX_GCOPS_OFFSCREEN(pDrawable))
343 return;
344
345 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
346
347 XFillPolygon(dmxScreen->beDisplay, draw, pGCPriv->gc,
348 (XPoint *) pPts, count, shape, mode);
349 dmxSync(dmxScreen, FALSE);
350 }
351
352 /** Render list of filled rectangles, \a prectInit in \a pDrawable on
353 * the back-end server associated with \a pDrawable's screen. If the
354 * offscreen optimization is enabled, only draw when \a pDrawable is at
355 * least partially visible. */
356 void
dmxPolyFillRect(DrawablePtr pDrawable,GCPtr pGC,int nrectFill,xRectangle * prectInit)357 dmxPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
358 int nrectFill, xRectangle *prectInit)
359 {
360 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
361 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
362 Drawable draw;
363
364 if (DMX_GCOPS_OFFSCREEN(pDrawable))
365 return;
366
367 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
368
369 XFillRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
370 (XRectangle *) prectInit, nrectFill);
371 dmxSync(dmxScreen, FALSE);
372 }
373
374 /** Render list of filled arcs, \a parcs in \a pDrawable on the back-end
375 * server associated with \a pDrawable's screen. If the offscreen
376 * optimization is enabled, only draw when \a pDrawable is at least
377 * partially visible. */
378 void
dmxPolyFillArc(DrawablePtr pDrawable,GCPtr pGC,int narcs,xArc * parcs)379 dmxPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * parcs)
380 {
381 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
382 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
383 Drawable draw;
384
385 if (DMX_GCOPS_OFFSCREEN(pDrawable))
386 return;
387
388 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
389
390 XFillArcs(dmxScreen->beDisplay, draw, pGCPriv->gc, (XArc *) parcs, narcs);
391 dmxSync(dmxScreen, FALSE);
392 }
393
394 /** Render string of 8-bit \a chars (foreground only) in \a pDrawable on
395 * the back-end server associated with \a pDrawable's screen. If the
396 * offscreen optimization is enabled, only draw when \a pDrawable is at
397 * least partially visible. */
398 int
dmxPolyText8(DrawablePtr pDrawable,GCPtr pGC,int x,int y,int count,char * chars)399 dmxPolyText8(DrawablePtr pDrawable, GCPtr pGC,
400 int x, int y, int count, char *chars)
401 {
402 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
403 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
404 unsigned long n, i;
405 int w;
406 CharInfoPtr charinfo[255];
407 Drawable draw;
408
409 GetGlyphs(pGC->font, (unsigned long) count, (unsigned char *) chars,
410 Linear8Bit, &n, charinfo);
411
412 /* Calculate text width */
413 w = 0;
414 for (i = 0; i < n; i++)
415 w += charinfo[i]->metrics.characterWidth;
416
417 if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
418 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
419
420 XDrawString(dmxScreen->beDisplay, draw, pGCPriv->gc,
421 x, y, chars, count);
422 dmxSync(dmxScreen, FALSE);
423 }
424
425 return x + w;
426 }
427
428 /** Render string of 16-bit \a chars (foreground only) in \a pDrawable
429 * on the back-end server associated with \a pDrawable's screen. If
430 * the offscreen optimization is enabled, only draw when \a pDrawable
431 * is at least partially visible. */
432 int
dmxPolyText16(DrawablePtr pDrawable,GCPtr pGC,int x,int y,int count,unsigned short * chars)433 dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC,
434 int x, int y, int count, unsigned short *chars)
435 {
436 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
437 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
438 unsigned long n, i;
439 int w;
440 CharInfoPtr charinfo[255];
441 Drawable draw;
442
443 GetGlyphs(pGC->font, (unsigned long) count, (unsigned char *) chars,
444 (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
445 &n, charinfo);
446
447 /* Calculate text width */
448 w = 0;
449 for (i = 0; i < n; i++)
450 w += charinfo[i]->metrics.characterWidth;
451
452 if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
453 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
454
455 XDrawString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
456 x, y, (XChar2b *) chars, count);
457 dmxSync(dmxScreen, FALSE);
458 }
459
460 return x + w;
461 }
462
463 /** Render string of 8-bit \a chars (both foreground and background) in
464 * \a pDrawable on the back-end server associated with \a pDrawable's
465 * screen. If the offscreen optimization is enabled, only draw when \a
466 * pDrawable is at least partially visible. */
467 void
dmxImageText8(DrawablePtr pDrawable,GCPtr pGC,int x,int y,int count,char * chars)468 dmxImageText8(DrawablePtr pDrawable, GCPtr pGC,
469 int x, int y, int count, char *chars)
470 {
471 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
472 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
473 Drawable draw;
474
475 if (DMX_GCOPS_OFFSCREEN(pDrawable))
476 return;
477
478 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
479
480 XDrawImageString(dmxScreen->beDisplay, draw, pGCPriv->gc,
481 x, y, chars, count);
482 dmxSync(dmxScreen, FALSE);
483 }
484
485 /** Render string of 16-bit \a chars (both foreground and background) in
486 * \a pDrawable on the back-end server associated with \a pDrawable's
487 * screen. If the offscreen optimization is enabled, only draw when \a
488 * pDrawable is at least partially visible. */
489 void
dmxImageText16(DrawablePtr pDrawable,GCPtr pGC,int x,int y,int count,unsigned short * chars)490 dmxImageText16(DrawablePtr pDrawable, GCPtr pGC,
491 int x, int y, int count, unsigned short *chars)
492 {
493 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
494 dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
495 Drawable draw;
496
497 if (DMX_GCOPS_OFFSCREEN(pDrawable))
498 return;
499
500 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
501
502 XDrawImageString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
503 x, y, (XChar2b *) chars, count);
504 dmxSync(dmxScreen, FALSE);
505 }
506
507 /** Image Glyph Blt -- this function should never be called. */
508 void
dmxImageGlyphBlt(DrawablePtr pDrawable,GCPtr pGC,int x,int y,unsigned int nglyph,CharInfoPtr * ppci,void * pglyphBase)509 dmxImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
510 int x, int y, unsigned int nglyph,
511 CharInfoPtr * ppci, void *pglyphBase)
512 {
513 /* Error -- this should never happen! */
514 }
515
516 /** Poly Glyph Blt -- this function should never be called. */
517 void
dmxPolyGlyphBlt(DrawablePtr pDrawable,GCPtr pGC,int x,int y,unsigned int nglyph,CharInfoPtr * ppci,void * pglyphBase)518 dmxPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
519 int x, int y, unsigned int nglyph,
520 CharInfoPtr * ppci, void *pglyphBase)
521 {
522 /* Error -- this should never happen! */
523 }
524
525 /** Push Pixels -- this function should never be called. */
526 void
dmxPushPixels(GCPtr pGC,PixmapPtr pBitMap,DrawablePtr pDst,int w,int h,int x,int y)527 dmxPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
528 int w, int h, int x, int y)
529 {
530 /* Error -- this should never happen! */
531 }
532
533 /**********************************************************************
534 * Miscellaneous drawing commands
535 */
536
537 /** When Xinerama is active, the client pixmaps are always obtained from
538 * screen 0. When screen 0 is detached, the pixmaps must be obtained
539 * from any other screen that is not detached. Usually, this is screen
540 * 1. */
541 static DMXScreenInfo *
dmxFindAlternatePixmap(DrawablePtr pDrawable,XID * draw)542 dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw)
543 {
544 #ifdef PANORAMIX
545 PanoramiXRes *pXinPix;
546 int i;
547 DMXScreenInfo *dmxScreen;
548
549 if (noPanoramiXExtension)
550 return NULL;
551 if (pDrawable->type != DRAWABLE_PIXMAP)
552 return NULL;
553
554 if (Success != dixLookupResourceByType((void **) &pXinPix,
555 pDrawable->id, XRT_PIXMAP,
556 NullClient, DixUnknownAccess))
557 return NULL;
558
559 FOR_NSCREENS_FORWARD_SKIP(i) {
560 dmxScreen = &dmxScreens[i];
561 if (dmxScreen->beDisplay) {
562 PixmapPtr pSrc;
563 dmxPixPrivPtr pSrcPriv;
564
565 dixLookupResourceByType((void **) &pSrc, pXinPix->info[i].id,
566 RT_PIXMAP, NullClient, DixUnknownAccess);
567 pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc);
568 if (pSrcPriv->pixmap) {
569 *draw = pSrcPriv->pixmap;
570 return dmxScreen;
571 }
572 }
573 }
574 #endif
575 return NULL;
576 }
577
578 /** Get an image from the back-end server associated with \a pDrawable's
579 * screen. If \a pDrawable is a window, it must be viewable to get an
580 * image from it. If it is not viewable, then get the image from the
581 * first ancestor of \a pDrawable that is viewable. If no viewable
582 * ancestor is found, then simply return without getting an image. */
583 void
dmxGetImage(DrawablePtr pDrawable,int sx,int sy,int w,int h,unsigned int format,unsigned long planeMask,char * pdstLine)584 dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
585 unsigned int format, unsigned long planeMask, char *pdstLine)
586 {
587 DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
588 XImage *img;
589 Drawable draw;
590
591 /* Cannot get image from unviewable window */
592 if (pDrawable->type == DRAWABLE_WINDOW) {
593 WindowPtr pWindow = (WindowPtr) pDrawable;
594
595 if (!pWindow->viewable) {
596 while (!pWindow->viewable && pWindow->parent) {
597 sx += pWindow->origin.x - wBorderWidth(pWindow);
598 sx += pWindow->origin.y - wBorderWidth(pWindow);
599 pWindow = pWindow->parent;
600 }
601 if (!pWindow->viewable) {
602 return;
603 }
604 }
605 DMX_GCOPS_SET_DRAWABLE(&pWindow->drawable, draw);
606 if (DMX_GCOPS_OFFSCREEN(&pWindow->drawable))
607 return;
608 }
609 else {
610 DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
611 if (DMX_GCOPS_OFFSCREEN(pDrawable)) {
612 /* Try to find the pixmap on a non-detached Xinerama screen */
613 dmxScreen = dmxFindAlternatePixmap(pDrawable, &draw);
614 if (!dmxScreen)
615 return;
616 }
617 }
618
619 img = XGetImage(dmxScreen->beDisplay, draw,
620 sx, sy, w, h, planeMask, format);
621 if (img) {
622 int len = img->bytes_per_line * img->height;
623
624 memmove(pdstLine, img->data, len);
625 XDestroyImage(img);
626 }
627
628 dmxSync(dmxScreen, FALSE);
629 }
630
631 /** Get Spans -- this function should never be called. */
632 void
dmxGetSpans(DrawablePtr pDrawable,int wMax,DDXPointPtr ppt,int * pwidth,int nspans,char * pdstStart)633 dmxGetSpans(DrawablePtr pDrawable, int wMax,
634 DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart)
635 {
636 /* Error -- this should never happen! */
637 }
638