Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
DISCONTINUED:openSUSE:11.1:Update
compiz-plugins-dmx
dmx-NOMAD.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File dmx-NOMAD.diff of Package compiz-plugins-dmx
diff --git a/dmx.c b/dmx.c index a7d1c8e..44c3326 100644 --- a/dmx.c +++ b/dmx.c @@ -20,15 +20,25 @@ typedef struct _DmxDisplay { Atom dmxRootAtom; Atom dmxNameAtom; + Atom dmxSupportingCmCheckAtom; } DmxDisplay; typedef struct _DmxScreen { - int windowPrivateIndex; - Window root; + int windowPrivateIndex; + Window root; + CompTexture bg; + + DrawWindowProc drawWindow; + PaintWindowProc paintWindow; + WindowMoveNotifyProc windowMoveNotify; + WindowResizeNotifyProc windowResizeNotify; } DmxScreen; typedef struct _DmxWindow { - char *name; + char *name; + Region region; + Window supportingCmCheckWindow; + CompTimeoutHandle checkHandle; } DmxWindow; #define GET_DMX_CORE(c) \ @@ -58,6 +68,178 @@ typedef struct _DmxWindow { GET_DMX_SCREEN (w->screen, \ GET_DMX_DISPLAY (w->screen->display))) +static Bool +dmxDrawWindow (CompWindow *w, + const CompTransform *transform, + const FragmentAttrib *attrib, + Region region, + unsigned int mask) +{ + Region wRegion = w->region; + Bool status; + + DMX_SCREEN (w->screen); + DMX_WINDOW (w); + + if (dw->region) + w->region = dw->region; + + UNWRAP (ds, w->screen, drawWindow); + status = (*w->screen->drawWindow) (w, transform, attrib, region, mask); + WRAP (ds, w->screen, drawWindow, dmxDrawWindow); + + w->region = wRegion; + + if (mask & PAINT_WINDOW_TRANSFORMED_MASK) + region = &infiniteRegion; + + if (w->redirectSubwindows && + w->desktopWindowCount == 0 && + dw->name && + ds->bg.name && + region->numRects) + { + CompMatrix matrix; + + if (mask & PAINT_WINDOW_TRANSLUCENT_MASK) + mask |= PAINT_WINDOW_BLEND_MASK; + + matrix.xx = 1.0f / w->width; + matrix.yy = 1.0f / w->height; + matrix.x0 = w->attrib.x * w->matrix.xx; + matrix.y0 = w->attrib.y * w->matrix.yy; + + w->vCount = w->indexCount = 0; + (*w->screen->addWindowGeometry) (w, &matrix, 1, w->region, region); + if (w->vCount) + (*w->screen->drawWindowTexture) (w, &ds->bg, attrib, mask); + } + + return status; +} + +static Bool +dmxPaintWindow (CompWindow *w, + const WindowPaintAttrib *attrib, + const CompTransform *transform, + Region region, + unsigned int mask) +{ + Bool status; + + DMX_SCREEN (w->screen); + DMX_WINDOW (w); + + if (dw->region) + mask |= PAINT_WINDOW_TRANSLUCENT_MASK; + + UNWRAP (ds, w->screen, paintWindow); + status = (*w->screen->paintWindow) (w, attrib, transform, region, mask); + WRAP (ds, w->screen, paintWindow, dmxPaintWindow); + + return status; +} + +static void +dmxWindowUpdateRootRegion (CompWindow *w) +{ + Region region = NULL; + CompWindow *c; + int dx = 0; + int dy = 0; + + DMX_SCREEN (w->screen); + + for (;;) + { + region = GET_DMX_WINDOW (w, ds)->region; + if (region) + break; + + if (!w->parent) + return; + + w = w->parent; + } + + XSubtractRegion (w->region, &emptyRegion, region); + + c = w; + for (;;) + { + DMX_WINDOW (c); + + if (dw->name) + { + if (c->redirectSubwindows) + { + XOffsetRegion (c->region, dx, dy); + XSubtractRegion (region, c->region, region); + XOffsetRegion (c->region, -dx, -dy); + } + } + else + { + if (c->windows) + { + dx += c->attrib.x; + dy += c->attrib.y; + c = c->windows; + continue; + } + } + + while (!c->next && (c != w)) + { + dx -= c->parent->attrib.x; + dy -= c->parent->attrib.y; + c = c->parent; + } + + if (c == w) + break; + + c = c->next; + } +} + +static void +dmxWindowMoveNotify (CompWindow *w, + int dx, + int dy, + Bool immediate) +{ + DMX_SCREEN (w->screen); + DMX_WINDOW (w); + + if (dw->region) + XOffsetRegion (dw->region, dx, dy); + else if (dw->name) + dmxWindowUpdateRootRegion (w); + + UNWRAP (ds, w->screen, windowMoveNotify); + (*w->screen->windowMoveNotify) (w, dx, dy, immediate); + WRAP (ds, w->screen, windowMoveNotify, dmxWindowMoveNotify); +} + +static void +dmxWindowResizeNotify (CompWindow *w, + int dx, + int dy, + int dwidth, + int dheight) +{ + DMX_SCREEN (w->screen); + DMX_WINDOW (w); + + if (dw->name || dw->region) + dmxWindowUpdateRootRegion (w); + + UNWRAP (ds, w->screen, windowResizeNotify); + (*w->screen->windowResizeNotify) (w, dx, dy, dwidth, dheight); + WRAP (ds, w->screen, windowResizeNotify, dmxWindowResizeNotify); +} + static char * dmxWindowGetDmxNameProp (CompWindow *w) { @@ -85,41 +267,114 @@ dmxWindowGetDmxNameProp (CompWindow *w) return name; } -static Bool -dmxWindowCheckDmxName (CompWindow *w) +static void +dmxWindowSupportingCmCheck (CompWindow *w, + Bool closeDown) { - CompDisplay *d = w->screen->display; - Window rootReturn, parentReturn; - Window *children; - unsigned int nchildren, i; + CompDisplay *d = w->screen->display; + DMX_DISPLAY (d); DMX_WINDOW (w); - if (w->redirectSubwindows || w->substructureRedirect || w->windows) - return FALSE; + dw->supportingCmCheckWindow = None; - if (dw->name) - return TRUE; + if (!closeDown) + { + Atom actual; + int result, format; + unsigned long n, left; + unsigned char *propData; + + result = XGetWindowProperty (d->display, w->id, + dd->dmxSupportingCmCheckAtom, 0L, 1L, + FALSE, XA_WINDOW, &actual, &format, + &n, &left, &propData); + if (result == Success && n && propData) + { + Window cmCheckWindow = *((unsigned long *) propData); + + XFree (propData); + + result = XGetWindowProperty (d->display, + cmCheckWindow, + dd->dmxSupportingCmCheckAtom, 0L, 1L, + FALSE, XA_WINDOW, &actual, &format, + &n, &left, &propData); + if (result == Success && n && propData) + { + dw->supportingCmCheckWindow = cmCheckWindow; + XFree (propData); + } + } + } - dw->name = dmxWindowGetDmxNameProp (w); - if (!dw->name) - return FALSE; + if (dw->supportingCmCheckWindow) + { + if (!w->redirectSubwindows) + { + Window rootReturn, parentReturn; + Window *children; + unsigned int nchildren, i; + + XCompositeRedirectSubwindows (d->display, w->id, + CompositeRedirectManual); + w->redirectSubwindows = TRUE; + + XSelectInput (d->display, w->id, + SubstructureNotifyMask | + StructureNotifyMask | + PropertyChangeMask); + + w->activeChild = getActiveWindow (d, w->id); + + XQueryTree (d->display, w->id, + &rootReturn, &parentReturn, + &children, &nchildren); + + for (i = 0; i < nchildren; i++) + addWindow (w, children[i], i ? children[i - 1] : 0); - XCompositeRedirectSubwindows (d->display, w->id, - CompositeRedirectManual); - w->redirectSubwindows = TRUE; + dmxWindowUpdateRootRegion (w); + } + } + else + { + if (w->redirectSubwindows) + { + while (w->windows) + removeWindow (w->windows); + + XSelectInput (d->display, w->id, StructureNotifyMask | + PropertyChangeMask); + + w->redirectSubwindows = FALSE; + XCompositeUnredirectSubwindows (d->display, w->id, + CompositeRedirectManual); - XSelectInput (d->display, w->id, - SubstructureNotifyMask | - StructureNotifyMask | - PropertyChangeMask); + dmxWindowUpdateRootRegion (w); + } + } +} - XQueryTree (d->display, w->id, - &rootReturn, &parentReturn, - &children, &nchildren); +static Bool +dmxWindowCheckDmxName (CompWindow *w) +{ + DMX_WINDOW (w); + + if (!w->parent) + return FALSE; + + if (w->redirectSubwindows || w->substructureRedirect || w->windows) + return FALSE; + + if (!dw->name) + { + dw->name = dmxWindowGetDmxNameProp (w); + if (!dw->name) + return FALSE; + } - for (i = 0; i < nchildren; i++) - addWindow (w, children[i], i ? children[i - 1] : 0); + dmxWindowSupportingCmCheck (w, FALSE); return TRUE; } @@ -183,16 +438,26 @@ dmxEnsureDmxRoot (CompWindow *ancestor, CompWindow *c; unsigned int i; - for (i = 0; i < npchildren; i++) - if (pchildren[i] == id) - addWindow (w, id, i ? pchildren[i - 1] : 0); + for (c = w->windows; c; c = c->next) + if (c->id == id) + break; + + if (!c) + { + for (i = 0; i < npchildren; i++) + if (pchildren[i] == id) + addWindow (w, id, i ? pchildren[i - 1] : 0); + + for (c = w->windows; c; c = c->next) + if (c->id == id) + break; + } if (pchildren) XFree (pchildren); - for (c = w->windows; c; c = c->next) - if (c->id == id) - return c; + if (c) + return c; } if (*children) @@ -217,6 +482,13 @@ dmxWindowCheckDmxRoot (CompWindow *w) if (!root) return FALSE; + if (!dw->region) + { + dw->region = XCreateRegion (); + if (dw->region) + XSubtractRegion (w->region, &emptyRegion, dw->region); + } + for (i = 0; i < n; i++) { CompWindow *r; @@ -226,20 +498,12 @@ dmxWindowCheckDmxRoot (CompWindow *w) ds->root = root[i]; r = dmxEnsureDmxRoot (w, root[i], &children, &nchildren); - if (r) - { - - dmxWindowCheckDmxName (r); - if (children) - XFree (children); - } + if (r && children) + XFree (children); } ds->root = None; - if (root) - free (root); - return TRUE; } @@ -251,6 +515,19 @@ dmxHandleEvent (CompDisplay *d, DMX_DISPLAY (d); + switch (event->type) { + case DestroyNotify: + w = findWindowAtDisplay (d, event->xdestroywindow.window); + if (w && w->parent) + { + DMX_WINDOW (w->parent); + + if (dw->name && dw->supportingCmCheckWindow == w->id) + dmxWindowSupportingCmCheck (w->parent, FALSE); + } + break; + } + UNWRAP (dd, d, handleEvent); (*d->handleEvent) (d, event); WRAP (dd, d, handleEvent, dmxHandleEvent); @@ -260,25 +537,59 @@ dmxHandleEvent (CompDisplay *d, if (event->xproperty.atom == dd->dmxNameAtom) { w = findWindowAtDisplay (d, event->xproperty.window); - if (w) + if (w && w->screen->root.redirectSubwindows) dmxWindowCheckDmxName (w); } else if (event->xproperty.atom == dd->dmxRootAtom) { w = findWindowAtDisplay (d, event->xproperty.window); - if (w) + if (w && w->screen->root.redirectSubwindows) dmxWindowCheckDmxRoot (w); } + else if (event->xproperty.atom == dd->dmxSupportingCmCheckAtom) + { + w = findWindowAtDisplay (d, event->xproperty.window); + if (w) + { + DMX_WINDOW (w); + + if (dw->name) + dmxWindowSupportingCmCheck (w, FALSE); + } + } break; } } +static Bool +dmxWindowCheck (void *closure) +{ + CompWindow *w = (CompWindow *) closure; + + DMX_WINDOW (w); + + if (!w->parent->substructureRedirect && !w->parent->redirectSubwindows) + XSelectInput (w->screen->display->display, w->id, + StructureNotifyMask | PropertyChangeMask); + + if (!dmxWindowCheckDmxName (w)) + dmxWindowCheckDmxRoot (w); + + dw->checkHandle = 0; + + return FALSE; +} + static void dmxWindowAdd (CompWindow *parent, CompWindow *w) { - if (!dmxWindowCheckDmxName (w)) - dmxWindowCheckDmxRoot (w); + DMX_WINDOW (w); + + if (!w->screen->root.redirectSubwindows || !w->parent) + return; + + dw->checkHandle = compAddTimeout (0, 0, dmxWindowCheck, w); } static void @@ -310,9 +621,6 @@ dmxInitCore (CompPlugin *p, if (!checkPluginABI ("core", CORE_ABIVERSION)) return FALSE; - if (!checkPluginABI ("glx", CORE_ABIVERSION)) - return FALSE; - dc = malloc (sizeof (DmxCore)); if (!dc) return FALSE; @@ -363,6 +671,9 @@ dmxInitDisplay (CompPlugin *plugin, CompDisplay *d) dd->dmxNameAtom = XInternAtom (d->display, "DMX_NAME", 0); dd->dmxRootAtom = XInternAtom (d->display, "DMX_ROOT", 0); + dd->dmxSupportingCmCheckAtom = + XInternAtom (d->display, "_DMX_SUPPORTING_CM_CHECK", 0); + d->base.privates[displayPrivateIndex].ptr = dd; WRAP (dd, d, handleEvent, dmxHandleEvent); @@ -385,7 +696,8 @@ dmxFiniDisplay (CompPlugin *plugin, CompDisplay *d) static Bool dmxInitScreen (CompPlugin *plugin, CompScreen *s) { - DmxScreen *ds; + DmxScreen *ds; + const char black[3] = { 0, 0, 0 }; DMX_DISPLAY (s->display); @@ -402,16 +714,48 @@ dmxInitScreen (CompPlugin *plugin, CompScreen *s) ds->root = None; + initTexture (s, &ds->bg); + + if (s->root.redirectSubwindows) + imageDataToTexture (s, &ds->bg, black, 1, 1, GL_RGB, GL_UNSIGNED_BYTE); + + WRAP (ds, s, drawWindow, dmxDrawWindow); + WRAP (ds, s, paintWindow, dmxPaintWindow); + WRAP (ds, s, windowMoveNotify, dmxWindowMoveNotify); + WRAP (ds, s, windowResizeNotify, dmxWindowResizeNotify); + s->base.privates[dd->screenPrivateIndex].ptr = ds; + XChangeProperty (s->display->display, s->grabWindow, + dd->dmxSupportingCmCheckAtom, + XA_WINDOW, 32, PropModeReplace, + (unsigned char *) &s->grabWindow, 1); + XChangeProperty (s->display->display, s->root.id, + dd->dmxSupportingCmCheckAtom, + XA_WINDOW, 32, PropModeReplace, + (unsigned char *) &s->grabWindow, 1); + return TRUE; } static void dmxFiniScreen (CompPlugin *plugin, CompScreen *s) { + DMX_DISPLAY (s->display); DMX_SCREEN (s); + XDeleteProperty (s->display->display, s->grabWindow, + dd->dmxSupportingCmCheckAtom); + XDeleteProperty (s->display->display, s->root.id, + dd->dmxSupportingCmCheckAtom); + + UNWRAP (ds, s, drawWindow); + UNWRAP (ds, s, paintWindow); + UNWRAP (ds, s, windowMoveNotify); + UNWRAP (ds, s, windowResizeNotify); + + finiTexture (s, &ds->bg); + freeWindowPrivateIndex (s, ds->windowPrivateIndex); free (ds); @@ -428,7 +772,10 @@ dmxInitWindow (CompPlugin *plugin, CompWindow *w) if (!dw) return FALSE; - dw->name = NULL; + dw->name = NULL; + dw->region = NULL; + dw->supportingCmCheckWindow = None; + dw->checkHandle = 0; w->base.privates[ds->windowPrivateIndex].ptr = dw; @@ -444,25 +791,28 @@ dmxInitWindow (CompPlugin *plugin, CompWindow *w) static void dmxFiniWindow (CompPlugin *plugin, CompWindow *w) { + DMX_SCREEN (w->screen); DMX_WINDOW (w); + if (!dw) + return; + + if (dw->checkHandle) + compRemoveTimeout (dw->checkHandle); + if (dw->name) { if (!w->destroyed) - { - CompDisplay *d = w->screen->display; - - XCompositeUnredirectSubwindows (d->display, - w->id, - CompositeRedirectManual); - w->redirectSubwindows = TRUE; - XSelectInput (d->display, w->id, 0); - } + dmxWindowSupportingCmCheck (w, TRUE); free (dw->name); } + if (dw->region) + XDestroyRegion (dw->region); + free (dw); + w->base.privates[ds->windowPrivateIndex].ptr = NULL; } static CompBool diff --git a/dmx.xml.in b/dmx.xml.in index 03bee85..1134db9 100644 --- a/dmx.xml.in +++ b/dmx.xml.in @@ -3,11 +3,6 @@ <!-- dmx metadata --> <plugin name="dmx" useBcop="true"> <category>Utility</category> - <deps> - <requirement> - <plugin>glx</plugin> - </requirement> - </deps> <_short>DMX</_short> <_long>DMX output compositing</_long> </plugin>
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor