summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Staplin <gstaplin@apple.com>2009-02-06 12:55:09 -0700
committerGeorge Staplin <gstaplin@apple.com>2009-02-06 12:55:09 -0700
commit58c4116c47543b5e30c2232e7bee8efc0b9be176 (patch)
treeb58f3e3c07f0767e13a61d7421ab5ba93cc2424d
parent0d5dd1501af35d8edcea5672b4cc539ce1251975 (diff)
XQuartz: xpr: The dri.c code for pixmaps was wrong in several ways. They weren't
being exported correctly by Xplugin. This should fix a bug with the surface for a window, when an export fails. Before the export could fail and leave behind an invalid (freed) pointer in the dix privates. I have an idea of how to fix the GLXPixmaps now without using CGLSetOffScreen. This work is a step towards that. The Xplugin will need a small patch to fix an issue that this change brought forth.
-rw-r--r--hw/xquartz/xpr/dri.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/hw/xquartz/xpr/dri.c b/hw/xquartz/xpr/dri.c
index 50b478b9c..bcd0c65bc 100644
--- a/hw/xquartz/xpr/dri.c
+++ b/hw/xquartz/xpr/dri.c
@@ -408,7 +408,7 @@ CreateSurfaceForWindow(ScreenPtr pScreen, WindowPtr pWin, xp_window_id *widPtr)
408 return pDRIDrawablePriv; 408 return pDRIDrawablePriv;
409} 409}
410 410
411/* Return FALSE if an error occurs. */ 411/* Return NULL if an error occurs. */
412static DRIDrawablePrivPtr 412static DRIDrawablePrivPtr
413CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) { 413CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
414 DRIDrawablePrivPtr pDRIDrawablePriv; 414 DRIDrawablePrivPtr pDRIDrawablePriv;
@@ -417,7 +417,6 @@ CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
417 417
418 if (pDRIDrawablePriv == NULL) { 418 if (pDRIDrawablePriv == NULL) {
419 xp_error err; 419 xp_error err;
420 xp_window_changes wc;
421 420
422 /* allocate a DRI Window Private record */ 421 /* allocate a DRI Window Private record */
423 if (!(pDRIDrawablePriv = xcalloc(1, sizeof(*pDRIDrawablePriv)))) { 422 if (!(pDRIDrawablePriv = xcalloc(1, sizeof(*pDRIDrawablePriv)))) {
@@ -439,18 +438,10 @@ CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
439 return NULL; 438 return NULL;
440 } 439 }
441 440
442 wc.x = 0; 441 /*
443 wc.y = 0; 442 * The DRIUpdateSurface will be called to resize the surface
444 wc.width = pPix->drawable.width; 443 * after this function, if the export is successful.
445 wc.height = pPix->drawable.height; 444 */
446
447 err = xp_configure_surface(pDRIDrawablePriv->sid, XP_BOUNDS, &wc);
448
449 if(err != Success) {
450 xp_destroy_surface(pDRIDrawablePriv->sid);
451 xfree(pDRIDrawablePriv);
452 return NULL;
453 }
454 445
455 /* save private off of preallocated index */ 446 /* save private off of preallocated index */
456 dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, 447 dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey,
@@ -491,21 +482,39 @@ DRICreateSurface(ScreenPtr pScreen, Drawable id,
491 /* NOT_DONE */ 482 /* NOT_DONE */
492 return FALSE; 483 return FALSE;
493 } 484 }
494
495 485
496 486
497 /* Finish initialization of new surfaces */ 487 /* Finish initialization of new surfaces */
498 if (pDRIDrawablePriv->refCount == 0) { 488 if (pDRIDrawablePriv->refCount == 0) {
499 unsigned int key[2] = {0}; 489 unsigned int key[2] = {0};
500 xp_error err; 490 xp_error err;
501 491
502 /* try to give the client access to the surface */ 492 /* try to give the client access to the surface */
503 if (client_id != 0 && wid != 0) { 493 if (client_id != 0) {
494 /*
495 * Xplugin accepts a 0 wid if the surface id is offscreen, such
496 * as for a pixmap.
497 */
504 err = xp_export_surface(wid, pDRIDrawablePriv->sid, 498 err = xp_export_surface(wid, pDRIDrawablePriv->sid,
505 client_id, key); 499 client_id, key);
506 if (err != Success) { 500 if (err != Success) {
507 xp_destroy_surface(pDRIDrawablePriv->sid); 501 xp_destroy_surface(pDRIDrawablePriv->sid);
508 xfree(pDRIDrawablePriv); 502 xfree(pDRIDrawablePriv);
503
504 /*
505 * Now set the dix privates to NULL that were previously set.
506 * This prevents reusing an invalid pointer.
507 */
508 if(pDrawable->type == DRAWABLE_WINDOW) {
509 WindowPtr pWin = (WindowPtr)pDrawable;
510
511 dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
512 } else if(pDrawable->type == DRAWABLE_PIXMAP) {
513 PixmapPtr pPix = (PixmapPtr)pDrawable;
514
515 dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL);
516 }
517
509 return FALSE; 518 return FALSE;
510 } 519 }
511 } 520 }