diff --git a/composite/compint.h b/composite/compint.h index cb73c386d..72022fd87 100644 --- a/composite/compint.h +++ b/composite/compint.h @@ -171,12 +171,7 @@ typedef struct _CompScreen { SourceValidateProcPtr SourceValidate; } CompScreenRec, *CompScreenPtr; -extern DevPrivateKeyRec CompScreenPrivateKeyRec; - #define CompScreenPrivateKey (&CompScreenPrivateKeyRec) - -extern DevPrivateKeyRec CompWindowPrivateKeyRec; - #define CompWindowPrivateKey (&CompWindowPrivateKeyRec) extern DevPrivateKeyRec CompSubwindowsPrivateKeyRec; @@ -197,18 +192,9 @@ extern RESTYPE CompositeClientOverlayType; * compalloc.c */ -Bool - compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update); - void compFreeClientWindow(WindowPtr pWin, XID id); -int - compUnredirectWindow(ClientPtr pClient, WindowPtr pWin, int update); - -int - compRedirectSubwindows(ClientPtr pClient, WindowPtr pWin, int update); - void compFreeClientSubwindows(WindowPtr pWin, XID id); @@ -257,12 +243,6 @@ compFindOverlayClient(ScreenPtr pScreen, ClientPtr pClient); CompOverlayClientPtr compCreateOverlayClient(ScreenPtr pScreen, ClientPtr pClient); -Bool - compCreateOverlayWindow(ScreenPtr pScreen); - -void - compDestroyOverlayWindow(ScreenPtr pScreen); - /* * compwindow.c */ diff --git a/composite/compositeext.h b/composite/compositeext.h index 27ce7ce40..52acdb3a5 100644 --- a/composite/compositeext.h +++ b/composite/compositeext.h @@ -31,6 +31,9 @@ #include "misc.h" #include "scrnintstr.h" +extern _X_EXPORT DevPrivateKeyRec CompWindowPrivateKeyRec; +extern _X_EXPORT DevPrivateKeyRec CompScreenPrivateKeyRec; + extern _X_EXPORT Bool CompositeRegisterAlternateVisuals(ScreenPtr pScreen, VisualID * vids, int nVisuals); @@ -45,4 +48,19 @@ Bool CompositeIsImplicitRedirectException(ScreenPtr pScreen, XID parentVisual, XID winVisual); extern _X_EXPORT RESTYPE CompositeClientWindowType; +extern _X_EXPORT Bool + compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update); + +extern _X_EXPORT int + compUnredirectWindow(ClientPtr pClient, WindowPtr pWin, int update); + +extern _X_EXPORT int + compRedirectSubwindows(ClientPtr pClient, WindowPtr pWin, int update); + +extern _X_EXPORT Bool + compCreateOverlayWindow(ScreenPtr pScreen); + +extern _X_EXPORT void + compDestroyOverlayWindow(ScreenPtr pScreen); + #endif /* _COMPOSITEEXT_H_ */ diff --git a/hw/xfree86/compositX/compositx.c b/hw/xfree86/compositX/compositx.c new file mode 100644 index 000000000..37e12a870 --- /dev/null +++ b/hw/xfree86/compositX/compositx.c @@ -0,0 +1,453 @@ +/** + * Spaghetti Display Server + * Copyright (C) 2026 SpaghettiFork + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "compositx.h" +#include "dixstruct.h" +#include "privates.h" +#include "propertyst.h" +#include "xf86Module.h" + +#define ShapeBounding 0 +#define ShapeClip 1 +#define ShapeInput 2 + +DevPrivateKeyRec compositXScreenPrivateKeyRec; +DevPrivateKeyRec compositXWindowPrivateKeyRec; + +static Atom compositXOpacityAtom; +static Atom compositXBypassAtom; + +static MODULESETUPPROTO(compositXSetup); + +static RegionPtr +compositXRegionCopy(RegionPtr pRegion) +{ + RegionPtr pNew = RegionCreate(RegionExtents(pRegion), + RegionNumRects(pRegion)); + + if (!pNew) + return NULL; + + if (!RegionCopy(pNew, pRegion)) { + RegionDestroy(pNew); + return NULL; + } + + return pNew; +} + +static void SetWindowShapeRegion(WindowPtr pWin, int kind, + int xOff, int yOff, RegionPtr pRegion) +{ + RegionPtr *pDestRegion; + + switch (kind) { + case ShapeBounding: + case ShapeClip: + case ShapeInput: + break; + default: + return; + } + + if (pRegion) { + pRegion = compositXRegionCopy(pRegion); + if (!pRegion) + return; + + if (!pWin->optional) + MakeWindowOptional(pWin); + + switch (kind) { + default: + case ShapeBounding: + pDestRegion = &pWin->optional->boundingShape; + break; + case ShapeClip: + pDestRegion = &pWin->optional->clipShape; + break; + case ShapeInput: + pDestRegion = &pWin->optional->inputShape; + break; + } + + if (xOff || yOff) + RegionTranslate(pRegion, xOff, yOff); + } else { + if (pWin->optional) { + switch (kind) { + default: + case ShapeBounding: + pDestRegion = &pWin->optional->boundingShape; + break; + case ShapeClip: + pDestRegion = &pWin->optional->clipShape; + break; + case ShapeInput: + pDestRegion = &pWin->optional->inputShape; + break; + } + } else { + pDestRegion = &pRegion; /* a NULL region pointer */ + } + } + + if (*pDestRegion) + RegionDestroy(*pDestRegion); + + *pDestRegion = pRegion; + (*pWin->drawable.pScreen->SetShape) (pWin, kind); + SendShapeNotify(pWin, kind); +} + +static Bool +compositXIsBypassed(WindowPtr pWindow) +{ + PropertyPtr pProp; + + if (dixLookupProperty(&pProp, pWindow, compositXBypassAtom, + serverClient, DixReadAccess) != Success) + return FALSE; + + return pProp->format == 32 && pProp->size >= 1 && + *(CARD32 *) pProp->data == 1; +} + +static void +compositXDamageReport(DamagePtr pDamage, RegionPtr pRegion, void *closure) +{ + WindowPtr pWindow = closure; + ScreenPtr pScreen = pWindow->drawable.pScreen; + CompXScreenPtr cxs = GetCompXScreen(pScreen); + + RegionUnion(&cxs->pendingDamage, &cxs->pendingDamage, pRegion); +} + +static void +compositXWakeupHandler(void *data, int result) +{ +} + +static void +compositXBlockHandler(void *data, void *pTimeout) +{ + ScreenPtr pScreen = data; + CompXScreenPtr cxs = GetCompXScreen(pScreen); + + if (!RegionNotEmpty(&cxs->pendingDamage)) + return; + + compositXRepaint(pScreen); + RegionEmpty(&cxs->pendingDamage); +} + +static void +compositXSetWindowPixmap(WindowPtr pWin, PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompXScreenPtr cxs = GetCompXScreen(pScreen); + CompXWindowPtr cxw = GetCompXWindow(pWin); + + if (cxw->pDamage) + DamageUnregister(cxw->pDamage); + + CompXUnwrap(cxs, pScreen, SetWindowPixmap); + (*pScreen->SetWindowPixmap)(pWin, pPixmap); + CompXWrap(cxs, pScreen, SetWindowPixmap, compositXSetWindowPixmap); + + if (cxw->pDamage && pWin->realized) + DamageRegister(&pWin->drawable, cxw->pDamage); +} + +static Bool +compositXCloseScreen(ScreenPtr pScreen) +{ + CompXScreenPtr cxs = GetCompXScreen(pScreen); + + RemoveBlockAndWakeupHandlers(compositXBlockHandler, + compositXWakeupHandler, pScreen); + RegionUninit(&cxs->pendingDamage); + + if (cxs->pOverlayPicture) { + FreePicture(cxs->pOverlayPicture, 0); + cxs->pOverlayPicture = NULL; + } + + if (cxs->pOverlay) { + compDestroyOverlayWindow(pScreen); + cxs->pOverlay = NULL; + } + + CompXUnwrap(cxs, pScreen, CloseScreen); + CompXUnwrap(cxs, pScreen, CreateWindow); + CompXUnwrap(cxs, pScreen, DestroyWindow); + CompXUnwrap(cxs, pScreen, RealizeWindow); + CompXUnwrap(cxs, pScreen, UnrealizeWindow); + CompXUnwrap(cxs, pScreen, SetWindowPixmap); + + return (*pScreen->CloseScreen)(pScreen); +} + +static Bool +compositXCreateWindow(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + CompXScreenPtr cxs = GetCompXScreen(pScreen); + CompXWindowPtr cxw = GetCompXWindow(pWindow); + Bool ret; + + CompXUnwrap(cxs, pScreen, CreateWindow); + ret = (*pScreen->CreateWindow)(pWindow); + CompXWrap(cxs, pScreen, CreateWindow, compositXCreateWindow); + + if (ret) { + cxw->opacity = COMPOSITX_OPAQUE; + cxw->bypass = FALSE; + cxw->pDamage = NULL; + } + + return ret; +} + +static Bool +compositXDestroyWindow(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen;; + CompXScreenPtr cxs = GetCompXScreen(pScreen); + CompXWindowPtr cxw = GetCompXWindow(pWindow); + + CompXUnwrap(cxs, pScreen, DestroyWindow); + (*pScreen->DestroyWindow)(pWindow); + CompXWrap(cxs, pScreen, DestroyWindow, compositXDestroyWindow); + + /* damage may still be live if the window is destroyed while mapped */ + if (cxw->pDamage) { + DamageDestroy(cxw->pDamage); + cxw->pDamage = NULL; + } + + return TRUE; +} + +static Bool +compositXRealizeWindow(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + CompXScreenPtr cxs = GetCompXScreen(pScreen); + CompXWindowPtr cxw = GetCompXWindow(pWindow); + Bool ret; + + CompXUnwrap(cxs, pScreen, RealizeWindow); + ret = (*pScreen->RealizeWindow)(pWindow); + CompXWrap(cxs, pScreen, RealizeWindow, compositXRealizeWindow); + + if (ret && !cxw->pDamage) { + cxw->bypass = compositXIsBypassed(pWindow); + if (cxw->bypass) { + compUnredirectWindow(serverClient, pWindow, CompositeRedirectManual); + } else { + cxw->pDamage = DamageCreate(compositXDamageReport, + NULL, + DamageReportRawRegion, + TRUE, + pScreen, + pWindow); + if (cxw->pDamage) + DamageRegister(&pWindow->drawable, cxw->pDamage); + } + } + + return ret; +} + +static Bool +compositXUnrealizeWindow(WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + CompXScreenPtr cxs = GetCompXScreen(pScreen); + CompXWindowPtr cxw = GetCompXWindow(pWindow); + Bool ret; + + if (cxw->bypass) { + compRedirectWindow(serverClient, pWindow, CompositeRedirectManual); + cxw->bypass = FALSE; + } + + CompXUnwrap(cxs, pScreen, UnrealizeWindow); + ret = (*pScreen->UnrealizeWindow)(pWindow); + CompXWrap(cxs, pScreen, UnrealizeWindow, compositXUnrealizeWindow); + + return ret; +} + +static void +compositXPropertyCallback(CallbackListPtr *pcbl, void *unused, void *data) +{ + PropertyStateRec *rec = data; + CompXWindowPtr cxw = GetCompXWindow(rec->win); + Bool bypass; + + if (rec->prop->propertyName == compositXOpacityAtom) { + if (rec->state == PropertyNewValue && rec->prop->size >= 1) + cxw->opacity = *(CARD32 *) rec->prop->data; + else + cxw->opacity = COMPOSITX_OPAQUE; + return; + } + + if (rec->prop->propertyName == compositXBypassAtom) { + bypass = (rec->state == PropertyNewValue && + rec->prop->size >= 1 && + *(CARD32 *) rec->prop->data == 1); + + if (bypass == cxw->bypass || !rec->win->mapped) + return; + + cxw->bypass = bypass; + + if (bypass) { + if (cxw->pDamage) { + DamageUnregister(cxw->pDamage); + DamageDestroy(cxw->pDamage); + cxw->pDamage = NULL; + } + compUnredirectWindow(serverClient, rec->win, CompositeRedirectManual); + } else { + ScreenPtr pScreen = rec->win->drawable.pScreen; + + compRedirectWindow(serverClient, rec->win, CompositeRedirectManual); + cxw->pDamage = DamageCreate(compositXDamageReport, NULL, + DamageReportRawRegion, TRUE, + pScreen, rec->win); + if (cxw->pDamage) + DamageRegister(&rec->win->drawable, cxw->pDamage); + } + } +} + +static void +compositXScreenSetup(ScreenPtr pScreen) +{ + CompXScreenPtr cxs = GetCompXScreen(pScreen); + CompScreenPtr cs = GetCompScreen(pScreen); + BoxRec screenBox = {0, 0, pScreen->width, pScreen->height}; + + if (!cs) + return; + + if (cs->pOverlayWin == NULL) + if (!compCreateOverlayWindow(pScreen)) + return; + + if (cxs->wrapped) + return; + + cxs->wrapped = TRUE; + cxs->pOverlay = cs->pOverlayWin; + compositXInitOverlay(pScreen); + + /* Ignore all inputs on the overlay. */ + RegionPtr pEmpty = RegionCreate(NULL, 0); + SetWindowShapeRegion(cxs->pOverlay, ShapeInput, 0, 0, pEmpty); + RegionDestroy(pEmpty); + + /* manual: the Composite extension will not auto-paint redirected windows */ + compRedirectSubwindows(serverClient, pScreen->root, CompositeRedirectManual); + + RegionInit(&cxs->pendingDamage, &screenBox, 1); + RegisterBlockAndWakeupHandlers(compositXBlockHandler, + compositXWakeupHandler, pScreen); + + CompXWrap(cxs, pScreen, CloseScreen, compositXCloseScreen); + CompXWrap(cxs, pScreen, CreateWindow, compositXCreateWindow); + CompXWrap(cxs, pScreen, DestroyWindow, compositXDestroyWindow); + CompXWrap(cxs, pScreen, RealizeWindow, compositXRealizeWindow); + CompXWrap(cxs, pScreen, UnrealizeWindow, compositXUnrealizeWindow); + CompXWrap(cxs, pScreen, SetWindowPixmap, compositXSetWindowPixmap); +} + +static void +compositXInitBlockHandler(void *data, void *pTimeout) +{ + RemoveBlockAndWakeupHandlers(compositXInitBlockHandler, + compositXWakeupHandler, NULL); + + for (int i = 0; i < screenInfo.numScreens; i++) + compositXScreenSetup(screenInfo.screens[i]); +} + +static void* +compositXSetup(void* module, void* opts, int *errmaj, int *errmin) +{ + static Bool initialized = FALSE; + + if (initialized) { + if (errmaj) *errmaj = LDR_ONCEONLY; + return NULL; + } + initialized = TRUE; + + if (!dixRegisterPrivateKey(&compositXScreenPrivateKeyRec, + PRIVATE_SCREEN, + sizeof(CompXScreenRec)) || + !dixRegisterPrivateKey(&compositXWindowPrivateKeyRec, + PRIVATE_WINDOW, + sizeof(CompXWindowRec))) { + if (errmaj) *errmaj = LDR_NOMEM; + return NULL; + } + + compositXOpacityAtom = MakeAtom("_NET_WM_WINDOW_OPACITY", + sizeof("_NET_WM_WINDOW_OPACITY") - 1, + TRUE); + compositXBypassAtom = MakeAtom("_NET_WM_BYPASS_COMPOSITOR", + sizeof("_NET_WM_BYPASS_COMPOSITOR") - 1, + TRUE); + + RegisterBlockAndWakeupHandlers(compositXInitBlockHandler, + compositXWakeupHandler, NULL); + AddCallback(&PropertyStateCallback, compositXPropertyCallback, NULL); + + return module; +} + +#undef ShapeBounding +#undef ShapeClip +#undef ShapeInput + +static XF86ModuleVersionInfo compositXVersRec = { + "compositX", + "Spaghetti Fork", + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + 1, 0, 0, + ABI_CLASS_EXTENSION, + ABI_EXTENSION_VERSION, + MOD_CLASS_EXTENSION, + {0, 0, 0, 0} +}; + +_X_EXPORT XF86ModuleData compositxModuleData = { + &compositXVersRec, + compositXSetup, + NULL +}; \ No newline at end of file diff --git a/hw/xfree86/compositX/compositx.h b/hw/xfree86/compositX/compositx.h new file mode 100644 index 000000000..d3e1515ef --- /dev/null +++ b/hw/xfree86/compositX/compositx.h @@ -0,0 +1,77 @@ +/** + * Spaghetti Display Server + * Copyright (C) 2026 SpaghettiFork + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef COMPOSITX_H +#define COMPOSITX_H + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include "scrnintstr.h" +#include "windowstr.h" +#include "damage.h" +#include "compint.h" +#include "picturestr.h" + +/* sentinel for windows without _NET_WM_WINDOW_OPACITY */ +#define COMPOSITX_OPAQUE 0xffffffffU + +typedef struct _CompXScreen { + CloseScreenProcPtr CloseScreen; + CreateWindowProcPtr CreateWindow; + DestroyWindowProcPtr DestroyWindow; + RealizeWindowProcPtr RealizeWindow; + UnrealizeWindowProcPtr UnrealizeWindow; + SetWindowPixmapProcPtr SetWindowPixmap; + + Bool wrapped; /* guard against double-wrapping */ + + WindowPtr pOverlay; + PicturePtr pOverlayPicture; /* cached destination; freed in CloseScreen */ + RegionRec pendingDamage; /* accumulated dirty region, drained in block handler */ +} CompXScreenRec, *CompXScreenPtr; + +typedef struct _CompXWindow { + CARD32 opacity; /* _NET_WM_WINDOW_OPACITY value; COMPOSITX_OPAQUE if absent */ + Bool bypass; /* _NET_WM_BYPASS_COMPOSITOR == 1 */ + DamagePtr pDamage; +} CompXWindowRec, *CompXWindowPtr; + +extern DevPrivateKeyRec compositXScreenPrivateKeyRec; +extern DevPrivateKeyRec compositXWindowPrivateKeyRec; + +#define GetCompXScreen(s) \ + ((CompXScreenPtr) dixLookupPrivate(&(s)->devPrivates, \ + &compositXScreenPrivateKeyRec)) +#define GetCompXWindow(w) \ + ((CompXWindowPtr) dixLookupPrivate(&(w)->devPrivates, \ + &compositXWindowPrivateKeyRec)) + +#define CompXWrap(priv, real, field, func) do { \ + (priv)->field = (real)->field; \ + (real)->field = (func); \ +} while (0) + +#define CompXUnwrap(priv, real, field) \ + ((real)->field = (priv)->field) + +void compositXInitOverlay(ScreenPtr pScreen); +void compositXRepaint(ScreenPtr pScreen); + +#endif /* COMPOSITX_H */ \ No newline at end of file diff --git a/hw/xfree86/compositX/meson.build b/hw/xfree86/compositX/meson.build new file mode 100644 index 000000000..320b0018a --- /dev/null +++ b/hw/xfree86/compositX/meson.build @@ -0,0 +1,14 @@ +sources = [ + 'compositx.c', + 'render.c', +] + +shared_module('compositx', + sources, + include_directories: [ inc, xorg_inc ], + dependencies: common_dep, + link_with: [ xorg_server ], + c_args: xorg_c_args, + install: true, + install_dir: module_dir, +) \ No newline at end of file diff --git a/hw/xfree86/compositX/render.c b/hw/xfree86/compositX/render.c new file mode 100644 index 000000000..04e204c39 --- /dev/null +++ b/hw/xfree86/compositX/render.c @@ -0,0 +1,117 @@ +/** + * Spaghetti Display Server + * Copyright (C) 2026 SpaghettiFork + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "compositx.h" +#include "picturestr.h" +#include "dixstruct.h" + +static PictFormatPtr +compositXFormatForVisual(ScreenPtr pScreen, int depth, VisualID vid) +{ + for (int i = 0; i < pScreen->numVisuals; i++) { + if (pScreen->visuals[i].vid == vid) + return PictureMatchVisual(pScreen, depth, &pScreen->visuals[i]); + } + + return NULL; +} + +static PicturePtr +compositXSolidAlpha(CARD16 alpha) +{ + xRenderColor color = { 0, 0, 0, alpha }; + int error; + return CreateSolidPicture(0, &color, &error); +} + +void +compositXInitOverlay(ScreenPtr pScreen) +{ + CompXScreenPtr cxs = GetCompXScreen(pScreen); + PictFormatPtr pFormat; + int error; + + if (!cxs->pOverlay) + return; + + pFormat = compositXFormatForVisual(pScreen, cxs->pOverlay->drawable.depth, + wVisual(cxs->pOverlay)); + if (!pFormat) + return; + + cxs->pOverlayPicture = CreatePicture(0, &cxs->pOverlay->drawable, pFormat, + 0, NULL, serverClient, &error); +} + +void +compositXRepaint(ScreenPtr pScreen) +{ + CompXScreenPtr cxs = GetCompXScreen(pScreen); + PicturePtr pClear, pSrc, pMask; + PictFormatPtr pFormat; + PixmapPtr pPixmap; + CompXWindowPtr cxw; + WindowPtr pChild; + int error; + + if (!cxs->pOverlayPicture) + return; + + pClear = compositXSolidAlpha(0); + CompositePicture(PictOpSrc, pClear, NULL, cxs->pOverlayPicture, + 0, 0, 0, 0, 0, 0, pScreen->width, pScreen->height); + FreePicture(pClear, 0); + + for (pChild = pScreen->root->lastChild; pChild; pChild = pChild->prevSib) { + cxw = GetCompXWindow(pChild); + + if (!pChild->mapped || !GetCompWindow(pChild) || cxw->bypass) + continue; + + pPixmap = (*pScreen->GetWindowPixmap)(pChild); + if (!pPixmap) + continue; + + pFormat = compositXFormatForVisual(pScreen, pChild->drawable.depth, + wVisual(pChild)); + if (!pFormat) + continue; + + pSrc = CreatePicture(0, &pPixmap->drawable, pFormat, + 0, NULL, serverClient, &error); + if (!pSrc) + continue; + + pMask = (cxw->opacity != COMPOSITX_OPAQUE) + ? compositXSolidAlpha((CARD16)(cxw->opacity >> 16)) + : NULL; + + CompositePicture(PictOpOver, + pSrc, pMask, cxs->pOverlayPicture, + 0, 0, 0, 0, + pChild->drawable.x, pChild->drawable.y, + pChild->drawable.width, pChild->drawable.height); + + FreePicture(pSrc, 0); + if (pMask) + FreePicture(pMask, 0); + } +} \ No newline at end of file diff --git a/hw/xfree86/meson.build b/hw/xfree86/meson.build index b557ab048..aad446f28 100644 --- a/hw/xfree86/meson.build +++ b/hw/xfree86/meson.build @@ -131,6 +131,9 @@ subdir('shadowfb') if build_vgahw subdir('vgahw') endif +if build_compositx + subdir('compositX') +endif if build_fission subdir('drivers/fission') endif diff --git a/include/property.h b/include/property.h index f4cbdb1af..84eeb37c1 100644 --- a/include/property.h +++ b/include/property.h @@ -57,7 +57,7 @@ typedef struct _PropertyStateRec { int state; } PropertyStateRec; -extern CallbackListPtr PropertyStateCallback; +extern _X_EXPORT CallbackListPtr PropertyStateCallback; extern _X_EXPORT int dixLookupProperty(PropertyPtr * /*result */ , WindowPtr /*pWin */ , diff --git a/meson.build b/meson.build index 1ed5dd83e..070492056 100644 --- a/meson.build +++ b/meson.build @@ -358,6 +358,7 @@ if build_glamor epoxy_dep = dependency('epoxy', required: false) endif +build_compositx = get_option('compositx') and compositeproto_dep.found() # Lots of sha1 options, because Linux is about choice :) # The idea behind the ordering here is that we should first prefer system diff --git a/meson_options.txt b/meson_options.txt index ee9578494..6f4f5a787 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -12,7 +12,8 @@ option('xwin', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto', description: 'Enable XWin X server') option('xquartz', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto', description: 'Enable Xquartz X server') - +option('compositx', type: 'boolean', value: true, + description: 'Enable compositX, the built-in compositor') option('builder_addr', type: 'string', description: 'Builder address', value: 'xorg@lists.freedesktop.org') option('builder_string', type: 'string', description: 'Additional builder string')