From: Dave Airlie <[email protected]>

Since reallocating the backing pixmap can fail, we need to try and do it before 
any other side effects of reconfiguring the window happen.

This changes the ConfigNotify hook to return a Bool, and moves the composite 
window reconfiguration wrappers to ConfigNotify. They all basically did the 
same thing, so we can drop the MoveWindow, ResizeWindow, ChangeBorderWidth 
wrappers, and allow ConfigNotify to do all the work. If reallocation fails we 
fail before we send any confiureNotify events, or enter the area we can't 
recover from.

The only place we now enforce 32k limits are in EXA/UXA/fb, so drivers that 
don't use this should probably deal with it in their pixmap allocate if they 
don't already.

This also breaks ABI, so we need an alternate fix for older servers, working on 
the X server makes me realise why I'm a kernel hacker.

v2: use int return instead of Bool as per keithp's comments.

v3: return Success (X should play the ta-da fanfare when I do this(.

Signed-off-by: Dave Airlie <[email protected]>
---
 composite/compinit.c   |   14 +---
 composite/compint.h    |   22 ++-----
 composite/compwindow.c |  171 +++++++++++++-----------------------------------
 dix/window.c           |    9 ++-
 hw/xfree86/dri2/dri2.c |   10 ++-
 include/scrnintstr.h   |    2 +-
 6 files changed, 70 insertions(+), 158 deletions(-)

diff --git a/composite/compinit.c b/composite/compinit.c
index e4b68c8..b4deaf5 100644
--- a/composite/compinit.c
+++ b/composite/compinit.c
@@ -69,9 +69,7 @@ compCloseScreen (int index, ScreenPtr pScreen)
     pScreen->InstallColormap = cs->InstallColormap;
     pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
     pScreen->ReparentWindow = cs->ReparentWindow;
-    pScreen->MoveWindow = cs->MoveWindow;
-    pScreen->ResizeWindow = cs->ResizeWindow;
-    pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
+    pScreen->ConfigNotify = cs->ConfigNotify;
     
     pScreen->ClipNotify = cs->ClipNotify;
     pScreen->UnrealizeWindow = cs->UnrealizeWindow;
@@ -362,14 +360,8 @@ compScreenInit (ScreenPtr pScreen)
     cs->ClipNotify = pScreen->ClipNotify;
     pScreen->ClipNotify = compClipNotify;
 
-    cs->MoveWindow = pScreen->MoveWindow;
-    pScreen->MoveWindow = compMoveWindow;
-
-    cs->ResizeWindow = pScreen->ResizeWindow;
-    pScreen->ResizeWindow = compResizeWindow;
-
-    cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
-    pScreen->ChangeBorderWidth = compChangeBorderWidth;
+    cs->ConfigNotify = pScreen->ConfigNotify;
+    pScreen->ConfigNotify = compConfigNotify;
 
     cs->ReparentWindow = pScreen->ReparentWindow;
     pScreen->ReparentWindow = compReparentWindow;
diff --git a/composite/compint.h b/composite/compint.h
index 845a196..93da4df 100644
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -127,13 +127,9 @@ typedef struct _CompScreen {
     UnrealizeWindowProcPtr     UnrealizeWindow;
     ClipNotifyProcPtr          ClipNotify;
     /*
-     * Called from ConfigureWindow, these
-     * three track changes to the offscreen storage
-     * geometry
+     * Called from ConfigureWindow.
      */
-    MoveWindowProcPtr          MoveWindow;
-    ResizeWindowProcPtr                ResizeWindow;
-    ChangeBorderWidthProcPtr   ChangeBorderWidth;
+    ConfigNotifyProcPtr         ConfigNotify;
     /*
      * Reparenting has an effect on Subwindows redirect
      */
@@ -280,16 +276,6 @@ void
 compClipNotify (WindowPtr pWin, int dx, int dy);
 
 void
-compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind);
-
-void
-compResizeWindow (WindowPtr pWin, int x, int y,
-                 unsigned int w, unsigned int h, WindowPtr pSib);
-
-void
-compChangeBorderWidth (WindowPtr pWin, unsigned int border_width);
-
-void
 compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent);
 
 Bool
@@ -316,4 +302,8 @@ CompositeRealChildHead (WindowPtr pWin);
 int
 DeleteWindowNoInputDevices(pointer value, XID wid);
 
+int
+compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
+                int bw, WindowPtr pSib);
+
 #endif /* _COMPINT_H_ */
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 3b16bf9..0f3898c 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -335,132 +335,6 @@ compImplicitRedirect (WindowPtr pWin, WindowPtr pParent)
 }
 
 void
-compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
-{
-    ScreenPtr          pScreen = pWin->drawable.pScreen;
-    CompScreenPtr      cs = GetCompScreen (pScreen);
-
-    compCheckTree (pScreen);
-    if (pWin->redirectDraw != RedirectDrawNone)
-    {
-       WindowPtr               pParent;
-       int                     draw_x, draw_y;
-       unsigned int            w, h, bw;
-
-       /* if this is a root window, can't be moved */
-       if (!(pParent = pWin->parent))
-          return;
-
-       bw = wBorderWidth (pWin);
-       draw_x = pParent->drawable.x + x + (int)bw;
-       draw_y = pParent->drawable.y + y + (int)bw;
-       w = pWin->drawable.width;
-       h = pWin->drawable.height;
-       compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
-    }
-    compCheckTree (pScreen);
-
-    pScreen->MoveWindow = cs->MoveWindow;
-    (*pScreen->MoveWindow) (pWin, x, y, pSib, kind);
-    cs->MoveWindow = pScreen->MoveWindow;
-    pScreen->MoveWindow = compMoveWindow;
-
-    if (pWin->redirectDraw != RedirectDrawNone)
-    {
-       CompWindowPtr   cw = GetCompWindow (pWin);
-       if (cw->pOldPixmap)
-       {
-           (*pScreen->DestroyPixmap) (cw->pOldPixmap);
-           cw->pOldPixmap = NullPixmap;
-       }
-    }
-
-    compCheckTree (pScreen);
-}
-
-void
-compResizeWindow (WindowPtr pWin, int x, int y,
-                 unsigned int w, unsigned int h, WindowPtr pSib)
-{
-    ScreenPtr          pScreen = pWin->drawable.pScreen;
-    CompScreenPtr      cs = GetCompScreen (pScreen);
-
-    compCheckTree (pScreen);
-    if (pWin->redirectDraw != RedirectDrawNone)
-    {
-       WindowPtr               pParent;
-       int                     draw_x, draw_y;
-       unsigned int            bw;
-
-       /* if this is a root window, can't be moved */
-       if (!(pParent = pWin->parent))
-          return;
-
-       bw = wBorderWidth (pWin);
-       draw_x = pParent->drawable.x + x + (int)bw;
-       draw_y = pParent->drawable.y + y + (int)bw;
-       compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
-    }
-    compCheckTree (pScreen);
-
-    pScreen->ResizeWindow = cs->ResizeWindow;
-    (*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
-    cs->ResizeWindow = pScreen->ResizeWindow;
-    pScreen->ResizeWindow = compResizeWindow;
-    if (pWin->redirectDraw != RedirectDrawNone)
-    {
-       CompWindowPtr   cw = GetCompWindow (pWin);
-       if (cw->pOldPixmap)
-       {
-           (*pScreen->DestroyPixmap) (cw->pOldPixmap);
-           cw->pOldPixmap = NullPixmap;
-       }
-    }
-    compCheckTree (pWin->drawable.pScreen);
-}
-
-void
-compChangeBorderWidth (WindowPtr pWin, unsigned int bw)
-{
-    ScreenPtr          pScreen = pWin->drawable.pScreen;
-    CompScreenPtr      cs = GetCompScreen (pScreen);
-
-    compCheckTree (pScreen);
-    if (pWin->redirectDraw != RedirectDrawNone)
-    {
-       WindowPtr               pParent;
-       int                     draw_x, draw_y;
-       unsigned int            w, h;
-
-       /* if this is a root window, can't be moved */
-       if (!(pParent = pWin->parent))
-          return;
-
-       draw_x = pWin->drawable.x;
-       draw_y = pWin->drawable.y;
-       w = pWin->drawable.width;
-       h = pWin->drawable.height;
-       compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
-    }
-    compCheckTree (pScreen);
-
-    pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
-    (*pScreen->ChangeBorderWidth) (pWin, bw);
-    cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
-    pScreen->ChangeBorderWidth = compChangeBorderWidth;
-    if (pWin->redirectDraw != RedirectDrawNone)
-    {
-       CompWindowPtr   cw = GetCompWindow (pWin);
-       if (cw->pOldPixmap)
-       {
-           (*pScreen->DestroyPixmap) (cw->pOldPixmap);
-           cw->pOldPixmap = NullPixmap;
-       }
-    }
-    compCheckTree (pWin->drawable.pScreen);
-}
-
-void
 compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent)
 {
     ScreenPtr          pScreen = pWin->drawable.pScreen;
@@ -822,3 +696,48 @@ CompositeRealChildHead (WindowPtr pWin)
        return pChildBefore;
     }
 }
+
+int
+compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
+                int bw, WindowPtr pSib)
+{
+    ScreenPtr          pScreen = pWin->drawable.pScreen;
+    CompScreenPtr      cs = GetCompScreen (pScreen);
+    Bool                ret = 0;
+    WindowPtr          pParent = pWin->parent;
+    CompWindowPtr       cw;
+    int                        draw_x, draw_y;
+    Bool alloc_ret;
+
+    if (cs->ConfigNotify)
+    {
+       pScreen->ConfigNotify = cs->ConfigNotify;
+       ret = (*pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib);
+       cs->ConfigNotify = pScreen->ConfigNotify;
+       pScreen->ConfigNotify = compConfigNotify;
+
+       if (ret)
+           return ret;
+    }
+
+    if (pWin->redirectDraw == RedirectDrawNone)
+       return Success;
+
+    compCheckTree (pScreen);
+
+    draw_x = pParent->drawable.x + x + bw;
+    draw_y = pParent->drawable.y + y + bw;
+    alloc_ret = compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
+    
+    cw = GetCompWindow (pWin);
+    if (cw->pOldPixmap)
+    {
+       (*pScreen->DestroyPixmap) (cw->pOldPixmap);
+       cw->pOldPixmap = NullPixmap;
+    }
+    compCheckTree (pScreen);
+
+    if (alloc_ret == FALSE)
+       return BadAlloc;
+    return Success;
+}
diff --git a/dix/window.c b/dix/window.c
index 9e1f491..ea729db 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -2302,7 +2302,14 @@ ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, 
ClientPtr client)
 
 ActuallyDoSomething:
     if (pWin->drawable.pScreen->ConfigNotify)
-       (*pWin->drawable.pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib);
+    {
+       int ret;
+       ret = (*pWin->drawable.pScreen->ConfigNotify)(pWin, x, y, w, h, bw, 
pSib);
+       if (ret) {
+           client->errorValue = 0;
+           return ret;
+       }
+    }
 
     if (SubStrSend(pWin, pParent))
     {
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 9ec4caa..45a8271 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -977,7 +977,7 @@ DRI2Authenticate(ScreenPtr pScreen, uint32_t magic)
     return TRUE;
 }
 
-static void
+static int
 DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
                 WindowPtr pSib)
 {
@@ -985,20 +985,24 @@ DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int 
h, int bw,
     ScreenPtr pScreen = pDraw->pScreen;
     DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
     DRI2DrawablePtr dd = DRI2GetDrawable(pDraw);
+    int ret;
 
     if (ds->ConfigNotify) {
        pScreen->ConfigNotify = ds->ConfigNotify;
 
-       (*pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib);
+       ret = (*pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib);
 
        ds->ConfigNotify = pScreen->ConfigNotify;
        pScreen->ConfigNotify = DRI2ConfigNotify;
+       if (ret)
+           return ret;
     }
 
     if (!dd || (dd->width == w && dd->height == h))
-       return;
+       return Success;
 
     DRI2InvalidateDrawable(pDraw);
+    return Success;
 }
 
 Bool
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index d67b264..361c484 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -396,7 +396,7 @@ typedef    void (* PostChangeSaveUnderProcPtr)(
        WindowPtr /*pLayerWin*/,
        WindowPtr /*firstChild*/);
 
-typedef    void (* ConfigNotifyProcPtr)(
+typedef    int (* ConfigNotifyProcPtr)(
        WindowPtr /*pWin*/,
        int /*x*/,
        int /*y*/,
-- 
1.6.5.2

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to