diff options
author | Keith Packard <keithp@keithp.com> | 2008-12-15 15:43:34 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2009-01-06 09:31:39 -0800 |
commit | 632f816c72cb4b48b690fd92d1cc1d5a9c9285c7 (patch) | |
tree | 80af87672f9a8ad3978a76bf0d6c951abe4b1b3d /uxa/uxa.c | |
parent | 90b28a56553d809374fa6d9b9529b7a8b583488c (diff) |
uxa: handle uxa_prepare_access failure
uxa_prepare_access may fail to map the pixmap into user space. Recover from
this without crashing.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'uxa/uxa.c')
-rw-r--r-- | uxa/uxa.c | 47 |
1 files changed, 30 insertions, 17 deletions
@@ -140,7 +140,7 @@ uxa_get_offscreen_pixmap (DrawablePtr drawable, int *xp, int *yp) * It deals with waiting for synchronization with the card, determining if * PrepareAccess() is necessary, and working around PrepareAccess() failure. */ -void +Bool uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access) { ScreenPtr pScreen = pDrawable->pScreen; @@ -149,10 +149,11 @@ uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access) Bool offscreen = uxa_pixmap_is_offscreen(pPixmap); if (!offscreen) - return; + return TRUE; if (uxa_screen->info->prepare_access) - (*uxa_screen->info->prepare_access) (pPixmap, access); + return (*uxa_screen->info->prepare_access) (pPixmap, access); + return TRUE; } /** @@ -209,10 +210,11 @@ uxa_validate_gc (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) * allocated pixmap. This isn't a problem yet, since we don't * put pixmaps in FB until at least one accelerated UXA op. */ - uxa_prepare_access(&pOldTile->drawable, UXA_ACCESS_RO); - pNewTile = fb24_32ReformatTile (pOldTile, - pDrawable->bitsPerPixel); - uxa_finish_access(&pOldTile->drawable); + if (uxa_prepare_access(&pOldTile->drawable, UXA_ACCESS_RO)) { + pNewTile = fb24_32ReformatTile (pOldTile, + pDrawable->bitsPerPixel); + uxa_finish_access(&pOldTile->drawable); + } } if (pNewTile) { @@ -227,9 +229,10 @@ uxa_validate_gc (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) if (!pGC->tileIsPixel && FbEvenTile (pGC->tile.pixmap->drawable.width * pDrawable->bitsPerPixel)) { - uxa_prepare_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RW); - fbPadPixmap (pGC->tile.pixmap); - uxa_finish_access(&pGC->tile.pixmap->drawable); + if (uxa_prepare_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RW)) { + fbPadPixmap (pGC->tile.pixmap); + uxa_finish_access(&pGC->tile.pixmap->drawable); + } } /* Mask out the GCTile change notification, now that we've done FB's * job for it. @@ -276,14 +279,22 @@ uxa_create_gc (GCPtr pGC) return TRUE; } -void +Bool uxa_prepare_access_window(WindowPtr pWin) { - if (pWin->backgroundState == BackgroundPixmap) - uxa_prepare_access(&pWin->background.pixmap->drawable, UXA_ACCESS_RO); + if (pWin->backgroundState == BackgroundPixmap) { + if (!uxa_prepare_access(&pWin->background.pixmap->drawable, UXA_ACCESS_RO)) + return FALSE; + } - if (pWin->borderIsPixel == FALSE) - uxa_prepare_access(&pWin->border.pixmap->drawable, UXA_ACCESS_RO); + if (pWin->borderIsPixel == FALSE) { + if (!uxa_prepare_access(&pWin->border.pixmap->drawable, UXA_ACCESS_RO)) { + if (pWin->backgroundState == BackgroundPixmap) + uxa_finish_access(&pWin->background.pixmap->drawable); + return FALSE; + } + } + return TRUE; } void @@ -301,7 +312,8 @@ uxa_change_window_attributes(WindowPtr pWin, unsigned long mask) { Bool ret; - uxa_prepare_access_window(pWin); + if (!uxa_prepare_access_window(pWin)) + return FALSE; ret = fbChangeWindowAttributes(pWin, mask); uxa_finish_access_window(pWin); return ret; @@ -311,7 +323,8 @@ static RegionPtr uxa_bitmap_to_region(PixmapPtr pPix) { RegionPtr ret; - uxa_prepare_access(&pPix->drawable, UXA_ACCESS_RO); + if (!uxa_prepare_access(&pPix->drawable, UXA_ACCESS_RO)) + return NULL; ret = fbPixmapToRegion(pPix); uxa_finish_access(&pPix->drawable); return ret; |