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