Commit 959a1eaf authored by Dave Airlie's avatar Dave Airlie Committed by Keith Packard
Browse files

composite: use config notify hook to do pixmap resize.



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 status, 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.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
Reviewed-by: Keith Packard's avatarKeith Packard <keithp@keithp.com>
Signed-off-by: Keith Packard's avatarKeith Packard <keithp@keithp.com>
parent 0f12e86e
......@@ -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;
......
......@@ -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
*/
......@@ -279,16 +275,6 @@ compUnrealizeWindow (WindowPtr pWin);
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);
......@@ -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_ */
......@@ -334,132 +334,6 @@ compImplicitRedirect (WindowPtr pWin, WindowPtr pParent)
return FALSE;
}
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)
{
......@@ -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;
}
......@@ -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))
{
......
......@@ -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
......
......@@ -396,7 +396,7 @@ typedef void (* PostChangeSaveUnderProcPtr)(
WindowPtr /*pLayerWin*/,
WindowPtr /*firstChild*/);
typedef void (* ConfigNotifyProcPtr)(
typedef int (* ConfigNotifyProcPtr)(
WindowPtr /*pWin*/,
int /*x*/,
int /*y*/,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment