~brandontschaefer/+junk/break-x

« back to all changes in this revision

Viewing changes to hw/dmx/dmxgcops.c

  • Committer: Brandon Schaefer
  • Date: 2014-09-30 19:38:40 UTC
  • Revision ID: brandon.schaefer@canonical.com-20140930193840-a65z6qk8ze02cgsb
* Init commit to back this up

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
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
 
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
 
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
 
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, 0L);
 
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, 0L);
 
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
 
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, bitPlane);
 
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, bitPlane);
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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 *
 
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
 
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
 
633
dmxGetSpans(DrawablePtr pDrawable, int wMax,
 
634
            DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart)
 
635
{
 
636
    /* Error -- this should never happen! */
 
637
}