summaryrefslogtreecommitdiff
path: root/uxa/uxa.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-12-15 15:43:34 -0800
committerKeith Packard <keithp@keithp.com>2009-01-06 09:31:39 -0800
commit632f816c72cb4b48b690fd92d1cc1d5a9c9285c7 (patch)
tree80af87672f9a8ad3978a76bf0d6c951abe4b1b3d /uxa/uxa.c
parent90b28a56553d809374fa6d9b9529b7a8b583488c (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.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/uxa/uxa.c b/uxa/uxa.c
index 102717de..4aeb5e47 100644
--- a/uxa/uxa.c
+++ b/uxa/uxa.c
@@ -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;