diff options
author | George Staplin <gstaplin@apple.com> | 2009-02-06 12:55:09 -0700 |
---|---|---|
committer | George Staplin <gstaplin@apple.com> | 2009-02-06 12:55:09 -0700 |
commit | 58c4116c47543b5e30c2232e7bee8efc0b9be176 (patch) | |
tree | b58f3e3c07f0767e13a61d7421ab5ba93cc2424d | |
parent | 0d5dd1501af35d8edcea5672b4cc539ce1251975 (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.c | 43 |
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. */ |
412 | static DRIDrawablePrivPtr | 412 | static DRIDrawablePrivPtr |
413 | CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) { | 413 | CreateSurfaceForPixmap(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 | } |