dmxpict.c revision 706f2543
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 * Provide support for the RENDER extension (version 0.8). 36706f2543Smrg */ 37706f2543Smrg 38706f2543Smrg#ifdef HAVE_DMX_CONFIG_H 39706f2543Smrg#include <dmx-config.h> 40706f2543Smrg#endif 41706f2543Smrg 42706f2543Smrg#include "dmx.h" 43706f2543Smrg#include "dmxsync.h" 44706f2543Smrg#include "dmxpict.h" 45706f2543Smrg#include "dmxwindow.h" 46706f2543Smrg#include "dmxpixmap.h" 47706f2543Smrg 48706f2543Smrg#include "fb.h" 49706f2543Smrg#include "pixmapstr.h" 50706f2543Smrg#include "dixstruct.h" 51706f2543Smrg 52706f2543Smrg#include <X11/extensions/render.h> 53706f2543Smrg#include <X11/extensions/renderproto.h> 54706f2543Smrg#include <X11/extensions/Xfixes.h> 55706f2543Smrg#include "picture.h" 56706f2543Smrg#include "picturestr.h" 57706f2543Smrg#include "mipict.h" 58706f2543Smrg#include "fbpict.h" 59706f2543Smrg 60706f2543Smrg 61706f2543Smrgextern int RenderErrBase; 62706f2543Smrgextern int (*ProcRenderVector[RenderNumberRequests])(ClientPtr); 63706f2543Smrg 64706f2543Smrgstatic int (*dmxSaveRenderVector[RenderNumberRequests])(ClientPtr); 65706f2543Smrg 66706f2543Smrg 67706f2543Smrgstatic int dmxProcRenderCreateGlyphSet(ClientPtr client); 68706f2543Smrgstatic int dmxProcRenderFreeGlyphSet(ClientPtr client); 69706f2543Smrgstatic int dmxProcRenderAddGlyphs(ClientPtr client); 70706f2543Smrgstatic int dmxProcRenderFreeGlyphs(ClientPtr client); 71706f2543Smrgstatic int dmxProcRenderCompositeGlyphs(ClientPtr client); 72706f2543Smrgstatic int dmxProcRenderSetPictureTransform(ClientPtr client); 73706f2543Smrgstatic int dmxProcRenderSetPictureFilter(ClientPtr client); 74706f2543Smrg#if 0 75706f2543Smrg/* FIXME: Not (yet) supported */ 76706f2543Smrgstatic int dmxProcRenderCreateCursor(ClientPtr client); 77706f2543Smrgstatic int dmxProcRenderCreateAnimCursor(ClientPtr client); 78706f2543Smrg#endif 79706f2543Smrg 80706f2543Smrg/** Catch errors that might occur when allocating Glyph Sets. Errors 81706f2543Smrg * are saved in dmxGlyphLastError for later handling. */ 82706f2543Smrgstatic int dmxGlyphLastError; 83706f2543Smrgstatic int dmxGlyphErrorHandler(Display *dpy, XErrorEvent *ev) 84706f2543Smrg{ 85706f2543Smrg dmxGlyphLastError = ev->error_code; 86706f2543Smrg return 0; 87706f2543Smrg} 88706f2543Smrg 89706f2543Smrg 90706f2543Smrg/** Initialize the Proc Vector for the RENDER extension. The functions 91706f2543Smrg * here cannot be handled by the mi layer RENDER hooks either because 92706f2543Smrg * the required information is no longer available when it reaches the 93706f2543Smrg * mi layer or no mi layer hooks exist. This function is called from 94706f2543Smrg * InitOutput() since it should be initialized only once per server 95706f2543Smrg * generation. */ 96706f2543Smrgvoid dmxInitRender(void) 97706f2543Smrg{ 98706f2543Smrg int i; 99706f2543Smrg 100706f2543Smrg for (i = 0; i < RenderNumberRequests; i++) 101706f2543Smrg dmxSaveRenderVector[i] = ProcRenderVector[i]; 102706f2543Smrg 103706f2543Smrg ProcRenderVector[X_RenderCreateGlyphSet] 104706f2543Smrg = dmxProcRenderCreateGlyphSet; 105706f2543Smrg ProcRenderVector[X_RenderFreeGlyphSet] 106706f2543Smrg = dmxProcRenderFreeGlyphSet; 107706f2543Smrg ProcRenderVector[X_RenderAddGlyphs] 108706f2543Smrg = dmxProcRenderAddGlyphs; 109706f2543Smrg ProcRenderVector[X_RenderFreeGlyphs] 110706f2543Smrg = dmxProcRenderFreeGlyphs; 111706f2543Smrg ProcRenderVector[X_RenderCompositeGlyphs8] 112706f2543Smrg = dmxProcRenderCompositeGlyphs; 113706f2543Smrg ProcRenderVector[X_RenderCompositeGlyphs16] 114706f2543Smrg = dmxProcRenderCompositeGlyphs; 115706f2543Smrg ProcRenderVector[X_RenderCompositeGlyphs32] 116706f2543Smrg = dmxProcRenderCompositeGlyphs; 117706f2543Smrg ProcRenderVector[X_RenderSetPictureTransform] 118706f2543Smrg = dmxProcRenderSetPictureTransform; 119706f2543Smrg ProcRenderVector[X_RenderSetPictureFilter] 120706f2543Smrg = dmxProcRenderSetPictureFilter; 121706f2543Smrg} 122706f2543Smrg 123706f2543Smrg/** Reset the Proc Vector for the RENDER extension back to the original 124706f2543Smrg * functions. This function is called from dmxCloseScreen() during the 125706f2543Smrg * server reset (only for screen #0). */ 126706f2543Smrgvoid dmxResetRender(void) 127706f2543Smrg{ 128706f2543Smrg int i; 129706f2543Smrg 130706f2543Smrg for (i = 0; i < RenderNumberRequests; i++) 131706f2543Smrg ProcRenderVector[i] = dmxSaveRenderVector[i]; 132706f2543Smrg} 133706f2543Smrg 134706f2543Smrg/** Initialize the RENDER extension, allocate the picture privates and 135706f2543Smrg * wrap mi function hooks. If the shadow frame buffer is used, then 136706f2543Smrg * call the appropriate fb initialization function. */ 137706f2543SmrgBool dmxPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats) 138706f2543Smrg{ 139706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 140706f2543Smrg PictureScreenPtr ps; 141706f2543Smrg 142706f2543Smrg /* The shadow framebuffer only relies on FB to be initialized */ 143706f2543Smrg if (dmxShadowFB) return fbPictureInit(pScreen, formats, nformats); 144706f2543Smrg 145706f2543Smrg if (!miPictureInit(pScreen, formats, nformats)) 146706f2543Smrg return FALSE; 147706f2543Smrg 148706f2543Smrg if (!dixRegisterPrivateKey(&dmxPictPrivateKeyRec, PRIVATE_PICTURE, sizeof(dmxPictPrivRec))) 149706f2543Smrg return FALSE; 150706f2543Smrg 151706f2543Smrg ps = GetPictureScreen(pScreen); 152706f2543Smrg 153706f2543Smrg DMX_WRAP(CreatePicture, dmxCreatePicture, dmxScreen, ps); 154706f2543Smrg DMX_WRAP(DestroyPicture, dmxDestroyPicture, dmxScreen, ps); 155706f2543Smrg 156706f2543Smrg DMX_WRAP(ChangePictureClip, dmxChangePictureClip, dmxScreen, ps); 157706f2543Smrg DMX_WRAP(DestroyPictureClip, dmxDestroyPictureClip, dmxScreen, ps); 158706f2543Smrg 159706f2543Smrg DMX_WRAP(ChangePicture, dmxChangePicture, dmxScreen, ps); 160706f2543Smrg DMX_WRAP(ValidatePicture, dmxValidatePicture, dmxScreen, ps); 161706f2543Smrg 162706f2543Smrg DMX_WRAP(Composite, dmxComposite, dmxScreen, ps); 163706f2543Smrg DMX_WRAP(Glyphs, dmxGlyphs, dmxScreen, ps); 164706f2543Smrg DMX_WRAP(CompositeRects, dmxCompositeRects, dmxScreen, ps); 165706f2543Smrg 166706f2543Smrg DMX_WRAP(Trapezoids, dmxTrapezoids, dmxScreen, ps); 167706f2543Smrg DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps); 168706f2543Smrg DMX_WRAP(TriStrip, dmxTriStrip, dmxScreen, ps); 169706f2543Smrg DMX_WRAP(TriFan, dmxTriFan, dmxScreen, ps); 170706f2543Smrg 171706f2543Smrg return TRUE; 172706f2543Smrg} 173706f2543Smrg 174706f2543Smrg 175706f2543Smrg/** Find the appropriate format on the requested screen given the 176706f2543Smrg * internal format requested. The list of formats is searched 177706f2543Smrg * sequentially as the XRenderFindFormat() function does not always 178706f2543Smrg * find the appropriate format when a specific format is requested. */ 179706f2543Smrgstatic XRenderPictFormat *dmxFindFormat(DMXScreenInfo *dmxScreen, 180706f2543Smrg PictFormatPtr pFmt) 181706f2543Smrg{ 182706f2543Smrg XRenderPictFormat *pFormat = NULL; 183706f2543Smrg int i = 0; 184706f2543Smrg 185706f2543Smrg if (!pFmt || !dmxScreen->beDisplay) return pFormat; 186706f2543Smrg 187706f2543Smrg while (1) { 188706f2543Smrg pFormat = XRenderFindFormat(dmxScreen->beDisplay, 0, 0, i++); 189706f2543Smrg if (!pFormat) break; 190706f2543Smrg 191706f2543Smrg if (pFormat->type != pFmt->type) continue; 192706f2543Smrg if (pFormat->depth != pFmt->depth) continue; 193706f2543Smrg if (pFormat->direct.red != pFmt->direct.red) continue; 194706f2543Smrg if (pFormat->direct.redMask != pFmt->direct.redMask) continue; 195706f2543Smrg if (pFormat->direct.green != pFmt->direct.green) continue; 196706f2543Smrg if (pFormat->direct.greenMask != pFmt->direct.greenMask) continue; 197706f2543Smrg if (pFormat->direct.blue != pFmt->direct.blue) continue; 198706f2543Smrg if (pFormat->direct.blueMask != pFmt->direct.blueMask) continue; 199706f2543Smrg if (pFormat->direct.alpha != pFmt->direct.alpha) continue; 200706f2543Smrg if (pFormat->direct.alphaMask != pFmt->direct.alphaMask) continue; 201706f2543Smrg 202706f2543Smrg /* We have a match! */ 203706f2543Smrg break; 204706f2543Smrg } 205706f2543Smrg 206706f2543Smrg return pFormat; 207706f2543Smrg} 208706f2543Smrg 209706f2543Smrg/** Free \a glyphSet on back-end screen number \a idx. */ 210706f2543SmrgBool dmxBEFreeGlyphSet(ScreenPtr pScreen, GlyphSetPtr glyphSet) 211706f2543Smrg{ 212706f2543Smrg dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); 213706f2543Smrg int idx = pScreen->myNum; 214706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[idx]; 215706f2543Smrg 216706f2543Smrg if (glyphPriv->glyphSets[idx]) { 217706f2543Smrg XRenderFreeGlyphSet(dmxScreen->beDisplay, glyphPriv->glyphSets[idx]); 218706f2543Smrg glyphPriv->glyphSets[idx] = (GlyphSet)0; 219706f2543Smrg return TRUE; 220706f2543Smrg } 221706f2543Smrg 222706f2543Smrg return FALSE; 223706f2543Smrg} 224706f2543Smrg 225706f2543Smrg/** Create \a glyphSet on the backend screen number \a idx. */ 226706f2543Smrgint dmxBECreateGlyphSet(int idx, GlyphSetPtr glyphSet) 227706f2543Smrg{ 228706f2543Smrg XRenderPictFormat *pFormat; 229706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[idx]; 230706f2543Smrg dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); 231706f2543Smrg PictFormatPtr pFmt = glyphSet->format; 232706f2543Smrg int (*oldErrorHandler)(Display *, XErrorEvent *); 233706f2543Smrg 234706f2543Smrg pFormat = dmxFindFormat(dmxScreen, pFmt); 235706f2543Smrg if (!pFormat) { 236706f2543Smrg return BadMatch; 237706f2543Smrg } 238706f2543Smrg 239706f2543Smrg dmxGlyphLastError = 0; 240706f2543Smrg oldErrorHandler = XSetErrorHandler(dmxGlyphErrorHandler); 241706f2543Smrg 242706f2543Smrg /* Catch when this fails */ 243706f2543Smrg glyphPriv->glyphSets[idx] 244706f2543Smrg = XRenderCreateGlyphSet(dmxScreen->beDisplay, pFormat); 245706f2543Smrg 246706f2543Smrg XSetErrorHandler(oldErrorHandler); 247706f2543Smrg 248706f2543Smrg if (dmxGlyphLastError) { 249706f2543Smrg return dmxGlyphLastError; 250706f2543Smrg } 251706f2543Smrg 252706f2543Smrg return Success; 253706f2543Smrg} 254706f2543Smrg 255706f2543Smrg/** Create a Glyph Set on each screen. Save the glyphset ID from each 256706f2543Smrg * screen in the Glyph Set's private structure. Fail if the format 257706f2543Smrg * requested is not available or if the Glyph Set cannot be created on 258706f2543Smrg * the screen. */ 259706f2543Smrgstatic int dmxProcRenderCreateGlyphSet(ClientPtr client) 260706f2543Smrg{ 261706f2543Smrg int ret; 262706f2543Smrg REQUEST(xRenderCreateGlyphSetReq); 263706f2543Smrg 264706f2543Smrg ret = dmxSaveRenderVector[stuff->renderReqType](client); 265706f2543Smrg 266706f2543Smrg if (ret == Success) { 267706f2543Smrg GlyphSetPtr glyphSet; 268706f2543Smrg dmxGlyphPrivPtr glyphPriv; 269706f2543Smrg int i; 270706f2543Smrg 271706f2543Smrg /* Look up glyphSet that was just created ???? */ 272706f2543Smrg /* Store glyphsets from backends in glyphSet->devPrivate ????? */ 273706f2543Smrg /* Make sure we handle all errors here!! */ 274706f2543Smrg 275706f2543Smrg dixLookupResourceByType((pointer*) &glyphSet, 276706f2543Smrg stuff->gsid, GlyphSetType, 277706f2543Smrg client, DixDestroyAccess); 278706f2543Smrg 279706f2543Smrg glyphPriv = malloc(sizeof(dmxGlyphPrivRec)); 280706f2543Smrg if (!glyphPriv) return BadAlloc; 281706f2543Smrg glyphPriv->glyphSets = NULL; 282706f2543Smrg MAXSCREENSALLOC_RETURN(glyphPriv->glyphSets, BadAlloc); 283706f2543Smrg DMX_SET_GLYPH_PRIV(glyphSet, glyphPriv); 284706f2543Smrg 285706f2543Smrg for (i = 0; i < dmxNumScreens; i++) { 286706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[i]; 287706f2543Smrg int beret; 288706f2543Smrg 289706f2543Smrg if (!dmxScreen->beDisplay) { 290706f2543Smrg glyphPriv->glyphSets[i] = 0; 291706f2543Smrg continue; 292706f2543Smrg } 293706f2543Smrg 294706f2543Smrg if ((beret = dmxBECreateGlyphSet(i, glyphSet)) != Success) { 295706f2543Smrg int j; 296706f2543Smrg 297706f2543Smrg /* Free the glyph sets we've allocated thus far */ 298706f2543Smrg for (j = 0; j < i; j++) 299706f2543Smrg dmxBEFreeGlyphSet(screenInfo.screens[j], glyphSet); 300706f2543Smrg 301706f2543Smrg /* Free the resource created by render */ 302706f2543Smrg FreeResource(stuff->gsid, RT_NONE); 303706f2543Smrg 304706f2543Smrg return beret; 305706f2543Smrg } 306706f2543Smrg } 307706f2543Smrg } 308706f2543Smrg 309706f2543Smrg return ret; 310706f2543Smrg} 311706f2543Smrg 312706f2543Smrg/** Free the previously allocated Glyph Sets for each screen. */ 313706f2543Smrgstatic int dmxProcRenderFreeGlyphSet(ClientPtr client) 314706f2543Smrg{ 315706f2543Smrg GlyphSetPtr glyphSet; 316706f2543Smrg REQUEST(xRenderFreeGlyphSetReq); 317706f2543Smrg 318706f2543Smrg REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq); 319706f2543Smrg dixLookupResourceByType((pointer*) &glyphSet, 320706f2543Smrg stuff->glyphset, GlyphSetType, 321706f2543Smrg client, DixDestroyAccess); 322706f2543Smrg 323706f2543Smrg if (glyphSet && glyphSet->refcnt == 1) { 324706f2543Smrg dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); 325706f2543Smrg int i; 326706f2543Smrg 327706f2543Smrg for (i = 0; i < dmxNumScreens; i++) { 328706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[i]; 329706f2543Smrg 330706f2543Smrg if (dmxScreen->beDisplay) { 331706f2543Smrg if (dmxBEFreeGlyphSet(screenInfo.screens[i], glyphSet)) 332706f2543Smrg dmxSync(dmxScreen, FALSE); 333706f2543Smrg } 334706f2543Smrg } 335706f2543Smrg 336706f2543Smrg MAXSCREENSFREE(glyphPriv->glyphSets); 337706f2543Smrg free(glyphPriv); 338706f2543Smrg DMX_SET_GLYPH_PRIV(glyphSet, NULL); 339706f2543Smrg } 340706f2543Smrg 341706f2543Smrg return dmxSaveRenderVector[stuff->renderReqType](client); 342706f2543Smrg} 343706f2543Smrg 344706f2543Smrg/** Add glyphs to the Glyph Set on each screen. */ 345706f2543Smrgstatic int dmxProcRenderAddGlyphs(ClientPtr client) 346706f2543Smrg{ 347706f2543Smrg int ret; 348706f2543Smrg REQUEST(xRenderAddGlyphsReq); 349706f2543Smrg 350706f2543Smrg ret = dmxSaveRenderVector[stuff->renderReqType](client); 351706f2543Smrg 352706f2543Smrg if (ret == Success) { 353706f2543Smrg GlyphSetPtr glyphSet; 354706f2543Smrg dmxGlyphPrivPtr glyphPriv; 355706f2543Smrg int i; 356706f2543Smrg int nglyphs; 357706f2543Smrg CARD32 *gids; 358706f2543Smrg Glyph *gidsCopy; 359706f2543Smrg xGlyphInfo *gi; 360706f2543Smrg CARD8 *bits; 361706f2543Smrg int nbytes; 362706f2543Smrg 363706f2543Smrg dixLookupResourceByType((pointer*) &glyphSet, 364706f2543Smrg stuff->glyphset, GlyphSetType, 365706f2543Smrg client, DixReadAccess); 366706f2543Smrg glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); 367706f2543Smrg 368706f2543Smrg nglyphs = stuff->nglyphs; 369706f2543Smrg gids = (CARD32 *)(stuff + 1); 370706f2543Smrg gi = (xGlyphInfo *)(gids + nglyphs); 371706f2543Smrg bits = (CARD8 *)(gi + nglyphs); 372706f2543Smrg nbytes = ((stuff->length << 2) - 373706f2543Smrg sizeof(xRenderAddGlyphsReq) - 374706f2543Smrg (sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs); 375706f2543Smrg 376706f2543Smrg gidsCopy = malloc(sizeof(*gidsCopy) * nglyphs); 377706f2543Smrg for (i = 0; i < nglyphs; i++) gidsCopy[i] = gids[i]; 378706f2543Smrg 379706f2543Smrg /* FIXME: Will this ever fail? */ 380706f2543Smrg for (i = 0; i < dmxNumScreens; i++) { 381706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[i]; 382706f2543Smrg 383706f2543Smrg if (dmxScreen->beDisplay) { 384706f2543Smrg XRenderAddGlyphs(dmxScreen->beDisplay, 385706f2543Smrg glyphPriv->glyphSets[i], 386706f2543Smrg gidsCopy, 387706f2543Smrg (XGlyphInfo *)gi, 388706f2543Smrg nglyphs, 389706f2543Smrg (char *)bits, 390706f2543Smrg nbytes); 391706f2543Smrg dmxSync(dmxScreen, FALSE); 392706f2543Smrg } 393706f2543Smrg } 394706f2543Smrg free(gidsCopy); 395706f2543Smrg } 396706f2543Smrg 397706f2543Smrg return ret; 398706f2543Smrg} 399706f2543Smrg 400706f2543Smrg/** Free glyphs from the Glyph Set for each screen. */ 401706f2543Smrgstatic int dmxProcRenderFreeGlyphs(ClientPtr client) 402706f2543Smrg{ 403706f2543Smrg GlyphSetPtr glyphSet; 404706f2543Smrg REQUEST(xRenderFreeGlyphsReq); 405706f2543Smrg 406706f2543Smrg REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq); 407706f2543Smrg dixLookupResourceByType((pointer*) &glyphSet, 408706f2543Smrg stuff->glyphset, GlyphSetType, 409706f2543Smrg client, DixWriteAccess); 410706f2543Smrg 411706f2543Smrg if (glyphSet) { 412706f2543Smrg dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); 413706f2543Smrg int i; 414706f2543Smrg int nglyphs; 415706f2543Smrg Glyph *gids; 416706f2543Smrg 417706f2543Smrg nglyphs = ((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq)) >> 2; 418706f2543Smrg if (nglyphs) { 419706f2543Smrg gids = malloc(sizeof(*gids) * nglyphs); 420706f2543Smrg for (i = 0; i < nglyphs; i++) 421706f2543Smrg gids[i] = ((CARD32 *)(stuff + 1))[i]; 422706f2543Smrg 423706f2543Smrg for (i = 0; i < dmxNumScreens; i++) { 424706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[i]; 425706f2543Smrg 426706f2543Smrg if (dmxScreen->beDisplay) { 427706f2543Smrg XRenderFreeGlyphs(dmxScreen->beDisplay, 428706f2543Smrg glyphPriv->glyphSets[i], gids, nglyphs); 429706f2543Smrg dmxSync(dmxScreen, FALSE); 430706f2543Smrg } 431706f2543Smrg } 432706f2543Smrg free(gids); 433706f2543Smrg } 434706f2543Smrg } 435706f2543Smrg 436706f2543Smrg return dmxSaveRenderVector[stuff->renderReqType](client); 437706f2543Smrg} 438706f2543Smrg 439706f2543Smrg/** Composite glyphs on each screen into the requested picture. If 440706f2543Smrg * either the src or dest picture has not been allocated due to lazy 441706f2543Smrg * window creation, this request will gracefully return. */ 442706f2543Smrgstatic int dmxProcRenderCompositeGlyphs(ClientPtr client) 443706f2543Smrg{ 444706f2543Smrg int ret; 445706f2543Smrg REQUEST(xRenderCompositeGlyphsReq); 446706f2543Smrg 447706f2543Smrg ret = dmxSaveRenderVector[stuff->renderReqType](client); 448706f2543Smrg 449706f2543Smrg /* For the following to work with PanoramiX, it assumes that Render 450706f2543Smrg * wraps the ProcRenderVector after dmxRenderInit has been called. 451706f2543Smrg */ 452706f2543Smrg if (ret == Success) { 453706f2543Smrg PicturePtr pSrc; 454706f2543Smrg dmxPictPrivPtr pSrcPriv; 455706f2543Smrg PicturePtr pDst; 456706f2543Smrg dmxPictPrivPtr pDstPriv; 457706f2543Smrg PictFormatPtr pFmt; 458706f2543Smrg XRenderPictFormat *pFormat; 459706f2543Smrg int size; 460706f2543Smrg 461706f2543Smrg int scrnNum; 462706f2543Smrg DMXScreenInfo *dmxScreen; 463706f2543Smrg 464706f2543Smrg CARD8 *buffer; 465706f2543Smrg CARD8 *end; 466706f2543Smrg int space; 467706f2543Smrg 468706f2543Smrg int nglyph; 469706f2543Smrg char *glyphs; 470706f2543Smrg char *curGlyph; 471706f2543Smrg 472706f2543Smrg xGlyphElt *elt; 473706f2543Smrg int nelt; 474706f2543Smrg XGlyphElt8 *elts; 475706f2543Smrg XGlyphElt8 *curElt; 476706f2543Smrg 477706f2543Smrg GlyphSetPtr glyphSet; 478706f2543Smrg dmxGlyphPrivPtr glyphPriv; 479706f2543Smrg 480706f2543Smrg dixLookupResourceByType((pointer*) &pSrc, 481706f2543Smrg stuff->src, PictureType, 482706f2543Smrg client, DixReadAccess); 483706f2543Smrg 484706f2543Smrg pSrcPriv = DMX_GET_PICT_PRIV(pSrc); 485706f2543Smrg if (!pSrcPriv->pict) 486706f2543Smrg return ret; 487706f2543Smrg 488706f2543Smrg dixLookupResourceByType((pointer*) &pDst, 489706f2543Smrg stuff->dst, PictureType, 490706f2543Smrg client, DixWriteAccess); 491706f2543Smrg 492706f2543Smrg pDstPriv = DMX_GET_PICT_PRIV(pDst); 493706f2543Smrg if (!pDstPriv->pict) 494706f2543Smrg return ret; 495706f2543Smrg 496706f2543Smrg scrnNum = pDst->pDrawable->pScreen->myNum; 497706f2543Smrg dmxScreen = &dmxScreens[scrnNum]; 498706f2543Smrg 499706f2543Smrg /* Note: If the back-end display has been detached, then it 500706f2543Smrg * should not be possible to reach here since the pSrcPriv->pict 501706f2543Smrg * and pDstPriv->pict will have already been set to 0. 502706f2543Smrg */ 503706f2543Smrg if (!dmxScreen->beDisplay) 504706f2543Smrg return ret; 505706f2543Smrg 506706f2543Smrg if (stuff->maskFormat) 507706f2543Smrg dixLookupResourceByType((pointer*) &pFmt, 508706f2543Smrg stuff->maskFormat, PictFormatType, 509706f2543Smrg client, DixReadAccess); 510706f2543Smrg else 511706f2543Smrg pFmt = NULL; 512706f2543Smrg 513706f2543Smrg pFormat = dmxFindFormat(dmxScreen, pFmt); 514706f2543Smrg 515706f2543Smrg switch (stuff->renderReqType) { 516706f2543Smrg case X_RenderCompositeGlyphs8: size = sizeof(CARD8); break; 517706f2543Smrg case X_RenderCompositeGlyphs16: size = sizeof(CARD16); break; 518706f2543Smrg case X_RenderCompositeGlyphs32: size = sizeof(CARD32); break; 519706f2543Smrg default: return BadPictOp; /* Can't happen */ 520706f2543Smrg } 521706f2543Smrg 522706f2543Smrg buffer = (CARD8 *)(stuff + 1); 523706f2543Smrg end = (CARD8 *)stuff + (stuff->length << 2); 524706f2543Smrg nelt = 0; 525706f2543Smrg nglyph = 0; 526706f2543Smrg while (buffer + sizeof(xGlyphElt) < end) { 527706f2543Smrg elt = (xGlyphElt *)buffer; 528706f2543Smrg buffer += sizeof(xGlyphElt); 529706f2543Smrg 530706f2543Smrg if (elt->len == 0xff) { 531706f2543Smrg buffer += 4; 532706f2543Smrg } else { 533706f2543Smrg nelt++; 534706f2543Smrg nglyph += elt->len; 535706f2543Smrg space = size * elt->len; 536706f2543Smrg if (space & 3) space += 4 - (space & 3); 537706f2543Smrg buffer += space; 538706f2543Smrg } 539706f2543Smrg } 540706f2543Smrg 541706f2543Smrg /* The following only works for Render version > 0.2 */ 542706f2543Smrg 543706f2543Smrg /* All of the XGlyphElt* structure sizes are identical */ 544706f2543Smrg elts = malloc(nelt * sizeof(XGlyphElt8)); 545706f2543Smrg if (!elts) 546706f2543Smrg return BadAlloc; 547706f2543Smrg 548706f2543Smrg glyphs = malloc(nglyph * size); 549706f2543Smrg if (!glyphs) { 550706f2543Smrg free(elts); 551706f2543Smrg return BadAlloc; 552706f2543Smrg } 553706f2543Smrg 554706f2543Smrg buffer = (CARD8 *)(stuff + 1); 555706f2543Smrg end = (CARD8 *)stuff + (stuff->length << 2); 556706f2543Smrg curGlyph = glyphs; 557706f2543Smrg curElt = elts; 558706f2543Smrg 559706f2543Smrg dixLookupResourceByType((pointer*) &glyphSet, 560706f2543Smrg stuff->glyphset, GlyphSetType, 561706f2543Smrg client, DixReadAccess); 562706f2543Smrg glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); 563706f2543Smrg 564706f2543Smrg while (buffer + sizeof(xGlyphElt) < end) { 565706f2543Smrg elt = (xGlyphElt *)buffer; 566706f2543Smrg buffer += sizeof(xGlyphElt); 567706f2543Smrg 568706f2543Smrg if (elt->len == 0xff) { 569706f2543Smrg dixLookupResourceByType((pointer*) &glyphSet, 570706f2543Smrg *((CARD32 *)buffer), 571706f2543Smrg GlyphSetType, 572706f2543Smrg client, 573706f2543Smrg DixReadAccess); 574706f2543Smrg glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); 575706f2543Smrg buffer += 4; 576706f2543Smrg } else { 577706f2543Smrg curElt->glyphset = glyphPriv->glyphSets[scrnNum]; 578706f2543Smrg curElt->xOff = elt->deltax; 579706f2543Smrg curElt->yOff = elt->deltay; 580706f2543Smrg curElt->nchars = elt->len; 581706f2543Smrg curElt->chars = curGlyph; 582706f2543Smrg 583706f2543Smrg memcpy(curGlyph, buffer, size*elt->len); 584706f2543Smrg curGlyph += size * elt->len; 585706f2543Smrg 586706f2543Smrg curElt++; 587706f2543Smrg 588706f2543Smrg space = size * elt->len; 589706f2543Smrg if (space & 3) space += 4 - (space & 3); 590706f2543Smrg buffer += space; 591706f2543Smrg } 592706f2543Smrg } 593706f2543Smrg 594706f2543Smrg switch (stuff->renderReqType) { 595706f2543Smrg case X_RenderCompositeGlyphs8: 596706f2543Smrg XRenderCompositeText8(dmxScreen->beDisplay, stuff->op, 597706f2543Smrg pSrcPriv->pict, pDstPriv->pict, 598706f2543Smrg pFormat, 599706f2543Smrg stuff->xSrc, stuff->ySrc, 600706f2543Smrg 0, 0, elts, nelt); 601706f2543Smrg break; 602706f2543Smrg case X_RenderCompositeGlyphs16: 603706f2543Smrg XRenderCompositeText16(dmxScreen->beDisplay, stuff->op, 604706f2543Smrg pSrcPriv->pict, pDstPriv->pict, 605706f2543Smrg pFormat, 606706f2543Smrg stuff->xSrc, stuff->ySrc, 607706f2543Smrg 0, 0, (XGlyphElt16 *)elts, nelt); 608706f2543Smrg break; 609706f2543Smrg case X_RenderCompositeGlyphs32: 610706f2543Smrg XRenderCompositeText32(dmxScreen->beDisplay, stuff->op, 611706f2543Smrg pSrcPriv->pict, pDstPriv->pict, 612706f2543Smrg pFormat, 613706f2543Smrg stuff->xSrc, stuff->ySrc, 614706f2543Smrg 0, 0, (XGlyphElt32 *)elts, nelt); 615706f2543Smrg break; 616706f2543Smrg } 617706f2543Smrg 618706f2543Smrg dmxSync(dmxScreen, FALSE); 619706f2543Smrg 620706f2543Smrg free(elts); 621706f2543Smrg free(glyphs); 622706f2543Smrg } 623706f2543Smrg 624706f2543Smrg return ret; 625706f2543Smrg} 626706f2543Smrg 627706f2543Smrg/** Set the picture transform on each screen. */ 628706f2543Smrgstatic int dmxProcRenderSetPictureTransform(ClientPtr client) 629706f2543Smrg{ 630706f2543Smrg DMXScreenInfo *dmxScreen; 631706f2543Smrg PicturePtr pPicture; 632706f2543Smrg dmxPictPrivPtr pPictPriv; 633706f2543Smrg XTransform xform; 634706f2543Smrg REQUEST(xRenderSetPictureTransformReq); 635706f2543Smrg 636706f2543Smrg REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); 637706f2543Smrg VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess); 638706f2543Smrg 639706f2543Smrg /* For the following to work with PanoramiX, it assumes that Render 640706f2543Smrg * wraps the ProcRenderVector after dmxRenderInit has been called. 641706f2543Smrg */ 642706f2543Smrg dmxScreen = &dmxScreens[pPicture->pDrawable->pScreen->myNum]; 643706f2543Smrg pPictPriv = DMX_GET_PICT_PRIV(pPicture); 644706f2543Smrg 645706f2543Smrg if (pPictPriv->pict) { 646706f2543Smrg xform.matrix[0][0] = stuff->transform.matrix11; 647706f2543Smrg xform.matrix[0][1] = stuff->transform.matrix12; 648706f2543Smrg xform.matrix[0][2] = stuff->transform.matrix13; 649706f2543Smrg xform.matrix[1][0] = stuff->transform.matrix21; 650706f2543Smrg xform.matrix[1][1] = stuff->transform.matrix22; 651706f2543Smrg xform.matrix[1][2] = stuff->transform.matrix23; 652706f2543Smrg xform.matrix[2][0] = stuff->transform.matrix31; 653706f2543Smrg xform.matrix[2][1] = stuff->transform.matrix32; 654706f2543Smrg xform.matrix[2][2] = stuff->transform.matrix33; 655706f2543Smrg 656706f2543Smrg XRenderSetPictureTransform(dmxScreen->beDisplay, 657706f2543Smrg pPictPriv->pict, 658706f2543Smrg &xform); 659706f2543Smrg dmxSync(dmxScreen, FALSE); 660706f2543Smrg } 661706f2543Smrg 662706f2543Smrg return dmxSaveRenderVector[stuff->renderReqType](client); 663706f2543Smrg} 664706f2543Smrg 665706f2543Smrg/** Set the picture filter on each screen. */ 666706f2543Smrgstatic int dmxProcRenderSetPictureFilter(ClientPtr client) 667706f2543Smrg{ 668706f2543Smrg DMXScreenInfo *dmxScreen; 669706f2543Smrg PicturePtr pPicture; 670706f2543Smrg dmxPictPrivPtr pPictPriv; 671706f2543Smrg char *filter; 672706f2543Smrg XFixed *params; 673706f2543Smrg int nparams; 674706f2543Smrg REQUEST(xRenderSetPictureFilterReq); 675706f2543Smrg 676706f2543Smrg REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq); 677706f2543Smrg VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess); 678706f2543Smrg 679706f2543Smrg /* For the following to work with PanoramiX, it assumes that Render 680706f2543Smrg * wraps the ProcRenderVector after dmxRenderInit has been called. 681706f2543Smrg */ 682706f2543Smrg dmxScreen = &dmxScreens[pPicture->pDrawable->pScreen->myNum]; 683706f2543Smrg pPictPriv = DMX_GET_PICT_PRIV(pPicture); 684706f2543Smrg 685706f2543Smrg if (pPictPriv->pict) { 686706f2543Smrg filter = (char *)(stuff + 1); 687706f2543Smrg params = (XFixed *)(filter + ((stuff->nbytes + 3) & ~3)); 688706f2543Smrg nparams = ((XFixed *)stuff + client->req_len) - params; 689706f2543Smrg 690706f2543Smrg XRenderSetPictureFilter(dmxScreen->beDisplay, 691706f2543Smrg pPictPriv->pict, 692706f2543Smrg filter, 693706f2543Smrg params, 694706f2543Smrg nparams); 695706f2543Smrg dmxSync(dmxScreen, FALSE); 696706f2543Smrg } 697706f2543Smrg 698706f2543Smrg return dmxSaveRenderVector[stuff->renderReqType](client); 699706f2543Smrg} 700706f2543Smrg 701706f2543Smrg 702706f2543Smrg/** Create a picture on the appropriate screen. This is the actual 703706f2543Smrg * function that creates the picture. However, if the associated 704706f2543Smrg * window has not yet been created due to lazy window creation, then 705706f2543Smrg * delay the picture creation until the window is mapped. */ 706706f2543Smrgstatic Picture dmxDoCreatePicture(PicturePtr pPicture) 707706f2543Smrg{ 708706f2543Smrg DrawablePtr pDraw = pPicture->pDrawable; 709706f2543Smrg ScreenPtr pScreen = pDraw->pScreen; 710706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 711706f2543Smrg XRenderPictFormat *pFormat; 712706f2543Smrg Drawable draw; 713706f2543Smrg 714706f2543Smrg if (pPicture->pDrawable->type == DRAWABLE_WINDOW) { 715706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV((WindowPtr)(pDraw)); 716706f2543Smrg 717706f2543Smrg if (!(draw = pWinPriv->window)) { 718706f2543Smrg /* Window has not been created yet due to the window 719706f2543Smrg * optimization. Delay picture creation until window is 720706f2543Smrg * mapped. 721706f2543Smrg */ 722706f2543Smrg pWinPriv->hasPict = TRUE; 723706f2543Smrg return 0; 724706f2543Smrg } 725706f2543Smrg } else { 726706f2543Smrg dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV((PixmapPtr)(pDraw)); 727706f2543Smrg 728706f2543Smrg if (!(draw = pPixPriv->pixmap)) { 729706f2543Smrg /* FIXME: Zero width/height pixmap?? */ 730706f2543Smrg return 0; 731706f2543Smrg } 732706f2543Smrg } 733706f2543Smrg 734706f2543Smrg /* This should not be reached if the back-end display has been 735706f2543Smrg * detached because the pWinPriv->window or the pPixPriv->pixmap 736706f2543Smrg * will be NULL; however, we add it here for completeness 737706f2543Smrg */ 738706f2543Smrg if (!dmxScreen->beDisplay) 739706f2543Smrg return 0; 740706f2543Smrg 741706f2543Smrg pFormat = dmxFindFormat(dmxScreen, pPicture->pFormat); 742706f2543Smrg 743706f2543Smrg return XRenderCreatePicture(dmxScreen->beDisplay, draw, pFormat, 0, 0); 744706f2543Smrg} 745706f2543Smrg 746706f2543Smrg/** Create a list of pictures. This function is called by 747706f2543Smrg * dmxCreateAndRealizeWindow() during the lazy window creation 748706f2543Smrg * realization process. It creates the entire list of pictures that 749706f2543Smrg * are associated with the given window. */ 750706f2543Smrgvoid dmxCreatePictureList(WindowPtr pWindow) 751706f2543Smrg{ 752706f2543Smrg PicturePtr pPicture = GetPictureWindow(pWindow); 753706f2543Smrg 754706f2543Smrg while (pPicture) { 755706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 756706f2543Smrg 757706f2543Smrg /* Create the picture for this window */ 758706f2543Smrg pPictPriv->pict = dmxDoCreatePicture(pPicture); 759706f2543Smrg 760706f2543Smrg /* ValidatePicture takes care of the state changes */ 761706f2543Smrg 762706f2543Smrg pPicture = pPicture->pNext; 763706f2543Smrg } 764706f2543Smrg} 765706f2543Smrg 766706f2543Smrg/** Create \a pPicture on the backend. */ 767706f2543Smrgint dmxBECreatePicture(PicturePtr pPicture) 768706f2543Smrg{ 769706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 770706f2543Smrg 771706f2543Smrg /* Create picutre on BE */ 772706f2543Smrg pPictPriv->pict = dmxDoCreatePicture(pPicture); 773706f2543Smrg 774706f2543Smrg /* Flush changes to the backend server */ 775706f2543Smrg dmxValidatePicture(pPicture, (1 << (CPLastBit+1)) - 1); 776706f2543Smrg 777706f2543Smrg return Success; 778706f2543Smrg} 779706f2543Smrg 780706f2543Smrg/** Create a picture. This function handles the CreatePicture 781706f2543Smrg * unwrapping/wrapping and calls dmxDoCreatePicture to actually create 782706f2543Smrg * the picture on the appropriate screen. */ 783706f2543Smrgint dmxCreatePicture(PicturePtr pPicture) 784706f2543Smrg{ 785706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 786706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 787706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 788706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 789706f2543Smrg int ret = Success; 790706f2543Smrg 791706f2543Smrg DMX_UNWRAP(CreatePicture, dmxScreen, ps); 792706f2543Smrg#if 1 793706f2543Smrg if (ps->CreatePicture) 794706f2543Smrg ret = ps->CreatePicture(pPicture); 795706f2543Smrg#endif 796706f2543Smrg 797706f2543Smrg /* Create picture on back-end server */ 798706f2543Smrg pPictPriv->pict = dmxDoCreatePicture(pPicture); 799706f2543Smrg pPictPriv->savedMask = 0; 800706f2543Smrg 801706f2543Smrg DMX_WRAP(CreatePicture, dmxCreatePicture, dmxScreen, ps); 802706f2543Smrg 803706f2543Smrg return ret; 804706f2543Smrg} 805706f2543Smrg 806706f2543Smrg/** Destroy \a pPicture on the back-end server. */ 807706f2543SmrgBool dmxBEFreePicture(PicturePtr pPicture) 808706f2543Smrg{ 809706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 810706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 811706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 812706f2543Smrg 813706f2543Smrg if (pPictPriv->pict) { 814706f2543Smrg XRenderFreePicture(dmxScreen->beDisplay, pPictPriv->pict); 815706f2543Smrg pPictPriv->pict = (Picture)0; 816706f2543Smrg return TRUE; 817706f2543Smrg } 818706f2543Smrg 819706f2543Smrg return FALSE; 820706f2543Smrg} 821706f2543Smrg 822706f2543Smrg/** Destroy a list of pictures that are associated with the window that 823706f2543Smrg * is being destroyed. This function is called by #dmxDestroyWindow(). 824706f2543Smrg * */ 825706f2543SmrgBool dmxDestroyPictureList(WindowPtr pWindow) 826706f2543Smrg{ 827706f2543Smrg PicturePtr pPicture = GetPictureWindow(pWindow); 828706f2543Smrg Bool ret = FALSE; 829706f2543Smrg 830706f2543Smrg while (pPicture) { 831706f2543Smrg ret |= dmxBEFreePicture(pPicture); 832706f2543Smrg pPicture = pPicture->pNext; 833706f2543Smrg } 834706f2543Smrg 835706f2543Smrg return ret; 836706f2543Smrg} 837706f2543Smrg 838706f2543Smrg/** Destroy a picture. This function calls the wrapped function that 839706f2543Smrg * frees the resources in the DMX server associated with this 840706f2543Smrg * picture. */ 841706f2543Smrgvoid dmxDestroyPicture(PicturePtr pPicture) 842706f2543Smrg{ 843706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 844706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 845706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 846706f2543Smrg 847706f2543Smrg DMX_UNWRAP(DestroyPicture, dmxScreen, ps); 848706f2543Smrg 849706f2543Smrg /* Destroy picture on back-end server */ 850706f2543Smrg if (dmxBEFreePicture(pPicture)) 851706f2543Smrg dmxSync(dmxScreen, FALSE); 852706f2543Smrg 853706f2543Smrg#if 1 854706f2543Smrg if (ps->DestroyPicture) 855706f2543Smrg ps->DestroyPicture(pPicture); 856706f2543Smrg#endif 857706f2543Smrg DMX_WRAP(DestroyPicture, dmxDestroyPicture, dmxScreen, ps); 858706f2543Smrg} 859706f2543Smrg 860706f2543Smrg/** Change the picture's list of clip rectangles. */ 861706f2543Smrgint dmxChangePictureClip(PicturePtr pPicture, int clipType, 862706f2543Smrg pointer value, int n) 863706f2543Smrg{ 864706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 865706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 866706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 867706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 868706f2543Smrg 869706f2543Smrg DMX_UNWRAP(ChangePictureClip, dmxScreen, ps); 870706f2543Smrg#if 1 871706f2543Smrg if (ps->ChangePictureClip) 872706f2543Smrg ps->ChangePictureClip(pPicture, clipType, value, n); 873706f2543Smrg#endif 874706f2543Smrg 875706f2543Smrg /* Change picture clip rects on back-end server */ 876706f2543Smrg if (pPictPriv->pict) { 877706f2543Smrg /* The clip has already been changed into a region by the mi 878706f2543Smrg * routine called above. 879706f2543Smrg */ 880706f2543Smrg if (clipType == CT_NONE) { 881706f2543Smrg /* Disable clipping, show all */ 882706f2543Smrg XFixesSetPictureClipRegion(dmxScreen->beDisplay, 883706f2543Smrg pPictPriv->pict, 0, 0, None); 884706f2543Smrg } else if (pPicture->clientClip) { 885706f2543Smrg RegionPtr pClip = pPicture->clientClip; 886706f2543Smrg BoxPtr pBox = RegionRects(pClip); 887706f2543Smrg int nBox = RegionNumRects(pClip); 888706f2543Smrg XRectangle *pRects; 889706f2543Smrg XRectangle *pRect; 890706f2543Smrg int nRects; 891706f2543Smrg 892706f2543Smrg nRects = nBox; 893706f2543Smrg pRects = pRect = malloc(nRects * sizeof(*pRect)); 894706f2543Smrg 895706f2543Smrg while (nBox--) { 896706f2543Smrg pRect->x = pBox->x1; 897706f2543Smrg pRect->y = pBox->y1; 898706f2543Smrg pRect->width = pBox->x2 - pBox->x1; 899706f2543Smrg pRect->height = pBox->y2 - pBox->y1; 900706f2543Smrg pBox++; 901706f2543Smrg pRect++; 902706f2543Smrg } 903706f2543Smrg 904706f2543Smrg XRenderSetPictureClipRectangles(dmxScreen->beDisplay, 905706f2543Smrg pPictPriv->pict, 906706f2543Smrg 0, 0, 907706f2543Smrg pRects, 908706f2543Smrg nRects); 909706f2543Smrg free(pRects); 910706f2543Smrg } else { 911706f2543Smrg XRenderSetPictureClipRectangles(dmxScreen->beDisplay, 912706f2543Smrg pPictPriv->pict, 913706f2543Smrg 0, 0, NULL, 0); 914706f2543Smrg } 915706f2543Smrg dmxSync(dmxScreen, FALSE); 916706f2543Smrg } else { 917706f2543Smrg /* FIXME: Handle saving clip region when offscreen */ 918706f2543Smrg } 919706f2543Smrg 920706f2543Smrg DMX_WRAP(ChangePictureClip, dmxChangePictureClip, dmxScreen, ps); 921706f2543Smrg 922706f2543Smrg return Success; 923706f2543Smrg} 924706f2543Smrg 925706f2543Smrg/** Destroy the picture's list of clip rectangles. */ 926706f2543Smrgvoid dmxDestroyPictureClip(PicturePtr pPicture) 927706f2543Smrg{ 928706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 929706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 930706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 931706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 932706f2543Smrg 933706f2543Smrg DMX_UNWRAP(DestroyPictureClip, dmxScreen, ps); 934706f2543Smrg#if 1 935706f2543Smrg if (ps->DestroyPictureClip) 936706f2543Smrg ps->DestroyPictureClip(pPicture); 937706f2543Smrg#endif 938706f2543Smrg 939706f2543Smrg /* Destroy picture clip rects on back-end server */ 940706f2543Smrg if (pPictPriv->pict) { 941706f2543Smrg XRenderSetPictureClipRectangles(dmxScreen->beDisplay, 942706f2543Smrg pPictPriv->pict, 943706f2543Smrg 0, 0, NULL, 0); 944706f2543Smrg dmxSync(dmxScreen, FALSE); 945706f2543Smrg } else { 946706f2543Smrg /* FIXME: Handle destroying clip region when offscreen */ 947706f2543Smrg } 948706f2543Smrg 949706f2543Smrg DMX_WRAP(DestroyPictureClip, dmxDestroyPictureClip, dmxScreen, ps); 950706f2543Smrg} 951706f2543Smrg 952706f2543Smrg/** Change the attributes of the pictures. If the picture has not yet 953706f2543Smrg * been created due to lazy window creation, save the mask so that it 954706f2543Smrg * can be used to appropriately initialize the picture's attributes 955706f2543Smrg * when it is created later. */ 956706f2543Smrgvoid dmxChangePicture(PicturePtr pPicture, Mask mask) 957706f2543Smrg{ 958706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 959706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 960706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 961706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 962706f2543Smrg 963706f2543Smrg DMX_UNWRAP(ChangePicture, dmxScreen, ps); 964706f2543Smrg#if 1 965706f2543Smrg if (ps->ChangePicture) 966706f2543Smrg ps->ChangePicture(pPicture, mask); 967706f2543Smrg#endif 968706f2543Smrg 969706f2543Smrg /* Picture attribute changes are handled in ValidatePicture */ 970706f2543Smrg pPictPriv->savedMask |= mask; 971706f2543Smrg 972706f2543Smrg DMX_WRAP(ChangePicture, dmxChangePicture, dmxScreen, ps); 973706f2543Smrg} 974706f2543Smrg 975706f2543Smrg/** Validate the picture's attributes before rendering to it. Update 976706f2543Smrg * any picture attributes that have been changed by one of the higher 977706f2543Smrg * layers. */ 978706f2543Smrgvoid dmxValidatePicture(PicturePtr pPicture, Mask mask) 979706f2543Smrg{ 980706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 981706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 982706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 983706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 984706f2543Smrg 985706f2543Smrg DMX_UNWRAP(ValidatePicture, dmxScreen, ps); 986706f2543Smrg 987706f2543Smrg /* Change picture attributes on back-end server */ 988706f2543Smrg if (pPictPriv->pict) { 989706f2543Smrg XRenderPictureAttributes attribs; 990706f2543Smrg 991706f2543Smrg if (mask & CPRepeat) { 992706f2543Smrg attribs.repeat = pPicture->repeatType; 993706f2543Smrg } 994706f2543Smrg if (mask & CPAlphaMap) { 995706f2543Smrg if (pPicture->alphaMap) { 996706f2543Smrg dmxPictPrivPtr pAlphaPriv; 997706f2543Smrg pAlphaPriv = DMX_GET_PICT_PRIV(pPicture->alphaMap); 998706f2543Smrg if (pAlphaPriv->pict) { 999706f2543Smrg attribs.alpha_map = pAlphaPriv->pict; 1000706f2543Smrg } else { 1001706f2543Smrg /* FIXME: alpha picture drawable has not been created?? */ 1002706f2543Smrg return; /* or should this be: attribs.alpha_map = None; */ 1003706f2543Smrg } 1004706f2543Smrg } else { 1005706f2543Smrg attribs.alpha_map = None; 1006706f2543Smrg } 1007706f2543Smrg } 1008706f2543Smrg if (mask & CPAlphaXOrigin) 1009706f2543Smrg attribs.alpha_x_origin = pPicture->alphaOrigin.x; 1010706f2543Smrg if (mask & CPAlphaYOrigin) 1011706f2543Smrg attribs.alpha_y_origin = pPicture->alphaOrigin.y; 1012706f2543Smrg if (mask & CPClipXOrigin) 1013706f2543Smrg attribs.clip_x_origin = pPicture->clipOrigin.x; 1014706f2543Smrg if (mask & CPClipYOrigin) 1015706f2543Smrg attribs.clip_y_origin = pPicture->clipOrigin.y; 1016706f2543Smrg if (mask & CPClipMask) 1017706f2543Smrg mask &= ~CPClipMask; /* Handled in ChangePictureClip */ 1018706f2543Smrg if (mask & CPGraphicsExposure) 1019706f2543Smrg attribs.graphics_exposures = pPicture->graphicsExposures; 1020706f2543Smrg if (mask & CPSubwindowMode) 1021706f2543Smrg attribs.subwindow_mode = pPicture->subWindowMode; 1022706f2543Smrg if (mask & CPPolyEdge) 1023706f2543Smrg attribs.poly_edge = pPicture->polyEdge; 1024706f2543Smrg if (mask & CPPolyMode) 1025706f2543Smrg attribs.poly_mode = pPicture->polyMode; 1026706f2543Smrg if (mask & CPComponentAlpha) 1027706f2543Smrg attribs.component_alpha = pPicture->componentAlpha; 1028706f2543Smrg 1029706f2543Smrg XRenderChangePicture(dmxScreen->beDisplay, pPictPriv->pict, 1030706f2543Smrg mask, &attribs); 1031706f2543Smrg dmxSync(dmxScreen, FALSE); 1032706f2543Smrg } else { 1033706f2543Smrg pPictPriv->savedMask |= mask; 1034706f2543Smrg } 1035706f2543Smrg 1036706f2543Smrg#if 1 1037706f2543Smrg if (ps->ValidatePicture) 1038706f2543Smrg ps->ValidatePicture(pPicture, mask); 1039706f2543Smrg#endif 1040706f2543Smrg 1041706f2543Smrg DMX_WRAP(ValidatePicture, dmxValidatePicture, dmxScreen, ps); 1042706f2543Smrg} 1043706f2543Smrg 1044706f2543Smrg/** Composite a picture on the appropriate screen by combining the 1045706f2543Smrg * specified rectangle of the transformed src and mask operands with 1046706f2543Smrg * the specified rectangle of the dst using op as the compositing 1047706f2543Smrg * operator. For a complete description see the protocol document of 1048706f2543Smrg * the RENDER library. */ 1049706f2543Smrgvoid dmxComposite(CARD8 op, 1050706f2543Smrg PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, 1051706f2543Smrg INT16 xSrc, INT16 ySrc, 1052706f2543Smrg INT16 xMask, INT16 yMask, 1053706f2543Smrg INT16 xDst, INT16 yDst, 1054706f2543Smrg CARD16 width, CARD16 height) 1055706f2543Smrg{ 1056706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 1057706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 1058706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 1059706f2543Smrg dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc); 1060706f2543Smrg dmxPictPrivPtr pMaskPriv = NULL; 1061706f2543Smrg dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst); 1062706f2543Smrg 1063706f2543Smrg if (pMask) pMaskPriv = DMX_GET_PICT_PRIV(pMask); 1064706f2543Smrg 1065706f2543Smrg DMX_UNWRAP(Composite, dmxScreen, ps); 1066706f2543Smrg#if 0 1067706f2543Smrg if (ps->Composite) 1068706f2543Smrg ps->Composite(op, pSrc, pMask, pDst, 1069706f2543Smrg xSrc, ySrc, xMask, yMask, xDst, yDst, 1070706f2543Smrg width, height); 1071706f2543Smrg#endif 1072706f2543Smrg 1073706f2543Smrg /* Composite on back-end server */ 1074706f2543Smrg if (pSrcPriv->pict && pDstPriv->pict && 1075706f2543Smrg ((pMaskPriv && pMaskPriv->pict) || !pMaskPriv)) { 1076706f2543Smrg XRenderComposite(dmxScreen->beDisplay, 1077706f2543Smrg op, 1078706f2543Smrg pSrcPriv->pict, 1079706f2543Smrg pMaskPriv ? pMaskPriv->pict : None, 1080706f2543Smrg pDstPriv->pict, 1081706f2543Smrg xSrc, ySrc, 1082706f2543Smrg xMask, yMask, 1083706f2543Smrg xDst, yDst, 1084706f2543Smrg width, height); 1085706f2543Smrg dmxSync(dmxScreen, FALSE); 1086706f2543Smrg } 1087706f2543Smrg 1088706f2543Smrg 1089706f2543Smrg DMX_WRAP(Composite, dmxComposite, dmxScreen, ps); 1090706f2543Smrg} 1091706f2543Smrg 1092706f2543Smrg/** Null function to catch when/if RENDER calls lower level mi hooks. 1093706f2543Smrg * Compositing glyphs is handled by dmxProcRenderCompositeGlyphs(). 1094706f2543Smrg * This function should never be called. */ 1095706f2543Smrgvoid dmxGlyphs(CARD8 op, 1096706f2543Smrg PicturePtr pSrc, PicturePtr pDst, 1097706f2543Smrg PictFormatPtr maskFormat, 1098706f2543Smrg INT16 xSrc, INT16 ySrc, 1099706f2543Smrg int nlists, GlyphListPtr lists, GlyphPtr *glyphs) 1100706f2543Smrg{ 1101706f2543Smrg /* This won't work, so we need to wrap ProcRenderCompositeGlyphs */ 1102706f2543Smrg} 1103706f2543Smrg 1104706f2543Smrg/** Fill a rectangle on the appropriate screen by combining the color 1105706f2543Smrg * with the dest picture in the area specified by the list of 1106706f2543Smrg * rectangles. For a complete description see the protocol document of 1107706f2543Smrg * the RENDER library. */ 1108706f2543Smrgvoid dmxCompositeRects(CARD8 op, 1109706f2543Smrg PicturePtr pDst, 1110706f2543Smrg xRenderColor *color, 1111706f2543Smrg int nRect, xRectangle *rects) 1112706f2543Smrg{ 1113706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 1114706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 1115706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 1116706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pDst); 1117706f2543Smrg 1118706f2543Smrg DMX_UNWRAP(CompositeRects, dmxScreen, ps); 1119706f2543Smrg#if 0 1120706f2543Smrg if (ps->CompositeRects) 1121706f2543Smrg ps->CompositeRects(op, pDst, color, nRect, rects); 1122706f2543Smrg#endif 1123706f2543Smrg 1124706f2543Smrg /* CompositeRects on back-end server */ 1125706f2543Smrg if (pPictPriv->pict) { 1126706f2543Smrg XRenderFillRectangles(dmxScreen->beDisplay, 1127706f2543Smrg op, 1128706f2543Smrg pPictPriv->pict, 1129706f2543Smrg (XRenderColor *)color, 1130706f2543Smrg (XRectangle *)rects, 1131706f2543Smrg nRect); 1132706f2543Smrg dmxSync(dmxScreen, FALSE); 1133706f2543Smrg } 1134706f2543Smrg 1135706f2543Smrg DMX_WRAP(CompositeRects, dmxCompositeRects, dmxScreen, ps); 1136706f2543Smrg} 1137706f2543Smrg 1138706f2543Smrg/** Indexed color visuals are not yet supported. */ 1139706f2543SmrgBool dmxInitIndexed(ScreenPtr pScreen, PictFormatPtr pFormat) 1140706f2543Smrg{ 1141706f2543Smrg return TRUE; 1142706f2543Smrg} 1143706f2543Smrg 1144706f2543Smrg/** Indexed color visuals are not yet supported. */ 1145706f2543Smrgvoid dmxCloseIndexed(ScreenPtr pScreen, PictFormatPtr pFormat) 1146706f2543Smrg{ 1147706f2543Smrg} 1148706f2543Smrg 1149706f2543Smrg/** Indexed color visuals are not yet supported. */ 1150706f2543Smrgvoid dmxUpdateIndexed(ScreenPtr pScreen, PictFormatPtr pFormat, 1151706f2543Smrg int ndef, xColorItem *pdef) 1152706f2543Smrg{ 1153706f2543Smrg} 1154706f2543Smrg 1155706f2543Smrg/** Composite a list of trapezoids on the appropriate screen. For a 1156706f2543Smrg * complete description see the protocol document of the RENDER 1157706f2543Smrg * library. */ 1158706f2543Smrgvoid dmxTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, 1159706f2543Smrg PictFormatPtr maskFormat, 1160706f2543Smrg INT16 xSrc, INT16 ySrc, 1161706f2543Smrg int ntrap, xTrapezoid *traps) 1162706f2543Smrg{ 1163706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 1164706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 1165706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 1166706f2543Smrg dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc); 1167706f2543Smrg dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst); 1168706f2543Smrg 1169706f2543Smrg DMX_UNWRAP(Trapezoids, dmxScreen, ps); 1170706f2543Smrg#if 0 1171706f2543Smrg if (ps->Trapezoids) 1172706f2543Smrg ps->Trapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, *traps); 1173706f2543Smrg#endif 1174706f2543Smrg 1175706f2543Smrg /* Draw trapezoids on back-end server */ 1176706f2543Smrg if (pDstPriv->pict) { 1177706f2543Smrg XRenderPictFormat *pFormat; 1178706f2543Smrg 1179706f2543Smrg pFormat = dmxFindFormat(dmxScreen, maskFormat); 1180706f2543Smrg if (!pFormat) { 1181706f2543Smrg /* FIXME: Error! */ 1182706f2543Smrg } 1183706f2543Smrg 1184706f2543Smrg XRenderCompositeTrapezoids(dmxScreen->beDisplay, 1185706f2543Smrg op, 1186706f2543Smrg pSrcPriv->pict, 1187706f2543Smrg pDstPriv->pict, 1188706f2543Smrg pFormat, 1189706f2543Smrg xSrc, ySrc, 1190706f2543Smrg (XTrapezoid *)traps, 1191706f2543Smrg ntrap); 1192706f2543Smrg dmxSync(dmxScreen, FALSE); 1193706f2543Smrg } 1194706f2543Smrg 1195706f2543Smrg DMX_WRAP(Trapezoids, dmxTrapezoids, dmxScreen, ps); 1196706f2543Smrg} 1197706f2543Smrg 1198706f2543Smrg/** Composite a list of triangles on the appropriate screen. For a 1199706f2543Smrg * complete description see the protocol document of the RENDER 1200706f2543Smrg * library. */ 1201706f2543Smrgvoid dmxTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst, 1202706f2543Smrg PictFormatPtr maskFormat, 1203706f2543Smrg INT16 xSrc, INT16 ySrc, 1204706f2543Smrg int ntri, xTriangle *tris) 1205706f2543Smrg{ 1206706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 1207706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 1208706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 1209706f2543Smrg dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc); 1210706f2543Smrg dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst); 1211706f2543Smrg 1212706f2543Smrg DMX_UNWRAP(Triangles, dmxScreen, ps); 1213706f2543Smrg#if 0 1214706f2543Smrg if (ps->Triangles) 1215706f2543Smrg ps->Triangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, *tris); 1216706f2543Smrg#endif 1217706f2543Smrg 1218706f2543Smrg /* Draw trapezoids on back-end server */ 1219706f2543Smrg if (pDstPriv->pict) { 1220706f2543Smrg XRenderPictFormat *pFormat; 1221706f2543Smrg 1222706f2543Smrg pFormat = dmxFindFormat(dmxScreen, maskFormat); 1223706f2543Smrg if (!pFormat) { 1224706f2543Smrg /* FIXME: Error! */ 1225706f2543Smrg } 1226706f2543Smrg 1227706f2543Smrg XRenderCompositeTriangles(dmxScreen->beDisplay, 1228706f2543Smrg op, 1229706f2543Smrg pSrcPriv->pict, 1230706f2543Smrg pDstPriv->pict, 1231706f2543Smrg pFormat, 1232706f2543Smrg xSrc, ySrc, 1233706f2543Smrg (XTriangle *)tris, 1234706f2543Smrg ntri); 1235706f2543Smrg dmxSync(dmxScreen, FALSE); 1236706f2543Smrg } 1237706f2543Smrg 1238706f2543Smrg DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps); 1239706f2543Smrg} 1240706f2543Smrg 1241706f2543Smrg/** Composite a triangle strip on the appropriate screen. For a 1242706f2543Smrg * complete description see the protocol document of the RENDER 1243706f2543Smrg * library. */ 1244706f2543Smrgvoid dmxTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst, 1245706f2543Smrg PictFormatPtr maskFormat, 1246706f2543Smrg INT16 xSrc, INT16 ySrc, 1247706f2543Smrg int npoint, xPointFixed *points) 1248706f2543Smrg{ 1249706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 1250706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 1251706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 1252706f2543Smrg dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc); 1253706f2543Smrg dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst); 1254706f2543Smrg 1255706f2543Smrg DMX_UNWRAP(TriStrip, dmxScreen, ps); 1256706f2543Smrg#if 0 1257706f2543Smrg if (ps->TriStrip) 1258706f2543Smrg ps->TriStrip(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points); 1259706f2543Smrg#endif 1260706f2543Smrg 1261706f2543Smrg /* Draw trapezoids on back-end server */ 1262706f2543Smrg if (pDstPriv->pict) { 1263706f2543Smrg XRenderPictFormat *pFormat; 1264706f2543Smrg 1265706f2543Smrg pFormat = dmxFindFormat(dmxScreen, maskFormat); 1266706f2543Smrg if (!pFormat) { 1267706f2543Smrg /* FIXME: Error! */ 1268706f2543Smrg } 1269706f2543Smrg 1270706f2543Smrg XRenderCompositeTriStrip(dmxScreen->beDisplay, 1271706f2543Smrg op, 1272706f2543Smrg pSrcPriv->pict, 1273706f2543Smrg pDstPriv->pict, 1274706f2543Smrg pFormat, 1275706f2543Smrg xSrc, ySrc, 1276706f2543Smrg (XPointFixed *)points, 1277706f2543Smrg npoint); 1278706f2543Smrg dmxSync(dmxScreen, FALSE); 1279706f2543Smrg } 1280706f2543Smrg 1281706f2543Smrg DMX_WRAP(TriStrip, dmxTriStrip, dmxScreen, ps); 1282706f2543Smrg} 1283706f2543Smrg 1284706f2543Smrg/** Composite a triangle fan on the appropriate screen. For a complete 1285706f2543Smrg * description see the protocol document of the RENDER library. */ 1286706f2543Smrgvoid dmxTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst, 1287706f2543Smrg PictFormatPtr maskFormat, 1288706f2543Smrg INT16 xSrc, INT16 ySrc, 1289706f2543Smrg int npoint, xPointFixed *points) 1290706f2543Smrg{ 1291706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 1292706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 1293706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 1294706f2543Smrg dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc); 1295706f2543Smrg dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst); 1296706f2543Smrg 1297706f2543Smrg DMX_UNWRAP(TriFan, dmxScreen, ps); 1298706f2543Smrg#if 0 1299706f2543Smrg if (ps->TriFan) 1300706f2543Smrg ps->TriFan(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points); 1301706f2543Smrg#endif 1302706f2543Smrg 1303706f2543Smrg /* Draw trapezoids on back-end server */ 1304706f2543Smrg if (pDstPriv->pict) { 1305706f2543Smrg XRenderPictFormat *pFormat; 1306706f2543Smrg 1307706f2543Smrg pFormat = dmxFindFormat(dmxScreen, maskFormat); 1308706f2543Smrg if (!pFormat) { 1309706f2543Smrg /* FIXME: Error! */ 1310706f2543Smrg } 1311706f2543Smrg 1312706f2543Smrg XRenderCompositeTriFan(dmxScreen->beDisplay, 1313706f2543Smrg op, 1314706f2543Smrg pSrcPriv->pict, 1315706f2543Smrg pDstPriv->pict, 1316706f2543Smrg pFormat, 1317706f2543Smrg xSrc, ySrc, 1318706f2543Smrg (XPointFixed *)points, 1319706f2543Smrg npoint); 1320706f2543Smrg dmxSync(dmxScreen, FALSE); 1321706f2543Smrg } 1322706f2543Smrg 1323706f2543Smrg DMX_WRAP(TriFan, dmxTriFan, dmxScreen, ps); 1324706f2543Smrg} 1325