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; 68948a68b89Smrg if (nparams < 0) 69048a68b89Smrg return BadLength; 691706f2543Smrg 692706f2543Smrg XRenderSetPictureFilter(dmxScreen->beDisplay, 693706f2543Smrg pPictPriv->pict, 694706f2543Smrg filter, 695706f2543Smrg params, 696706f2543Smrg nparams); 697706f2543Smrg dmxSync(dmxScreen, FALSE); 698706f2543Smrg } 699706f2543Smrg 700706f2543Smrg return dmxSaveRenderVector[stuff->renderReqType](client); 701706f2543Smrg} 702706f2543Smrg 703706f2543Smrg 704706f2543Smrg/** Create a picture on the appropriate screen. This is the actual 705706f2543Smrg * function that creates the picture. However, if the associated 706706f2543Smrg * window has not yet been created due to lazy window creation, then 707706f2543Smrg * delay the picture creation until the window is mapped. */ 708706f2543Smrgstatic Picture dmxDoCreatePicture(PicturePtr pPicture) 709706f2543Smrg{ 710706f2543Smrg DrawablePtr pDraw = pPicture->pDrawable; 711706f2543Smrg ScreenPtr pScreen = pDraw->pScreen; 712706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 713706f2543Smrg XRenderPictFormat *pFormat; 714706f2543Smrg Drawable draw; 715706f2543Smrg 716706f2543Smrg if (pPicture->pDrawable->type == DRAWABLE_WINDOW) { 717706f2543Smrg dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV((WindowPtr)(pDraw)); 718706f2543Smrg 719706f2543Smrg if (!(draw = pWinPriv->window)) { 720706f2543Smrg /* Window has not been created yet due to the window 721706f2543Smrg * optimization. Delay picture creation until window is 722706f2543Smrg * mapped. 723706f2543Smrg */ 724706f2543Smrg pWinPriv->hasPict = TRUE; 725706f2543Smrg return 0; 726706f2543Smrg } 727706f2543Smrg } else { 728706f2543Smrg dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV((PixmapPtr)(pDraw)); 729706f2543Smrg 730706f2543Smrg if (!(draw = pPixPriv->pixmap)) { 731706f2543Smrg /* FIXME: Zero width/height pixmap?? */ 732706f2543Smrg return 0; 733706f2543Smrg } 734706f2543Smrg } 735706f2543Smrg 736706f2543Smrg /* This should not be reached if the back-end display has been 737706f2543Smrg * detached because the pWinPriv->window or the pPixPriv->pixmap 738706f2543Smrg * will be NULL; however, we add it here for completeness 739706f2543Smrg */ 740706f2543Smrg if (!dmxScreen->beDisplay) 741706f2543Smrg return 0; 742706f2543Smrg 743706f2543Smrg pFormat = dmxFindFormat(dmxScreen, pPicture->pFormat); 744706f2543Smrg 745706f2543Smrg return XRenderCreatePicture(dmxScreen->beDisplay, draw, pFormat, 0, 0); 746706f2543Smrg} 747706f2543Smrg 748706f2543Smrg/** Create a list of pictures. This function is called by 749706f2543Smrg * dmxCreateAndRealizeWindow() during the lazy window creation 750706f2543Smrg * realization process. It creates the entire list of pictures that 751706f2543Smrg * are associated with the given window. */ 752706f2543Smrgvoid dmxCreatePictureList(WindowPtr pWindow) 753706f2543Smrg{ 754706f2543Smrg PicturePtr pPicture = GetPictureWindow(pWindow); 755706f2543Smrg 756706f2543Smrg while (pPicture) { 757706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 758706f2543Smrg 759706f2543Smrg /* Create the picture for this window */ 760706f2543Smrg pPictPriv->pict = dmxDoCreatePicture(pPicture); 761706f2543Smrg 762706f2543Smrg /* ValidatePicture takes care of the state changes */ 763706f2543Smrg 764706f2543Smrg pPicture = pPicture->pNext; 765706f2543Smrg } 766706f2543Smrg} 767706f2543Smrg 768706f2543Smrg/** Create \a pPicture on the backend. */ 769706f2543Smrgint dmxBECreatePicture(PicturePtr pPicture) 770706f2543Smrg{ 771706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 772706f2543Smrg 773706f2543Smrg /* Create picutre on BE */ 774706f2543Smrg pPictPriv->pict = dmxDoCreatePicture(pPicture); 775706f2543Smrg 776706f2543Smrg /* Flush changes to the backend server */ 777706f2543Smrg dmxValidatePicture(pPicture, (1 << (CPLastBit+1)) - 1); 778706f2543Smrg 779706f2543Smrg return Success; 780706f2543Smrg} 781706f2543Smrg 782706f2543Smrg/** Create a picture. This function handles the CreatePicture 783706f2543Smrg * unwrapping/wrapping and calls dmxDoCreatePicture to actually create 784706f2543Smrg * the picture on the appropriate screen. */ 785706f2543Smrgint dmxCreatePicture(PicturePtr pPicture) 786706f2543Smrg{ 787706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 788706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 789706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 790706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 791706f2543Smrg int ret = Success; 792706f2543Smrg 793706f2543Smrg DMX_UNWRAP(CreatePicture, dmxScreen, ps); 794706f2543Smrg#if 1 795706f2543Smrg if (ps->CreatePicture) 796706f2543Smrg ret = ps->CreatePicture(pPicture); 797706f2543Smrg#endif 798706f2543Smrg 799706f2543Smrg /* Create picture on back-end server */ 800706f2543Smrg pPictPriv->pict = dmxDoCreatePicture(pPicture); 801706f2543Smrg pPictPriv->savedMask = 0; 802706f2543Smrg 803706f2543Smrg DMX_WRAP(CreatePicture, dmxCreatePicture, dmxScreen, ps); 804706f2543Smrg 805706f2543Smrg return ret; 806706f2543Smrg} 807706f2543Smrg 808706f2543Smrg/** Destroy \a pPicture on the back-end server. */ 809706f2543SmrgBool dmxBEFreePicture(PicturePtr pPicture) 810706f2543Smrg{ 811706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 812706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 813706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 814706f2543Smrg 815706f2543Smrg if (pPictPriv->pict) { 816706f2543Smrg XRenderFreePicture(dmxScreen->beDisplay, pPictPriv->pict); 817706f2543Smrg pPictPriv->pict = (Picture)0; 818706f2543Smrg return TRUE; 819706f2543Smrg } 820706f2543Smrg 821706f2543Smrg return FALSE; 822706f2543Smrg} 823706f2543Smrg 824706f2543Smrg/** Destroy a list of pictures that are associated with the window that 825706f2543Smrg * is being destroyed. This function is called by #dmxDestroyWindow(). 826706f2543Smrg * */ 827706f2543SmrgBool dmxDestroyPictureList(WindowPtr pWindow) 828706f2543Smrg{ 829706f2543Smrg PicturePtr pPicture = GetPictureWindow(pWindow); 830706f2543Smrg Bool ret = FALSE; 831706f2543Smrg 832706f2543Smrg while (pPicture) { 833706f2543Smrg ret |= dmxBEFreePicture(pPicture); 834706f2543Smrg pPicture = pPicture->pNext; 835706f2543Smrg } 836706f2543Smrg 837706f2543Smrg return ret; 838706f2543Smrg} 839706f2543Smrg 840706f2543Smrg/** Destroy a picture. This function calls the wrapped function that 841706f2543Smrg * frees the resources in the DMX server associated with this 842706f2543Smrg * picture. */ 843706f2543Smrgvoid dmxDestroyPicture(PicturePtr pPicture) 844706f2543Smrg{ 845706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 846706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 847706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 848706f2543Smrg 849706f2543Smrg DMX_UNWRAP(DestroyPicture, dmxScreen, ps); 850706f2543Smrg 851706f2543Smrg /* Destroy picture on back-end server */ 852706f2543Smrg if (dmxBEFreePicture(pPicture)) 853706f2543Smrg dmxSync(dmxScreen, FALSE); 854706f2543Smrg 855706f2543Smrg#if 1 856706f2543Smrg if (ps->DestroyPicture) 857706f2543Smrg ps->DestroyPicture(pPicture); 858706f2543Smrg#endif 859706f2543Smrg DMX_WRAP(DestroyPicture, dmxDestroyPicture, dmxScreen, ps); 860706f2543Smrg} 861706f2543Smrg 862706f2543Smrg/** Change the picture's list of clip rectangles. */ 863706f2543Smrgint dmxChangePictureClip(PicturePtr pPicture, int clipType, 864706f2543Smrg pointer value, int n) 865706f2543Smrg{ 866706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 867706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 868706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 869706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 870706f2543Smrg 871706f2543Smrg DMX_UNWRAP(ChangePictureClip, dmxScreen, ps); 872706f2543Smrg#if 1 873706f2543Smrg if (ps->ChangePictureClip) 874706f2543Smrg ps->ChangePictureClip(pPicture, clipType, value, n); 875706f2543Smrg#endif 876706f2543Smrg 877706f2543Smrg /* Change picture clip rects on back-end server */ 878706f2543Smrg if (pPictPriv->pict) { 879706f2543Smrg /* The clip has already been changed into a region by the mi 880706f2543Smrg * routine called above. 881706f2543Smrg */ 882706f2543Smrg if (clipType == CT_NONE) { 883706f2543Smrg /* Disable clipping, show all */ 884706f2543Smrg XFixesSetPictureClipRegion(dmxScreen->beDisplay, 885706f2543Smrg pPictPriv->pict, 0, 0, None); 886706f2543Smrg } else if (pPicture->clientClip) { 887706f2543Smrg RegionPtr pClip = pPicture->clientClip; 888706f2543Smrg BoxPtr pBox = RegionRects(pClip); 889706f2543Smrg int nBox = RegionNumRects(pClip); 890706f2543Smrg XRectangle *pRects; 891706f2543Smrg XRectangle *pRect; 892706f2543Smrg int nRects; 893706f2543Smrg 894706f2543Smrg nRects = nBox; 895706f2543Smrg pRects = pRect = malloc(nRects * sizeof(*pRect)); 896706f2543Smrg 897706f2543Smrg while (nBox--) { 898706f2543Smrg pRect->x = pBox->x1; 899706f2543Smrg pRect->y = pBox->y1; 900706f2543Smrg pRect->width = pBox->x2 - pBox->x1; 901706f2543Smrg pRect->height = pBox->y2 - pBox->y1; 902706f2543Smrg pBox++; 903706f2543Smrg pRect++; 904706f2543Smrg } 905706f2543Smrg 906706f2543Smrg XRenderSetPictureClipRectangles(dmxScreen->beDisplay, 907706f2543Smrg pPictPriv->pict, 908706f2543Smrg 0, 0, 909706f2543Smrg pRects, 910706f2543Smrg nRects); 911706f2543Smrg free(pRects); 912706f2543Smrg } else { 913706f2543Smrg XRenderSetPictureClipRectangles(dmxScreen->beDisplay, 914706f2543Smrg pPictPriv->pict, 915706f2543Smrg 0, 0, NULL, 0); 916706f2543Smrg } 917706f2543Smrg dmxSync(dmxScreen, FALSE); 918706f2543Smrg } else { 919706f2543Smrg /* FIXME: Handle saving clip region when offscreen */ 920706f2543Smrg } 921706f2543Smrg 922706f2543Smrg DMX_WRAP(ChangePictureClip, dmxChangePictureClip, dmxScreen, ps); 923706f2543Smrg 924706f2543Smrg return Success; 925706f2543Smrg} 926706f2543Smrg 927706f2543Smrg/** Destroy the picture's list of clip rectangles. */ 928706f2543Smrgvoid dmxDestroyPictureClip(PicturePtr pPicture) 929706f2543Smrg{ 930706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 931706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 932706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 933706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 934706f2543Smrg 935706f2543Smrg DMX_UNWRAP(DestroyPictureClip, dmxScreen, ps); 936706f2543Smrg#if 1 937706f2543Smrg if (ps->DestroyPictureClip) 938706f2543Smrg ps->DestroyPictureClip(pPicture); 939706f2543Smrg#endif 940706f2543Smrg 941706f2543Smrg /* Destroy picture clip rects on back-end server */ 942706f2543Smrg if (pPictPriv->pict) { 943706f2543Smrg XRenderSetPictureClipRectangles(dmxScreen->beDisplay, 944706f2543Smrg pPictPriv->pict, 945706f2543Smrg 0, 0, NULL, 0); 946706f2543Smrg dmxSync(dmxScreen, FALSE); 947706f2543Smrg } else { 948706f2543Smrg /* FIXME: Handle destroying clip region when offscreen */ 949706f2543Smrg } 950706f2543Smrg 951706f2543Smrg DMX_WRAP(DestroyPictureClip, dmxDestroyPictureClip, dmxScreen, ps); 952706f2543Smrg} 953706f2543Smrg 954706f2543Smrg/** Change the attributes of the pictures. If the picture has not yet 955706f2543Smrg * been created due to lazy window creation, save the mask so that it 956706f2543Smrg * can be used to appropriately initialize the picture's attributes 957706f2543Smrg * when it is created later. */ 958706f2543Smrgvoid dmxChangePicture(PicturePtr pPicture, Mask mask) 959706f2543Smrg{ 960706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 961706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 962706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 963706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 964706f2543Smrg 965706f2543Smrg DMX_UNWRAP(ChangePicture, dmxScreen, ps); 966706f2543Smrg#if 1 967706f2543Smrg if (ps->ChangePicture) 968706f2543Smrg ps->ChangePicture(pPicture, mask); 969706f2543Smrg#endif 970706f2543Smrg 971706f2543Smrg /* Picture attribute changes are handled in ValidatePicture */ 972706f2543Smrg pPictPriv->savedMask |= mask; 973706f2543Smrg 974706f2543Smrg DMX_WRAP(ChangePicture, dmxChangePicture, dmxScreen, ps); 975706f2543Smrg} 976706f2543Smrg 977706f2543Smrg/** Validate the picture's attributes before rendering to it. Update 978706f2543Smrg * any picture attributes that have been changed by one of the higher 979706f2543Smrg * layers. */ 980706f2543Smrgvoid dmxValidatePicture(PicturePtr pPicture, Mask mask) 981706f2543Smrg{ 982706f2543Smrg ScreenPtr pScreen = pPicture->pDrawable->pScreen; 983706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 984706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 985706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); 986706f2543Smrg 987706f2543Smrg DMX_UNWRAP(ValidatePicture, dmxScreen, ps); 988706f2543Smrg 989706f2543Smrg /* Change picture attributes on back-end server */ 990706f2543Smrg if (pPictPriv->pict) { 991706f2543Smrg XRenderPictureAttributes attribs; 992706f2543Smrg 993706f2543Smrg if (mask & CPRepeat) { 994706f2543Smrg attribs.repeat = pPicture->repeatType; 995706f2543Smrg } 996706f2543Smrg if (mask & CPAlphaMap) { 997706f2543Smrg if (pPicture->alphaMap) { 998706f2543Smrg dmxPictPrivPtr pAlphaPriv; 999706f2543Smrg pAlphaPriv = DMX_GET_PICT_PRIV(pPicture->alphaMap); 1000706f2543Smrg if (pAlphaPriv->pict) { 1001706f2543Smrg attribs.alpha_map = pAlphaPriv->pict; 1002706f2543Smrg } else { 1003706f2543Smrg /* FIXME: alpha picture drawable has not been created?? */ 1004706f2543Smrg return; /* or should this be: attribs.alpha_map = None; */ 1005706f2543Smrg } 1006706f2543Smrg } else { 1007706f2543Smrg attribs.alpha_map = None; 1008706f2543Smrg } 1009706f2543Smrg } 1010706f2543Smrg if (mask & CPAlphaXOrigin) 1011706f2543Smrg attribs.alpha_x_origin = pPicture->alphaOrigin.x; 1012706f2543Smrg if (mask & CPAlphaYOrigin) 1013706f2543Smrg attribs.alpha_y_origin = pPicture->alphaOrigin.y; 1014706f2543Smrg if (mask & CPClipXOrigin) 1015706f2543Smrg attribs.clip_x_origin = pPicture->clipOrigin.x; 1016706f2543Smrg if (mask & CPClipYOrigin) 1017706f2543Smrg attribs.clip_y_origin = pPicture->clipOrigin.y; 1018706f2543Smrg if (mask & CPClipMask) 1019706f2543Smrg mask &= ~CPClipMask; /* Handled in ChangePictureClip */ 1020706f2543Smrg if (mask & CPGraphicsExposure) 1021706f2543Smrg attribs.graphics_exposures = pPicture->graphicsExposures; 1022706f2543Smrg if (mask & CPSubwindowMode) 1023706f2543Smrg attribs.subwindow_mode = pPicture->subWindowMode; 1024706f2543Smrg if (mask & CPPolyEdge) 1025706f2543Smrg attribs.poly_edge = pPicture->polyEdge; 1026706f2543Smrg if (mask & CPPolyMode) 1027706f2543Smrg attribs.poly_mode = pPicture->polyMode; 1028706f2543Smrg if (mask & CPComponentAlpha) 1029706f2543Smrg attribs.component_alpha = pPicture->componentAlpha; 1030706f2543Smrg 1031706f2543Smrg XRenderChangePicture(dmxScreen->beDisplay, pPictPriv->pict, 1032706f2543Smrg mask, &attribs); 1033706f2543Smrg dmxSync(dmxScreen, FALSE); 1034706f2543Smrg } else { 1035706f2543Smrg pPictPriv->savedMask |= mask; 1036706f2543Smrg } 1037706f2543Smrg 1038706f2543Smrg#if 1 1039706f2543Smrg if (ps->ValidatePicture) 1040706f2543Smrg ps->ValidatePicture(pPicture, mask); 1041706f2543Smrg#endif 1042706f2543Smrg 1043706f2543Smrg DMX_WRAP(ValidatePicture, dmxValidatePicture, dmxScreen, ps); 1044706f2543Smrg} 1045706f2543Smrg 1046706f2543Smrg/** Composite a picture on the appropriate screen by combining the 1047706f2543Smrg * specified rectangle of the transformed src and mask operands with 1048706f2543Smrg * the specified rectangle of the dst using op as the compositing 1049706f2543Smrg * operator. For a complete description see the protocol document of 1050706f2543Smrg * the RENDER library. */ 1051706f2543Smrgvoid dmxComposite(CARD8 op, 1052706f2543Smrg PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, 1053706f2543Smrg INT16 xSrc, INT16 ySrc, 1054706f2543Smrg INT16 xMask, INT16 yMask, 1055706f2543Smrg INT16 xDst, INT16 yDst, 1056706f2543Smrg CARD16 width, CARD16 height) 1057706f2543Smrg{ 1058706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 1059706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 1060706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 1061706f2543Smrg dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc); 1062706f2543Smrg dmxPictPrivPtr pMaskPriv = NULL; 1063706f2543Smrg dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst); 1064706f2543Smrg 1065706f2543Smrg if (pMask) pMaskPriv = DMX_GET_PICT_PRIV(pMask); 1066706f2543Smrg 1067706f2543Smrg DMX_UNWRAP(Composite, dmxScreen, ps); 1068706f2543Smrg#if 0 1069706f2543Smrg if (ps->Composite) 1070706f2543Smrg ps->Composite(op, pSrc, pMask, pDst, 1071706f2543Smrg xSrc, ySrc, xMask, yMask, xDst, yDst, 1072706f2543Smrg width, height); 1073706f2543Smrg#endif 1074706f2543Smrg 1075706f2543Smrg /* Composite on back-end server */ 1076706f2543Smrg if (pSrcPriv->pict && pDstPriv->pict && 1077706f2543Smrg ((pMaskPriv && pMaskPriv->pict) || !pMaskPriv)) { 1078706f2543Smrg XRenderComposite(dmxScreen->beDisplay, 1079706f2543Smrg op, 1080706f2543Smrg pSrcPriv->pict, 1081706f2543Smrg pMaskPriv ? pMaskPriv->pict : None, 1082706f2543Smrg pDstPriv->pict, 1083706f2543Smrg xSrc, ySrc, 1084706f2543Smrg xMask, yMask, 1085706f2543Smrg xDst, yDst, 1086706f2543Smrg width, height); 1087706f2543Smrg dmxSync(dmxScreen, FALSE); 1088706f2543Smrg } 1089706f2543Smrg 1090706f2543Smrg 1091706f2543Smrg DMX_WRAP(Composite, dmxComposite, dmxScreen, ps); 1092706f2543Smrg} 1093706f2543Smrg 1094706f2543Smrg/** Null function to catch when/if RENDER calls lower level mi hooks. 1095706f2543Smrg * Compositing glyphs is handled by dmxProcRenderCompositeGlyphs(). 1096706f2543Smrg * This function should never be called. */ 1097706f2543Smrgvoid dmxGlyphs(CARD8 op, 1098706f2543Smrg PicturePtr pSrc, PicturePtr pDst, 1099706f2543Smrg PictFormatPtr maskFormat, 1100706f2543Smrg INT16 xSrc, INT16 ySrc, 1101706f2543Smrg int nlists, GlyphListPtr lists, GlyphPtr *glyphs) 1102706f2543Smrg{ 1103706f2543Smrg /* This won't work, so we need to wrap ProcRenderCompositeGlyphs */ 1104706f2543Smrg} 1105706f2543Smrg 1106706f2543Smrg/** Fill a rectangle on the appropriate screen by combining the color 1107706f2543Smrg * with the dest picture in the area specified by the list of 1108706f2543Smrg * rectangles. For a complete description see the protocol document of 1109706f2543Smrg * the RENDER library. */ 1110706f2543Smrgvoid dmxCompositeRects(CARD8 op, 1111706f2543Smrg PicturePtr pDst, 1112706f2543Smrg xRenderColor *color, 1113706f2543Smrg int nRect, xRectangle *rects) 1114706f2543Smrg{ 1115706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 1116706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 1117706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 1118706f2543Smrg dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pDst); 1119706f2543Smrg 1120706f2543Smrg DMX_UNWRAP(CompositeRects, dmxScreen, ps); 1121706f2543Smrg#if 0 1122706f2543Smrg if (ps->CompositeRects) 1123706f2543Smrg ps->CompositeRects(op, pDst, color, nRect, rects); 1124706f2543Smrg#endif 1125706f2543Smrg 1126706f2543Smrg /* CompositeRects on back-end server */ 1127706f2543Smrg if (pPictPriv->pict) { 1128706f2543Smrg XRenderFillRectangles(dmxScreen->beDisplay, 1129706f2543Smrg op, 1130706f2543Smrg pPictPriv->pict, 1131706f2543Smrg (XRenderColor *)color, 1132706f2543Smrg (XRectangle *)rects, 1133706f2543Smrg nRect); 1134706f2543Smrg dmxSync(dmxScreen, FALSE); 1135706f2543Smrg } 1136706f2543Smrg 1137706f2543Smrg DMX_WRAP(CompositeRects, dmxCompositeRects, dmxScreen, ps); 1138706f2543Smrg} 1139706f2543Smrg 1140706f2543Smrg/** Indexed color visuals are not yet supported. */ 1141706f2543SmrgBool dmxInitIndexed(ScreenPtr pScreen, PictFormatPtr pFormat) 1142706f2543Smrg{ 1143706f2543Smrg return TRUE; 1144706f2543Smrg} 1145706f2543Smrg 1146706f2543Smrg/** Indexed color visuals are not yet supported. */ 1147706f2543Smrgvoid dmxCloseIndexed(ScreenPtr pScreen, PictFormatPtr pFormat) 1148706f2543Smrg{ 1149706f2543Smrg} 1150706f2543Smrg 1151706f2543Smrg/** Indexed color visuals are not yet supported. */ 1152706f2543Smrgvoid dmxUpdateIndexed(ScreenPtr pScreen, PictFormatPtr pFormat, 1153706f2543Smrg int ndef, xColorItem *pdef) 1154706f2543Smrg{ 1155706f2543Smrg} 1156706f2543Smrg 1157706f2543Smrg/** Composite a list of trapezoids on the appropriate screen. For a 1158706f2543Smrg * complete description see the protocol document of the RENDER 1159706f2543Smrg * library. */ 1160706f2543Smrgvoid dmxTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, 1161706f2543Smrg PictFormatPtr maskFormat, 1162706f2543Smrg INT16 xSrc, INT16 ySrc, 1163706f2543Smrg int ntrap, xTrapezoid *traps) 1164706f2543Smrg{ 1165706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 1166706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 1167706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 1168706f2543Smrg dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc); 1169706f2543Smrg dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst); 1170706f2543Smrg 1171706f2543Smrg DMX_UNWRAP(Trapezoids, dmxScreen, ps); 1172706f2543Smrg#if 0 1173706f2543Smrg if (ps->Trapezoids) 1174706f2543Smrg ps->Trapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, *traps); 1175706f2543Smrg#endif 1176706f2543Smrg 1177706f2543Smrg /* Draw trapezoids on back-end server */ 1178706f2543Smrg if (pDstPriv->pict) { 1179706f2543Smrg XRenderPictFormat *pFormat; 1180706f2543Smrg 1181706f2543Smrg pFormat = dmxFindFormat(dmxScreen, maskFormat); 1182706f2543Smrg if (!pFormat) { 1183706f2543Smrg /* FIXME: Error! */ 1184706f2543Smrg } 1185706f2543Smrg 1186706f2543Smrg XRenderCompositeTrapezoids(dmxScreen->beDisplay, 1187706f2543Smrg op, 1188706f2543Smrg pSrcPriv->pict, 1189706f2543Smrg pDstPriv->pict, 1190706f2543Smrg pFormat, 1191706f2543Smrg xSrc, ySrc, 1192706f2543Smrg (XTrapezoid *)traps, 1193706f2543Smrg ntrap); 1194706f2543Smrg dmxSync(dmxScreen, FALSE); 1195706f2543Smrg } 1196706f2543Smrg 1197706f2543Smrg DMX_WRAP(Trapezoids, dmxTrapezoids, dmxScreen, ps); 1198706f2543Smrg} 1199706f2543Smrg 1200706f2543Smrg/** Composite a list of triangles on the appropriate screen. For a 1201706f2543Smrg * complete description see the protocol document of the RENDER 1202706f2543Smrg * library. */ 1203706f2543Smrgvoid dmxTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst, 1204706f2543Smrg PictFormatPtr maskFormat, 1205706f2543Smrg INT16 xSrc, INT16 ySrc, 1206706f2543Smrg int ntri, xTriangle *tris) 1207706f2543Smrg{ 1208706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 1209706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 1210706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 1211706f2543Smrg dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc); 1212706f2543Smrg dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst); 1213706f2543Smrg 1214706f2543Smrg DMX_UNWRAP(Triangles, dmxScreen, ps); 1215706f2543Smrg#if 0 1216706f2543Smrg if (ps->Triangles) 1217706f2543Smrg ps->Triangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, *tris); 1218706f2543Smrg#endif 1219706f2543Smrg 1220706f2543Smrg /* Draw trapezoids on back-end server */ 1221706f2543Smrg if (pDstPriv->pict) { 1222706f2543Smrg XRenderPictFormat *pFormat; 1223706f2543Smrg 1224706f2543Smrg pFormat = dmxFindFormat(dmxScreen, maskFormat); 1225706f2543Smrg if (!pFormat) { 1226706f2543Smrg /* FIXME: Error! */ 1227706f2543Smrg } 1228706f2543Smrg 1229706f2543Smrg XRenderCompositeTriangles(dmxScreen->beDisplay, 1230706f2543Smrg op, 1231706f2543Smrg pSrcPriv->pict, 1232706f2543Smrg pDstPriv->pict, 1233706f2543Smrg pFormat, 1234706f2543Smrg xSrc, ySrc, 1235706f2543Smrg (XTriangle *)tris, 1236706f2543Smrg ntri); 1237706f2543Smrg dmxSync(dmxScreen, FALSE); 1238706f2543Smrg } 1239706f2543Smrg 1240706f2543Smrg DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps); 1241706f2543Smrg} 1242706f2543Smrg 1243706f2543Smrg/** Composite a triangle strip on the appropriate screen. For a 1244706f2543Smrg * complete description see the protocol document of the RENDER 1245706f2543Smrg * library. */ 1246706f2543Smrgvoid dmxTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst, 1247706f2543Smrg PictFormatPtr maskFormat, 1248706f2543Smrg INT16 xSrc, INT16 ySrc, 1249706f2543Smrg int npoint, xPointFixed *points) 1250706f2543Smrg{ 1251706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 1252706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 1253706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 1254706f2543Smrg dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc); 1255706f2543Smrg dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst); 1256706f2543Smrg 1257706f2543Smrg DMX_UNWRAP(TriStrip, dmxScreen, ps); 1258706f2543Smrg#if 0 1259706f2543Smrg if (ps->TriStrip) 1260706f2543Smrg ps->TriStrip(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points); 1261706f2543Smrg#endif 1262706f2543Smrg 1263706f2543Smrg /* Draw trapezoids on back-end server */ 1264706f2543Smrg if (pDstPriv->pict) { 1265706f2543Smrg XRenderPictFormat *pFormat; 1266706f2543Smrg 1267706f2543Smrg pFormat = dmxFindFormat(dmxScreen, maskFormat); 1268706f2543Smrg if (!pFormat) { 1269706f2543Smrg /* FIXME: Error! */ 1270706f2543Smrg } 1271706f2543Smrg 1272706f2543Smrg XRenderCompositeTriStrip(dmxScreen->beDisplay, 1273706f2543Smrg op, 1274706f2543Smrg pSrcPriv->pict, 1275706f2543Smrg pDstPriv->pict, 1276706f2543Smrg pFormat, 1277706f2543Smrg xSrc, ySrc, 1278706f2543Smrg (XPointFixed *)points, 1279706f2543Smrg npoint); 1280706f2543Smrg dmxSync(dmxScreen, FALSE); 1281706f2543Smrg } 1282706f2543Smrg 1283706f2543Smrg DMX_WRAP(TriStrip, dmxTriStrip, dmxScreen, ps); 1284706f2543Smrg} 1285706f2543Smrg 1286706f2543Smrg/** Composite a triangle fan on the appropriate screen. For a complete 1287706f2543Smrg * description see the protocol document of the RENDER library. */ 1288706f2543Smrgvoid dmxTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst, 1289706f2543Smrg PictFormatPtr maskFormat, 1290706f2543Smrg INT16 xSrc, INT16 ySrc, 1291706f2543Smrg int npoint, xPointFixed *points) 1292706f2543Smrg{ 1293706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 1294706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 1295706f2543Smrg PictureScreenPtr ps = GetPictureScreen(pScreen); 1296706f2543Smrg dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc); 1297706f2543Smrg dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst); 1298706f2543Smrg 1299706f2543Smrg DMX_UNWRAP(TriFan, dmxScreen, ps); 1300706f2543Smrg#if 0 1301706f2543Smrg if (ps->TriFan) 1302706f2543Smrg ps->TriFan(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points); 1303706f2543Smrg#endif 1304706f2543Smrg 1305706f2543Smrg /* Draw trapezoids on back-end server */ 1306706f2543Smrg if (pDstPriv->pict) { 1307706f2543Smrg XRenderPictFormat *pFormat; 1308706f2543Smrg 1309706f2543Smrg pFormat = dmxFindFormat(dmxScreen, maskFormat); 1310706f2543Smrg if (!pFormat) { 1311706f2543Smrg /* FIXME: Error! */ 1312706f2543Smrg } 1313706f2543Smrg 1314706f2543Smrg XRenderCompositeTriFan(dmxScreen->beDisplay, 1315706f2543Smrg op, 1316706f2543Smrg pSrcPriv->pict, 1317706f2543Smrg pDstPriv->pict, 1318706f2543Smrg pFormat, 1319706f2543Smrg xSrc, ySrc, 1320706f2543Smrg (XPointFixed *)points, 1321706f2543Smrg npoint); 1322706f2543Smrg dmxSync(dmxScreen, FALSE); 1323706f2543Smrg } 1324706f2543Smrg 1325706f2543Smrg DMX_WRAP(TriFan, dmxTriFan, dmxScreen, ps); 1326706f2543Smrg} 1327