dmxpict.c 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277
  1. /*
  2. * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
  3. *
  4. * All Rights Reserved.
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining
  7. * a copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation on the rights to use, copy, modify, merge,
  10. * publish, distribute, sublicense, and/or sell copies of the Software,
  11. * and to permit persons to whom the Software is furnished to do so,
  12. * subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice (including the
  15. * next paragraph) shall be included in all copies or substantial
  16. * portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
  22. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  23. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  25. * SOFTWARE.
  26. */
  27. /*
  28. * Authors:
  29. * Kevin E. Martin <kem@redhat.com>
  30. *
  31. */
  32. /** \file
  33. * Provide support for the RENDER extension (version 0.8).
  34. */
  35. #ifdef HAVE_DMX_CONFIG_H
  36. #include <dmx-config.h>
  37. #endif
  38. #include "dmx.h"
  39. #include "dmxsync.h"
  40. #include "dmxpict.h"
  41. #include "dmxwindow.h"
  42. #include "dmxpixmap.h"
  43. #include "fb.h"
  44. #include "pixmapstr.h"
  45. #include "dixstruct.h"
  46. #include <X11/extensions/render.h>
  47. #include <X11/extensions/renderproto.h>
  48. #include <X11/extensions/Xfixes.h>
  49. #include "picture.h"
  50. #include "picturestr.h"
  51. #include "mipict.h"
  52. #include "fbpict.h"
  53. extern int RenderErrBase;
  54. extern int (*ProcRenderVector[RenderNumberRequests]) (ClientPtr);
  55. static int (*dmxSaveRenderVector[RenderNumberRequests]) (ClientPtr);
  56. static int dmxProcRenderCreateGlyphSet(ClientPtr client);
  57. static int dmxProcRenderFreeGlyphSet(ClientPtr client);
  58. static int dmxProcRenderAddGlyphs(ClientPtr client);
  59. static int dmxProcRenderFreeGlyphs(ClientPtr client);
  60. static int dmxProcRenderCompositeGlyphs(ClientPtr client);
  61. static int dmxProcRenderSetPictureTransform(ClientPtr client);
  62. static int dmxProcRenderSetPictureFilter(ClientPtr client);
  63. #if 0
  64. /* FIXME: Not (yet) supported */
  65. static int dmxProcRenderCreateCursor(ClientPtr client);
  66. static int dmxProcRenderCreateAnimCursor(ClientPtr client);
  67. #endif
  68. /** Catch errors that might occur when allocating Glyph Sets. Errors
  69. * are saved in dmxGlyphLastError for later handling. */
  70. static int dmxGlyphLastError;
  71. static int
  72. dmxGlyphErrorHandler(Display * dpy, XErrorEvent * ev)
  73. {
  74. dmxGlyphLastError = ev->error_code;
  75. return 0;
  76. }
  77. /** Initialize the Proc Vector for the RENDER extension. The functions
  78. * here cannot be handled by the mi layer RENDER hooks either because
  79. * the required information is no longer available when it reaches the
  80. * mi layer or no mi layer hooks exist. This function is called from
  81. * InitOutput() since it should be initialized only once per server
  82. * generation. */
  83. void
  84. dmxInitRender(void)
  85. {
  86. int i;
  87. for (i = 0; i < RenderNumberRequests; i++)
  88. dmxSaveRenderVector[i] = ProcRenderVector[i];
  89. ProcRenderVector[X_RenderCreateGlyphSet]
  90. = dmxProcRenderCreateGlyphSet;
  91. ProcRenderVector[X_RenderFreeGlyphSet]
  92. = dmxProcRenderFreeGlyphSet;
  93. ProcRenderVector[X_RenderAddGlyphs]
  94. = dmxProcRenderAddGlyphs;
  95. ProcRenderVector[X_RenderFreeGlyphs]
  96. = dmxProcRenderFreeGlyphs;
  97. ProcRenderVector[X_RenderCompositeGlyphs8]
  98. = dmxProcRenderCompositeGlyphs;
  99. ProcRenderVector[X_RenderCompositeGlyphs16]
  100. = dmxProcRenderCompositeGlyphs;
  101. ProcRenderVector[X_RenderCompositeGlyphs32]
  102. = dmxProcRenderCompositeGlyphs;
  103. ProcRenderVector[X_RenderSetPictureTransform]
  104. = dmxProcRenderSetPictureTransform;
  105. ProcRenderVector[X_RenderSetPictureFilter]
  106. = dmxProcRenderSetPictureFilter;
  107. }
  108. /** Reset the Proc Vector for the RENDER extension back to the original
  109. * functions. This function is called from dmxCloseScreen() during the
  110. * server reset (only for screen #0). */
  111. void
  112. dmxResetRender(void)
  113. {
  114. int i;
  115. for (i = 0; i < RenderNumberRequests; i++)
  116. ProcRenderVector[i] = dmxSaveRenderVector[i];
  117. }
  118. /** Initialize the RENDER extension, allocate the picture privates and
  119. * wrap mi function hooks. If the shadow frame buffer is used, then
  120. * call the appropriate fb initialization function. */
  121. Bool
  122. dmxPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
  123. {
  124. DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
  125. PictureScreenPtr ps;
  126. if (!miPictureInit(pScreen, formats, nformats))
  127. return FALSE;
  128. if (!dixRegisterPrivateKey
  129. (&dmxPictPrivateKeyRec, PRIVATE_PICTURE, sizeof(dmxPictPrivRec)))
  130. return FALSE;
  131. ps = GetPictureScreen(pScreen);
  132. DMX_WRAP(CreatePicture, dmxCreatePicture, dmxScreen, ps);
  133. DMX_WRAP(DestroyPicture, dmxDestroyPicture, dmxScreen, ps);
  134. DMX_WRAP(ChangePictureClip, dmxChangePictureClip, dmxScreen, ps);
  135. DMX_WRAP(DestroyPictureClip, dmxDestroyPictureClip, dmxScreen, ps);
  136. DMX_WRAP(ChangePicture, dmxChangePicture, dmxScreen, ps);
  137. DMX_WRAP(ValidatePicture, dmxValidatePicture, dmxScreen, ps);
  138. DMX_WRAP(Composite, dmxComposite, dmxScreen, ps);
  139. DMX_WRAP(Glyphs, dmxGlyphs, dmxScreen, ps);
  140. DMX_WRAP(CompositeRects, dmxCompositeRects, dmxScreen, ps);
  141. DMX_WRAP(Trapezoids, dmxTrapezoids, dmxScreen, ps);
  142. DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps);
  143. return TRUE;
  144. }
  145. /** Find the appropriate format on the requested screen given the
  146. * internal format requested. The list of formats is searched
  147. * sequentially as the XRenderFindFormat() function does not always
  148. * find the appropriate format when a specific format is requested. */
  149. static XRenderPictFormat *
  150. dmxFindFormat(DMXScreenInfo * dmxScreen, PictFormatPtr pFmt)
  151. {
  152. XRenderPictFormat *pFormat = NULL;
  153. int i = 0;
  154. if (!pFmt || !dmxScreen->beDisplay)
  155. return pFormat;
  156. while (1) {
  157. pFormat = XRenderFindFormat(dmxScreen->beDisplay, 0, 0, i++);
  158. if (!pFormat)
  159. break;
  160. if (pFormat->type != pFmt->type)
  161. continue;
  162. if (pFormat->depth != pFmt->depth)
  163. continue;
  164. if (pFormat->direct.red != pFmt->direct.red)
  165. continue;
  166. if (pFormat->direct.redMask != pFmt->direct.redMask)
  167. continue;
  168. if (pFormat->direct.green != pFmt->direct.green)
  169. continue;
  170. if (pFormat->direct.greenMask != pFmt->direct.greenMask)
  171. continue;
  172. if (pFormat->direct.blue != pFmt->direct.blue)
  173. continue;
  174. if (pFormat->direct.blueMask != pFmt->direct.blueMask)
  175. continue;
  176. if (pFormat->direct.alpha != pFmt->direct.alpha)
  177. continue;
  178. if (pFormat->direct.alphaMask != pFmt->direct.alphaMask)
  179. continue;
  180. /* We have a match! */
  181. break;
  182. }
  183. return pFormat;
  184. }
  185. /** Free \a glyphSet on back-end screen number \a idx. */
  186. Bool
  187. dmxBEFreeGlyphSet(ScreenPtr pScreen, GlyphSetPtr glyphSet)
  188. {
  189. dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
  190. int idx = pScreen->myNum;
  191. DMXScreenInfo *dmxScreen = &dmxScreens[idx];
  192. if (glyphPriv->glyphSets[idx]) {
  193. XRenderFreeGlyphSet(dmxScreen->beDisplay, glyphPriv->glyphSets[idx]);
  194. glyphPriv->glyphSets[idx] = (GlyphSet) 0;
  195. return TRUE;
  196. }
  197. return FALSE;
  198. }
  199. /** Create \a glyphSet on the backend screen number \a idx. */
  200. int
  201. dmxBECreateGlyphSet(int idx, GlyphSetPtr glyphSet)
  202. {
  203. XRenderPictFormat *pFormat;
  204. DMXScreenInfo *dmxScreen = &dmxScreens[idx];
  205. dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
  206. PictFormatPtr pFmt = glyphSet->format;
  207. int (*oldErrorHandler) (Display *, XErrorEvent *);
  208. pFormat = dmxFindFormat(dmxScreen, pFmt);
  209. if (!pFormat) {
  210. return BadMatch;
  211. }
  212. dmxGlyphLastError = 0;
  213. oldErrorHandler = XSetErrorHandler(dmxGlyphErrorHandler);
  214. /* Catch when this fails */
  215. glyphPriv->glyphSets[idx]
  216. = XRenderCreateGlyphSet(dmxScreen->beDisplay, pFormat);
  217. XSetErrorHandler(oldErrorHandler);
  218. if (dmxGlyphLastError) {
  219. return dmxGlyphLastError;
  220. }
  221. return Success;
  222. }
  223. /** Create a Glyph Set on each screen. Save the glyphset ID from each
  224. * screen in the Glyph Set's private structure. Fail if the format
  225. * requested is not available or if the Glyph Set cannot be created on
  226. * the screen. */
  227. static int
  228. dmxProcRenderCreateGlyphSet(ClientPtr client)
  229. {
  230. int ret;
  231. REQUEST(xRenderCreateGlyphSetReq);
  232. ret = dmxSaveRenderVector[stuff->renderReqType] (client);
  233. if (ret == Success) {
  234. GlyphSetPtr glyphSet;
  235. dmxGlyphPrivPtr glyphPriv;
  236. int i;
  237. /* Look up glyphSet that was just created ???? */
  238. /* Store glyphsets from backends in glyphSet->devPrivate ????? */
  239. /* Make sure we handle all errors here!! */
  240. dixLookupResourceByType((void **) &glyphSet,
  241. stuff->gsid, GlyphSetType,
  242. client, DixDestroyAccess);
  243. glyphPriv = malloc(sizeof(dmxGlyphPrivRec));
  244. if (!glyphPriv)
  245. return BadAlloc;
  246. glyphPriv->glyphSets = NULL;
  247. MAXSCREENSALLOC_RETURN(glyphPriv->glyphSets, BadAlloc);
  248. DMX_SET_GLYPH_PRIV(glyphSet, glyphPriv);
  249. for (i = 0; i < dmxNumScreens; i++) {
  250. DMXScreenInfo *dmxScreen = &dmxScreens[i];
  251. int beret;
  252. if (!dmxScreen->beDisplay) {
  253. glyphPriv->glyphSets[i] = 0;
  254. continue;
  255. }
  256. if ((beret = dmxBECreateGlyphSet(i, glyphSet)) != Success) {
  257. int j;
  258. /* Free the glyph sets we've allocated thus far */
  259. for (j = 0; j < i; j++)
  260. dmxBEFreeGlyphSet(screenInfo.screens[j], glyphSet);
  261. /* Free the resource created by render */
  262. FreeResource(stuff->gsid, RT_NONE);
  263. return beret;
  264. }
  265. }
  266. }
  267. return ret;
  268. }
  269. /** Free the previously allocated Glyph Sets for each screen. */
  270. static int
  271. dmxProcRenderFreeGlyphSet(ClientPtr client)
  272. {
  273. GlyphSetPtr glyphSet;
  274. REQUEST(xRenderFreeGlyphSetReq);
  275. REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
  276. dixLookupResourceByType((void **) &glyphSet,
  277. stuff->glyphset, GlyphSetType,
  278. client, DixDestroyAccess);
  279. if (glyphSet && glyphSet->refcnt == 1) {
  280. dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
  281. int i;
  282. for (i = 0; i < dmxNumScreens; i++) {
  283. DMXScreenInfo *dmxScreen = &dmxScreens[i];
  284. if (dmxScreen->beDisplay) {
  285. if (dmxBEFreeGlyphSet(screenInfo.screens[i], glyphSet))
  286. dmxSync(dmxScreen, FALSE);
  287. }
  288. }
  289. MAXSCREENSFREE(glyphPriv->glyphSets);
  290. free(glyphPriv);
  291. DMX_SET_GLYPH_PRIV(glyphSet, NULL);
  292. }
  293. return dmxSaveRenderVector[stuff->renderReqType] (client);
  294. }
  295. /** Add glyphs to the Glyph Set on each screen. */
  296. static int
  297. dmxProcRenderAddGlyphs(ClientPtr client)
  298. {
  299. int ret;
  300. REQUEST(xRenderAddGlyphsReq);
  301. ret = dmxSaveRenderVector[stuff->renderReqType] (client);
  302. if (ret == Success) {
  303. GlyphSetPtr glyphSet;
  304. dmxGlyphPrivPtr glyphPriv;
  305. int i;
  306. int nglyphs;
  307. CARD32 *gids;
  308. Glyph *gidsCopy;
  309. xGlyphInfo *gi;
  310. CARD8 *bits;
  311. int nbytes;
  312. dixLookupResourceByType((void **) &glyphSet,
  313. stuff->glyphset, GlyphSetType,
  314. client, DixReadAccess);
  315. glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
  316. nglyphs = stuff->nglyphs;
  317. gids = (CARD32 *) (stuff + 1);
  318. gi = (xGlyphInfo *) (gids + nglyphs);
  319. bits = (CARD8 *) (gi + nglyphs);
  320. nbytes = ((stuff->length << 2) -
  321. sizeof(xRenderAddGlyphsReq) -
  322. (sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs);
  323. gidsCopy = malloc(sizeof(*gidsCopy) * nglyphs);
  324. for (i = 0; i < nglyphs; i++)
  325. gidsCopy[i] = gids[i];
  326. /* FIXME: Will this ever fail? */
  327. for (i = 0; i < dmxNumScreens; i++) {
  328. DMXScreenInfo *dmxScreen = &dmxScreens[i];
  329. if (dmxScreen->beDisplay) {
  330. XRenderAddGlyphs(dmxScreen->beDisplay,
  331. glyphPriv->glyphSets[i],
  332. gidsCopy,
  333. (XGlyphInfo *) gi,
  334. nglyphs, (char *) bits, nbytes);
  335. dmxSync(dmxScreen, FALSE);
  336. }
  337. }
  338. free(gidsCopy);
  339. }
  340. return ret;
  341. }
  342. /** Free glyphs from the Glyph Set for each screen. */
  343. static int
  344. dmxProcRenderFreeGlyphs(ClientPtr client)
  345. {
  346. GlyphSetPtr glyphSet;
  347. REQUEST(xRenderFreeGlyphsReq);
  348. REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
  349. dixLookupResourceByType((void **) &glyphSet,
  350. stuff->glyphset, GlyphSetType,
  351. client, DixWriteAccess);
  352. if (glyphSet) {
  353. dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
  354. int i;
  355. int nglyphs;
  356. Glyph *gids;
  357. nglyphs = ((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq)) >> 2;
  358. if (nglyphs) {
  359. gids = malloc(sizeof(*gids) * nglyphs);
  360. for (i = 0; i < nglyphs; i++)
  361. gids[i] = ((CARD32 *) (stuff + 1))[i];
  362. for (i = 0; i < dmxNumScreens; i++) {
  363. DMXScreenInfo *dmxScreen = &dmxScreens[i];
  364. if (dmxScreen->beDisplay) {
  365. XRenderFreeGlyphs(dmxScreen->beDisplay,
  366. glyphPriv->glyphSets[i], gids, nglyphs);
  367. dmxSync(dmxScreen, FALSE);
  368. }
  369. }
  370. free(gids);
  371. }
  372. }
  373. return dmxSaveRenderVector[stuff->renderReqType] (client);
  374. }
  375. /** Composite glyphs on each screen into the requested picture. If
  376. * either the src or dest picture has not been allocated due to lazy
  377. * window creation, this request will gracefully return. */
  378. static int
  379. dmxProcRenderCompositeGlyphs(ClientPtr client)
  380. {
  381. int ret;
  382. REQUEST(xRenderCompositeGlyphsReq);
  383. ret = dmxSaveRenderVector[stuff->renderReqType] (client);
  384. /* For the following to work with PanoramiX, it assumes that Render
  385. * wraps the ProcRenderVector after dmxRenderInit has been called.
  386. */
  387. if (ret == Success) {
  388. PicturePtr pSrc;
  389. dmxPictPrivPtr pSrcPriv;
  390. PicturePtr pDst;
  391. dmxPictPrivPtr pDstPriv;
  392. PictFormatPtr pFmt;
  393. XRenderPictFormat *pFormat;
  394. int size;
  395. int scrnNum;
  396. DMXScreenInfo *dmxScreen;
  397. CARD8 *buffer;
  398. CARD8 *end;
  399. int space;
  400. int nglyph;
  401. char *glyphs;
  402. char *curGlyph;
  403. xGlyphElt *elt;
  404. int nelt;
  405. XGlyphElt8 *elts;
  406. XGlyphElt8 *curElt;
  407. GlyphSetPtr glyphSet;
  408. dmxGlyphPrivPtr glyphPriv;
  409. dixLookupResourceByType((void **) &pSrc,
  410. stuff->src, PictureType, client, DixReadAccess);
  411. pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
  412. if (!pSrcPriv->pict)
  413. return ret;
  414. dixLookupResourceByType((void **) &pDst,
  415. stuff->dst, PictureType,
  416. client, DixWriteAccess);
  417. pDstPriv = DMX_GET_PICT_PRIV(pDst);
  418. if (!pDstPriv->pict)
  419. return ret;
  420. scrnNum = pDst->pDrawable->pScreen->myNum;
  421. dmxScreen = &dmxScreens[scrnNum];
  422. /* Note: If the back-end display has been detached, then it
  423. * should not be possible to reach here since the pSrcPriv->pict
  424. * and pDstPriv->pict will have already been set to 0.
  425. */
  426. if (!dmxScreen->beDisplay)
  427. return ret;
  428. if (stuff->maskFormat)
  429. dixLookupResourceByType((void **) &pFmt,
  430. stuff->maskFormat, PictFormatType,
  431. client, DixReadAccess);
  432. else
  433. pFmt = NULL;
  434. pFormat = dmxFindFormat(dmxScreen, pFmt);
  435. switch (stuff->renderReqType) {
  436. case X_RenderCompositeGlyphs8:
  437. size = sizeof(CARD8);
  438. break;
  439. case X_RenderCompositeGlyphs16:
  440. size = sizeof(CARD16);
  441. break;
  442. case X_RenderCompositeGlyphs32:
  443. size = sizeof(CARD32);
  444. break;
  445. default:
  446. return BadPictOp; /* Can't happen */
  447. }
  448. buffer = (CARD8 *) (stuff + 1);
  449. end = (CARD8 *) stuff + (stuff->length << 2);
  450. nelt = 0;
  451. nglyph = 0;
  452. while (buffer + sizeof(xGlyphElt) < end) {
  453. elt = (xGlyphElt *) buffer;
  454. buffer += sizeof(xGlyphElt);
  455. if (elt->len == 0xff) {
  456. buffer += 4;
  457. }
  458. else {
  459. nelt++;
  460. nglyph += elt->len;
  461. space = size * elt->len;
  462. if (space & 3)
  463. space += 4 - (space & 3);
  464. buffer += space;
  465. }
  466. }
  467. /* The following only works for Render version > 0.2 */
  468. /* All of the XGlyphElt* structure sizes are identical */
  469. elts = malloc(nelt * sizeof(XGlyphElt8));
  470. if (!elts)
  471. return BadAlloc;
  472. glyphs = malloc(nglyph * size);
  473. if (!glyphs) {
  474. free(elts);
  475. return BadAlloc;
  476. }
  477. buffer = (CARD8 *) (stuff + 1);
  478. end = (CARD8 *) stuff + (stuff->length << 2);
  479. curGlyph = glyphs;
  480. curElt = elts;
  481. dixLookupResourceByType((void **) &glyphSet,
  482. stuff->glyphset, GlyphSetType,
  483. client, DixReadAccess);
  484. glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
  485. while (buffer + sizeof(xGlyphElt) < end) {
  486. elt = (xGlyphElt *) buffer;
  487. buffer += sizeof(xGlyphElt);
  488. if (elt->len == 0xff) {
  489. dixLookupResourceByType((void **) &glyphSet,
  490. *((CARD32 *) buffer),
  491. GlyphSetType, client, DixReadAccess);
  492. glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
  493. buffer += 4;
  494. }
  495. else {
  496. curElt->glyphset = glyphPriv->glyphSets[scrnNum];
  497. curElt->xOff = elt->deltax;
  498. curElt->yOff = elt->deltay;
  499. curElt->nchars = elt->len;
  500. curElt->chars = curGlyph;
  501. memcpy(curGlyph, buffer, size * elt->len);
  502. curGlyph += size * elt->len;
  503. curElt++;
  504. space = size * elt->len;
  505. if (space & 3)
  506. space += 4 - (space & 3);
  507. buffer += space;
  508. }
  509. }
  510. switch (stuff->renderReqType) {
  511. case X_RenderCompositeGlyphs8:
  512. XRenderCompositeText8(dmxScreen->beDisplay, stuff->op,
  513. pSrcPriv->pict, pDstPriv->pict,
  514. pFormat,
  515. stuff->xSrc, stuff->ySrc, 0, 0, elts, nelt);
  516. break;
  517. case X_RenderCompositeGlyphs16:
  518. XRenderCompositeText16(dmxScreen->beDisplay, stuff->op,
  519. pSrcPriv->pict, pDstPriv->pict,
  520. pFormat,
  521. stuff->xSrc, stuff->ySrc,
  522. 0, 0, (XGlyphElt16 *) elts, nelt);
  523. break;
  524. case X_RenderCompositeGlyphs32:
  525. XRenderCompositeText32(dmxScreen->beDisplay, stuff->op,
  526. pSrcPriv->pict, pDstPriv->pict,
  527. pFormat,
  528. stuff->xSrc, stuff->ySrc,
  529. 0, 0, (XGlyphElt32 *) elts, nelt);
  530. break;
  531. }
  532. dmxSync(dmxScreen, FALSE);
  533. free(elts);
  534. free(glyphs);
  535. }
  536. return ret;
  537. }
  538. /** Set the picture transform on each screen. */
  539. static int
  540. dmxProcRenderSetPictureTransform(ClientPtr client)
  541. {
  542. DMXScreenInfo *dmxScreen;
  543. PicturePtr pPicture;
  544. dmxPictPrivPtr pPictPriv;
  545. XTransform xform;
  546. REQUEST(xRenderSetPictureTransformReq);
  547. REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
  548. VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess);
  549. /* For the following to work with PanoramiX, it assumes that Render
  550. * wraps the ProcRenderVector after dmxRenderInit has been called.
  551. */
  552. dmxScreen = &dmxScreens[pPicture->pDrawable->pScreen->myNum];
  553. pPictPriv = DMX_GET_PICT_PRIV(pPicture);
  554. if (pPictPriv->pict) {
  555. xform.matrix[0][0] = stuff->transform.matrix11;
  556. xform.matrix[0][1] = stuff->transform.matrix12;
  557. xform.matrix[0][2] = stuff->transform.matrix13;
  558. xform.matrix[1][0] = stuff->transform.matrix21;
  559. xform.matrix[1][1] = stuff->transform.matrix22;
  560. xform.matrix[1][2] = stuff->transform.matrix23;
  561. xform.matrix[2][0] = stuff->transform.matrix31;
  562. xform.matrix[2][1] = stuff->transform.matrix32;
  563. xform.matrix[2][2] = stuff->transform.matrix33;
  564. XRenderSetPictureTransform(dmxScreen->beDisplay,
  565. pPictPriv->pict, &xform);
  566. dmxSync(dmxScreen, FALSE);
  567. }
  568. return dmxSaveRenderVector[stuff->renderReqType] (client);
  569. }
  570. /** Set the picture filter on each screen. */
  571. static int
  572. dmxProcRenderSetPictureFilter(ClientPtr client)
  573. {
  574. DMXScreenInfo *dmxScreen;
  575. PicturePtr pPicture;
  576. dmxPictPrivPtr pPictPriv;
  577. char *filter;
  578. XFixed *params;
  579. int nparams;
  580. REQUEST(xRenderSetPictureFilterReq);
  581. REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
  582. VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess);
  583. /* For the following to work with PanoramiX, it assumes that Render
  584. * wraps the ProcRenderVector after dmxRenderInit has been called.
  585. */
  586. dmxScreen = &dmxScreens[pPicture->pDrawable->pScreen->myNum];
  587. pPictPriv = DMX_GET_PICT_PRIV(pPicture);
  588. if (pPictPriv->pict) {
  589. filter = (char *) (stuff + 1);
  590. params = (XFixed *) (filter + ((stuff->nbytes + 3) & ~3));
  591. nparams = ((XFixed *) stuff + client->req_len) - params;
  592. XRenderSetPictureFilter(dmxScreen->beDisplay,
  593. pPictPriv->pict, filter, params, nparams);
  594. dmxSync(dmxScreen, FALSE);
  595. }
  596. return dmxSaveRenderVector[stuff->renderReqType] (client);
  597. }
  598. /** Create a picture on the appropriate screen. This is the actual
  599. * function that creates the picture. However, if the associated
  600. * window has not yet been created due to lazy window creation, then
  601. * delay the picture creation until the window is mapped. */
  602. static Picture
  603. dmxDoCreatePicture(PicturePtr pPicture)
  604. {
  605. DrawablePtr pDraw = pPicture->pDrawable;
  606. ScreenPtr pScreen = pDraw->pScreen;
  607. DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
  608. XRenderPictFormat *pFormat;
  609. Drawable draw;
  610. if (pPicture->pDrawable->type == DRAWABLE_WINDOW) {
  611. dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV((WindowPtr) (pDraw));
  612. if (!(draw = pWinPriv->window)) {
  613. /* Window has not been created yet due to the window
  614. * optimization. Delay picture creation until window is
  615. * mapped.
  616. */
  617. pWinPriv->hasPict = TRUE;
  618. return 0;
  619. }
  620. }
  621. else {
  622. dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV((PixmapPtr) (pDraw));
  623. if (!(draw = pPixPriv->pixmap)) {
  624. /* FIXME: Zero width/height pixmap?? */
  625. return 0;
  626. }
  627. }
  628. /* This should not be reached if the back-end display has been
  629. * detached because the pWinPriv->window or the pPixPriv->pixmap
  630. * will be NULL; however, we add it here for completeness
  631. */
  632. if (!dmxScreen->beDisplay)
  633. return 0;
  634. pFormat = dmxFindFormat(dmxScreen, pPicture->pFormat);
  635. return XRenderCreatePicture(dmxScreen->beDisplay, draw, pFormat, 0, 0);
  636. }
  637. /** Create a list of pictures. This function is called by
  638. * dmxCreateAndRealizeWindow() during the lazy window creation
  639. * realization process. It creates the entire list of pictures that
  640. * are associated with the given window. */
  641. void
  642. dmxCreatePictureList(WindowPtr pWindow)
  643. {
  644. PicturePtr pPicture = GetPictureWindow(pWindow);
  645. while (pPicture) {
  646. dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
  647. /* Create the picture for this window */
  648. pPictPriv->pict = dmxDoCreatePicture(pPicture);
  649. /* ValidatePicture takes care of the state changes */
  650. pPicture = pPicture->pNext;
  651. }
  652. }
  653. /** Create \a pPicture on the backend. */
  654. int
  655. dmxBECreatePicture(PicturePtr pPicture)
  656. {
  657. dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
  658. /* Create picutre on BE */
  659. pPictPriv->pict = dmxDoCreatePicture(pPicture);
  660. /* Flush changes to the backend server */
  661. dmxValidatePicture(pPicture, (1 << (CPLastBit + 1)) - 1);
  662. return Success;
  663. }
  664. /** Create a picture. This function handles the CreatePicture
  665. * unwrapping/wrapping and calls dmxDoCreatePicture to actually create
  666. * the picture on the appropriate screen. */
  667. int
  668. dmxCreatePicture(PicturePtr pPicture)
  669. {
  670. ScreenPtr pScreen = pPicture->pDrawable->pScreen;
  671. DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
  672. PictureScreenPtr ps = GetPictureScreen(pScreen);
  673. dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
  674. int ret = Success;
  675. DMX_UNWRAP(CreatePicture, dmxScreen, ps);
  676. #if 1
  677. if (ps->CreatePicture)
  678. ret = ps->CreatePicture(pPicture);
  679. #endif
  680. /* Create picture on back-end server */
  681. pPictPriv->pict = dmxDoCreatePicture(pPicture);
  682. pPictPriv->savedMask = 0;
  683. DMX_WRAP(CreatePicture, dmxCreatePicture, dmxScreen, ps);
  684. return ret;
  685. }
  686. /** Destroy \a pPicture on the back-end server. */
  687. Bool
  688. dmxBEFreePicture(PicturePtr pPicture)
  689. {
  690. ScreenPtr pScreen = pPicture->pDrawable->pScreen;
  691. DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
  692. dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
  693. if (pPictPriv->pict) {
  694. XRenderFreePicture(dmxScreen->beDisplay, pPictPriv->pict);
  695. pPictPriv->pict = (Picture) 0;
  696. return TRUE;
  697. }
  698. return FALSE;
  699. }
  700. /** Destroy a list of pictures that are associated with the window that
  701. * is being destroyed. This function is called by #dmxDestroyWindow().
  702. * */
  703. Bool
  704. dmxDestroyPictureList(WindowPtr pWindow)
  705. {
  706. PicturePtr pPicture = GetPictureWindow(pWindow);
  707. Bool ret = FALSE;
  708. while (pPicture) {
  709. ret |= dmxBEFreePicture(pPicture);
  710. pPicture = pPicture->pNext;
  711. }
  712. return ret;
  713. }
  714. /** Destroy a picture. This function calls the wrapped function that
  715. * frees the resources in the DMX server associated with this
  716. * picture. */
  717. void
  718. dmxDestroyPicture(PicturePtr pPicture)
  719. {
  720. ScreenPtr pScreen = pPicture->pDrawable->pScreen;
  721. DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
  722. PictureScreenPtr ps = GetPictureScreen(pScreen);
  723. DMX_UNWRAP(DestroyPicture, dmxScreen, ps);
  724. /* Destroy picture on back-end server */
  725. if (dmxBEFreePicture(pPicture))
  726. dmxSync(dmxScreen, FALSE);
  727. #if 1
  728. if (ps->DestroyPicture)
  729. ps->DestroyPicture(pPicture);
  730. #endif
  731. DMX_WRAP(DestroyPicture, dmxDestroyPicture, dmxScreen, ps);
  732. }
  733. /** Change the picture's list of clip rectangles. */
  734. int
  735. dmxChangePictureClip(PicturePtr pPicture, int clipType, void *value, int n)
  736. {
  737. ScreenPtr pScreen = pPicture->pDrawable->pScreen;
  738. DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
  739. PictureScreenPtr ps = GetPictureScreen(pScreen);
  740. dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
  741. DMX_UNWRAP(ChangePictureClip, dmxScreen, ps);
  742. #if 1
  743. if (ps->ChangePictureClip)
  744. ps->ChangePictureClip(pPicture, clipType, value, n);
  745. #endif
  746. /* Change picture clip rects on back-end server */
  747. if (pPictPriv->pict) {
  748. /* The clip has already been changed into a region by the mi
  749. * routine called above.
  750. */
  751. if (clipType == CT_NONE) {
  752. /* Disable clipping, show all */
  753. XFixesSetPictureClipRegion(dmxScreen->beDisplay,
  754. pPictPriv->pict, 0, 0, None);
  755. }
  756. else if (pPicture->clientClip) {
  757. RegionPtr pClip = pPicture->clientClip;
  758. BoxPtr pBox = RegionRects(pClip);
  759. int nBox = RegionNumRects(pClip);
  760. XRectangle *pRects;
  761. XRectangle *pRect;
  762. int nRects;
  763. nRects = nBox;
  764. pRects = pRect = malloc(nRects * sizeof(*pRect));
  765. while (nBox--) {
  766. pRect->x = pBox->x1;
  767. pRect->y = pBox->y1;
  768. pRect->width = pBox->x2 - pBox->x1;
  769. pRect->height = pBox->y2 - pBox->y1;
  770. pBox++;
  771. pRect++;
  772. }
  773. XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
  774. pPictPriv->pict,
  775. 0, 0, pRects, nRects);
  776. free(pRects);
  777. }
  778. else {
  779. XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
  780. pPictPriv->pict, 0, 0, NULL, 0);
  781. }
  782. dmxSync(dmxScreen, FALSE);
  783. }
  784. else {
  785. /* FIXME: Handle saving clip region when offscreen */
  786. }
  787. DMX_WRAP(ChangePictureClip, dmxChangePictureClip, dmxScreen, ps);
  788. return Success;
  789. }
  790. /** Destroy the picture's list of clip rectangles. */
  791. void
  792. dmxDestroyPictureClip(PicturePtr pPicture)
  793. {
  794. ScreenPtr pScreen = pPicture->pDrawable->pScreen;
  795. DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
  796. PictureScreenPtr ps = GetPictureScreen(pScreen);
  797. dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
  798. DMX_UNWRAP(DestroyPictureClip, dmxScreen, ps);
  799. #if 1
  800. if (ps->DestroyPictureClip)
  801. ps->DestroyPictureClip(pPicture);
  802. #endif
  803. /* Destroy picture clip rects on back-end server */
  804. if (pPictPriv->pict) {
  805. XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
  806. pPictPriv->pict, 0, 0, NULL, 0);
  807. dmxSync(dmxScreen, FALSE);
  808. }
  809. else {
  810. /* FIXME: Handle destroying clip region when offscreen */
  811. }
  812. DMX_WRAP(DestroyPictureClip, dmxDestroyPictureClip, dmxScreen, ps);
  813. }
  814. /** Change the attributes of the pictures. If the picture has not yet
  815. * been created due to lazy window creation, save the mask so that it
  816. * can be used to appropriately initialize the picture's attributes
  817. * when it is created later. */
  818. void
  819. dmxChangePicture(PicturePtr pPicture, Mask mask)
  820. {
  821. ScreenPtr pScreen = pPicture->pDrawable->pScreen;
  822. DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
  823. PictureScreenPtr ps = GetPictureScreen(pScreen);
  824. dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
  825. DMX_UNWRAP(ChangePicture, dmxScreen, ps);
  826. #if 1
  827. if (ps->ChangePicture)
  828. ps->ChangePicture(pPicture, mask);
  829. #endif
  830. /* Picture attribute changes are handled in ValidatePicture */
  831. pPictPriv->savedMask |= mask;
  832. DMX_WRAP(ChangePicture, dmxChangePicture, dmxScreen, ps);
  833. }
  834. /** Validate the picture's attributes before rendering to it. Update
  835. * any picture attributes that have been changed by one of the higher
  836. * layers. */
  837. void
  838. dmxValidatePicture(PicturePtr pPicture, Mask mask)
  839. {
  840. ScreenPtr pScreen = pPicture->pDrawable->pScreen;
  841. DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
  842. PictureScreenPtr ps = GetPictureScreen(pScreen);
  843. dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
  844. DMX_UNWRAP(ValidatePicture, dmxScreen, ps);
  845. /* Change picture attributes on back-end server */
  846. if (pPictPriv->pict) {
  847. XRenderPictureAttributes attribs;
  848. if (mask & CPRepeat) {
  849. attribs.repeat = pPicture->repeatType;
  850. }
  851. if (mask & CPAlphaMap) {
  852. if (pPicture->alphaMap) {
  853. dmxPictPrivPtr pAlphaPriv;
  854. pAlphaPriv = DMX_GET_PICT_PRIV(pPicture->alphaMap);
  855. if (pAlphaPriv->pict) {
  856. attribs.alpha_map = pAlphaPriv->pict;
  857. }
  858. else {
  859. /* FIXME: alpha picture drawable has not been created?? */
  860. return; /* or should this be: attribs.alpha_map = None; */
  861. }
  862. }
  863. else {
  864. attribs.alpha_map = None;
  865. }
  866. }
  867. if (mask & CPAlphaXOrigin)
  868. attribs.alpha_x_origin = pPicture->alphaOrigin.x;
  869. if (mask & CPAlphaYOrigin)
  870. attribs.alpha_y_origin = pPicture->alphaOrigin.y;
  871. if (mask & CPClipXOrigin)
  872. attribs.clip_x_origin = pPicture->clipOrigin.x;
  873. if (mask & CPClipYOrigin)
  874. attribs.clip_y_origin = pPicture->clipOrigin.y;
  875. if (mask & CPClipMask)
  876. mask &= ~CPClipMask; /* Handled in ChangePictureClip */
  877. if (mask & CPGraphicsExposure)
  878. attribs.graphics_exposures = pPicture->graphicsExposures;
  879. if (mask & CPSubwindowMode)
  880. attribs.subwindow_mode = pPicture->subWindowMode;
  881. if (mask & CPPolyEdge)
  882. attribs.poly_edge = pPicture->polyEdge;
  883. if (mask & CPPolyMode)
  884. attribs.poly_mode = pPicture->polyMode;
  885. if (mask & CPComponentAlpha)
  886. attribs.component_alpha = pPicture->componentAlpha;
  887. XRenderChangePicture(dmxScreen->beDisplay, pPictPriv->pict,
  888. mask, &attribs);
  889. dmxSync(dmxScreen, FALSE);
  890. }
  891. else {
  892. pPictPriv->savedMask |= mask;
  893. }
  894. #if 1
  895. if (ps->ValidatePicture)
  896. ps->ValidatePicture(pPicture, mask);
  897. #endif
  898. DMX_WRAP(ValidatePicture, dmxValidatePicture, dmxScreen, ps);
  899. }
  900. /** Composite a picture on the appropriate screen by combining the
  901. * specified rectangle of the transformed src and mask operands with
  902. * the specified rectangle of the dst using op as the compositing
  903. * operator. For a complete description see the protocol document of
  904. * the RENDER library. */
  905. void
  906. dmxComposite(CARD8 op,
  907. PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
  908. INT16 xSrc, INT16 ySrc,
  909. INT16 xMask, INT16 yMask,
  910. INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
  911. {
  912. ScreenPtr pScreen = pDst->pDrawable->pScreen;
  913. DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
  914. PictureScreenPtr ps = GetPictureScreen(pScreen);
  915. dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
  916. dmxPictPrivPtr pMaskPriv = NULL;
  917. dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst);
  918. if (pMask)
  919. pMaskPriv = DMX_GET_PICT_PRIV(pMask);
  920. DMX_UNWRAP(Composite, dmxScreen, ps);
  921. #if 0
  922. if (ps->Composite)
  923. ps->Composite(op, pSrc, pMask, pDst,
  924. xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
  925. #endif
  926. /* Composite on back-end server */
  927. if (pSrcPriv->pict && pDstPriv->pict &&
  928. ((pMaskPriv && pMaskPriv->pict) || !pMaskPriv)) {
  929. XRenderComposite(dmxScreen->beDisplay,
  930. op,
  931. pSrcPriv->pict,
  932. pMaskPriv ? pMaskPriv->pict : None,
  933. pDstPriv->pict,
  934. xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
  935. dmxSync(dmxScreen, FALSE);
  936. }
  937. DMX_WRAP(Composite, dmxComposite, dmxScreen, ps);
  938. }
  939. /** Null function to catch when/if RENDER calls lower level mi hooks.
  940. * Compositing glyphs is handled by dmxProcRenderCompositeGlyphs().
  941. * This function should never be called. */
  942. void
  943. dmxGlyphs(CARD8 op,
  944. PicturePtr pSrc, PicturePtr pDst,
  945. PictFormatPtr maskFormat,
  946. INT16 xSrc, INT16 ySrc,
  947. int nlists, GlyphListPtr lists, GlyphPtr * glyphs)
  948. {
  949. /* This won't work, so we need to wrap ProcRenderCompositeGlyphs */
  950. }
  951. /** Fill a rectangle on the appropriate screen by combining the color
  952. * with the dest picture in the area specified by the list of
  953. * rectangles. For a complete description see the protocol document of
  954. * the RENDER library. */
  955. void
  956. dmxCompositeRects(CARD8 op,
  957. PicturePtr pDst,
  958. xRenderColor * color, int nRect, xRectangle *rects)
  959. {
  960. ScreenPtr pScreen = pDst->pDrawable->pScreen;
  961. DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
  962. PictureScreenPtr ps = GetPictureScreen(pScreen);
  963. dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pDst);
  964. DMX_UNWRAP(CompositeRects, dmxScreen, ps);
  965. #if 0
  966. if (ps->CompositeRects)
  967. ps->CompositeRects(op, pDst, color, nRect, rects);
  968. #endif
  969. /* CompositeRects on back-end server */
  970. if (pPictPriv->pict) {
  971. XRenderFillRectangles(dmxScreen->beDisplay,
  972. op,
  973. pPictPriv->pict,
  974. (XRenderColor *) color,
  975. (XRectangle *) rects, nRect);
  976. dmxSync(dmxScreen, FALSE);
  977. }
  978. DMX_WRAP(CompositeRects, dmxCompositeRects, dmxScreen, ps);
  979. }
  980. /** Indexed color visuals are not yet supported. */
  981. Bool
  982. dmxInitIndexed(ScreenPtr pScreen, PictFormatPtr pFormat)
  983. {
  984. return TRUE;
  985. }
  986. /** Indexed color visuals are not yet supported. */
  987. void
  988. dmxCloseIndexed(ScreenPtr pScreen, PictFormatPtr pFormat)
  989. {
  990. }
  991. /** Indexed color visuals are not yet supported. */
  992. void
  993. dmxUpdateIndexed(ScreenPtr pScreen, PictFormatPtr pFormat,
  994. int ndef, xColorItem * pdef)
  995. {
  996. }
  997. /** Composite a list of trapezoids on the appropriate screen. For a
  998. * complete description see the protocol document of the RENDER
  999. * library. */
  1000. void
  1001. dmxTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
  1002. PictFormatPtr maskFormat,
  1003. INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps)
  1004. {
  1005. ScreenPtr pScreen = pDst->pDrawable->pScreen;
  1006. DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
  1007. PictureScreenPtr ps = GetPictureScreen(pScreen);
  1008. dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
  1009. dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst);
  1010. DMX_UNWRAP(Trapezoids, dmxScreen, ps);
  1011. #if 0
  1012. if (ps->Trapezoids)
  1013. ps->Trapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, *traps);
  1014. #endif
  1015. /* Draw trapezoids on back-end server */
  1016. if (pDstPriv->pict) {
  1017. XRenderPictFormat *pFormat;
  1018. pFormat = dmxFindFormat(dmxScreen, maskFormat);
  1019. if (!pFormat) {
  1020. /* FIXME: Error! */
  1021. }
  1022. XRenderCompositeTrapezoids(dmxScreen->beDisplay,
  1023. op,
  1024. pSrcPriv->pict,
  1025. pDstPriv->pict,
  1026. pFormat,
  1027. xSrc, ySrc, (XTrapezoid *) traps, ntrap);
  1028. dmxSync(dmxScreen, FALSE);
  1029. }
  1030. DMX_WRAP(Trapezoids, dmxTrapezoids, dmxScreen, ps);
  1031. }
  1032. /** Composite a list of triangles on the appropriate screen. For a
  1033. * complete description see the protocol document of the RENDER
  1034. * library. */
  1035. void
  1036. dmxTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
  1037. PictFormatPtr maskFormat,
  1038. INT16 xSrc, INT16 ySrc, int ntri, xTriangle * tris)
  1039. {
  1040. ScreenPtr pScreen = pDst->pDrawable->pScreen;
  1041. DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
  1042. PictureScreenPtr ps = GetPictureScreen(pScreen);
  1043. dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
  1044. dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst);
  1045. DMX_UNWRAP(Triangles, dmxScreen, ps);
  1046. #if 0
  1047. if (ps->Triangles)
  1048. ps->Triangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, *tris);
  1049. #endif
  1050. /* Draw trapezoids on back-end server */
  1051. if (pDstPriv->pict) {
  1052. XRenderPictFormat *pFormat;
  1053. pFormat = dmxFindFormat(dmxScreen, maskFormat);
  1054. if (!pFormat) {
  1055. /* FIXME: Error! */
  1056. }
  1057. XRenderCompositeTriangles(dmxScreen->beDisplay,
  1058. op,
  1059. pSrcPriv->pict,
  1060. pDstPriv->pict,
  1061. pFormat,
  1062. xSrc, ySrc, (XTriangle *) tris, ntri);
  1063. dmxSync(dmxScreen, FALSE);
  1064. }
  1065. DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps);
  1066. }