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: Dave Airlie <airlied@redhat.com> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
parent
0f12e86e60
commit
959a1eaf1c
|
@ -69,9 +69,7 @@ compCloseScreen (int index, ScreenPtr pScreen)
|
||||||
pScreen->InstallColormap = cs->InstallColormap;
|
pScreen->InstallColormap = cs->InstallColormap;
|
||||||
pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
|
pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
|
||||||
pScreen->ReparentWindow = cs->ReparentWindow;
|
pScreen->ReparentWindow = cs->ReparentWindow;
|
||||||
pScreen->MoveWindow = cs->MoveWindow;
|
pScreen->ConfigNotify = cs->ConfigNotify;
|
||||||
pScreen->ResizeWindow = cs->ResizeWindow;
|
|
||||||
pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
|
|
||||||
|
|
||||||
pScreen->ClipNotify = cs->ClipNotify;
|
pScreen->ClipNotify = cs->ClipNotify;
|
||||||
pScreen->UnrealizeWindow = cs->UnrealizeWindow;
|
pScreen->UnrealizeWindow = cs->UnrealizeWindow;
|
||||||
|
@ -362,14 +360,8 @@ compScreenInit (ScreenPtr pScreen)
|
||||||
cs->ClipNotify = pScreen->ClipNotify;
|
cs->ClipNotify = pScreen->ClipNotify;
|
||||||
pScreen->ClipNotify = compClipNotify;
|
pScreen->ClipNotify = compClipNotify;
|
||||||
|
|
||||||
cs->MoveWindow = pScreen->MoveWindow;
|
cs->ConfigNotify = pScreen->ConfigNotify;
|
||||||
pScreen->MoveWindow = compMoveWindow;
|
pScreen->ConfigNotify = compConfigNotify;
|
||||||
|
|
||||||
cs->ResizeWindow = pScreen->ResizeWindow;
|
|
||||||
pScreen->ResizeWindow = compResizeWindow;
|
|
||||||
|
|
||||||
cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
|
|
||||||
pScreen->ChangeBorderWidth = compChangeBorderWidth;
|
|
||||||
|
|
||||||
cs->ReparentWindow = pScreen->ReparentWindow;
|
cs->ReparentWindow = pScreen->ReparentWindow;
|
||||||
pScreen->ReparentWindow = compReparentWindow;
|
pScreen->ReparentWindow = compReparentWindow;
|
||||||
|
|
|
@ -127,13 +127,9 @@ typedef struct _CompScreen {
|
||||||
UnrealizeWindowProcPtr UnrealizeWindow;
|
UnrealizeWindowProcPtr UnrealizeWindow;
|
||||||
ClipNotifyProcPtr ClipNotify;
|
ClipNotifyProcPtr ClipNotify;
|
||||||
/*
|
/*
|
||||||
* Called from ConfigureWindow, these
|
* Called from ConfigureWindow.
|
||||||
* three track changes to the offscreen storage
|
|
||||||
* geometry
|
|
||||||
*/
|
*/
|
||||||
MoveWindowProcPtr MoveWindow;
|
ConfigNotifyProcPtr ConfigNotify;
|
||||||
ResizeWindowProcPtr ResizeWindow;
|
|
||||||
ChangeBorderWidthProcPtr ChangeBorderWidth;
|
|
||||||
/*
|
/*
|
||||||
* Reparenting has an effect on Subwindows redirect
|
* Reparenting has an effect on Subwindows redirect
|
||||||
*/
|
*/
|
||||||
|
@ -279,16 +275,6 @@ compUnrealizeWindow (WindowPtr pWin);
|
||||||
void
|
void
|
||||||
compClipNotify (WindowPtr pWin, int dx, int dy);
|
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
|
void
|
||||||
compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent);
|
compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent);
|
||||||
|
|
||||||
|
@ -316,4 +302,8 @@ CompositeRealChildHead (WindowPtr pWin);
|
||||||
int
|
int
|
||||||
DeleteWindowNoInputDevices(pointer value, XID wid);
|
DeleteWindowNoInputDevices(pointer value, XID wid);
|
||||||
|
|
||||||
|
int
|
||||||
|
compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
|
||||||
|
int bw, WindowPtr pSib);
|
||||||
|
|
||||||
#endif /* _COMPINT_H_ */
|
#endif /* _COMPINT_H_ */
|
||||||
|
|
|
@ -334,132 +334,6 @@ compImplicitRedirect (WindowPtr pWin, WindowPtr pParent)
|
||||||
return FALSE;
|
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
|
void
|
||||||
compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent)
|
compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent)
|
||||||
{
|
{
|
||||||
|
@ -822,3 +696,48 @@ CompositeRealChildHead (WindowPtr pWin)
|
||||||
return pChildBefore;
|
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:
|
ActuallyDoSomething:
|
||||||
if (pWin->drawable.pScreen->ConfigNotify)
|
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))
|
if (SubStrSend(pWin, pParent))
|
||||||
{
|
{
|
||||||
|
|
|
@ -977,7 +977,7 @@ DRI2Authenticate(ScreenPtr pScreen, uint32_t magic)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
|
DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
|
||||||
WindowPtr pSib)
|
WindowPtr pSib)
|
||||||
{
|
{
|
||||||
|
@ -985,20 +985,24 @@ DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
|
||||||
ScreenPtr pScreen = pDraw->pScreen;
|
ScreenPtr pScreen = pDraw->pScreen;
|
||||||
DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
|
DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
|
||||||
DRI2DrawablePtr dd = DRI2GetDrawable(pDraw);
|
DRI2DrawablePtr dd = DRI2GetDrawable(pDraw);
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (ds->ConfigNotify) {
|
if (ds->ConfigNotify) {
|
||||||
pScreen->ConfigNotify = 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;
|
ds->ConfigNotify = pScreen->ConfigNotify;
|
||||||
pScreen->ConfigNotify = DRI2ConfigNotify;
|
pScreen->ConfigNotify = DRI2ConfigNotify;
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dd || (dd->width == w && dd->height == h))
|
if (!dd || (dd->width == w && dd->height == h))
|
||||||
return;
|
return Success;
|
||||||
|
|
||||||
DRI2InvalidateDrawable(pDraw);
|
DRI2InvalidateDrawable(pDraw);
|
||||||
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
|
|
|
@ -396,7 +396,7 @@ typedef void (* PostChangeSaveUnderProcPtr)(
|
||||||
WindowPtr /*pLayerWin*/,
|
WindowPtr /*pLayerWin*/,
|
||||||
WindowPtr /*firstChild*/);
|
WindowPtr /*firstChild*/);
|
||||||
|
|
||||||
typedef void (* ConfigNotifyProcPtr)(
|
typedef int (* ConfigNotifyProcPtr)(
|
||||||
WindowPtr /*pWin*/,
|
WindowPtr /*pWin*/,
|
||||||
int /*x*/,
|
int /*x*/,
|
||||||
int /*y*/,
|
int /*y*/,
|
||||||
|
|
Loading…
Reference in New Issue