rendered paste body#include <X11/Xatom.h>#include <X11/extensions/Xrender.h>#include <X11/extensions/Xcomposite.h>#include <compiz-core.h>#include "basicblur_options.h"#include <math.h>#include <GL/glext.h>#ifndef PAINT_WINDOW_DECORATION_MASK#define PAINT_WINDOW_DECORATION_MASK (1 << 4)#endifstatic int BasicBlurdisplayPrivateIndex;static GLfloat * convfilter;static int fsize = 5 ;// should be an option. Hackers please help :D// Basically, the only thing that actually works properly is when I call toggleWindow which// seems to unredirect then redirect windows which is no good. Otherwise it detects focus changes// but the screen isn't redrawn properly. The only thing I can think of is to re-apply the filter// or re-work the toggling systemtypedef struct _basicblurDisplay { int screenPrivateIndex; HandleEventProc handleEvent;} basicblurDisplay;typedef struct _basicblurSCreen { int windowPrivateIndex; DrawWindowTextureProc drawWindowTexture; DamageWindowRectProc damageWindowRect; DonePaintScreenProc donePaintScreen; Bool isBlured;} basicblurScreen;typedef struct _basicblurWindow { Bool first; Bool isBlured;} basicblurWindow;#define GET_BASICBLUR_DISPLAY(d) ((basicblurDisplay *) (d)->base.privates[BasicBlurdisplayPrivateIndex].ptr)#define BASICBLUR_DISPLAY(d) basicblurDisplay *nd = GET_BASICBLUR_DISPLAY (d)#define GET_BASICBLUR_SCREEN(s, nd) ((basicblurScreen *) (s)->base.privates[(nd)->screenPrivateIndex].ptr)#define BASICBLUR_SCREEN(s) basicblurScreen *ns = GET_BASICBLUR_SCREEN (s, GET_BASICBLUR_DISPLAY (s->display))#define GET_BASICBLUR_WINDOW(w, ns) ((basicblurWindow *) (w)->base.privates[(ns)->windowPrivateIndex].ptr)#define BASICBLUR_WINDOW(w) basicblurWindow *nw = GET_BASICBLUR_WINDOW (w, GET_BASICBLUR_SCREEN (w->screen, GET_BASICBLUR_DISPLAY (w->screen->display)))#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))static void windowWalk (CompDisplay *d){ fprintf(stderr, "windowWalk"); CompScreen *s; CompWindow *w; for (s = d->screens; s; s = s->next) { for (w = s->windows; w; w = w->next) { fprintf(stderr, "gettingVars\n"); BASICBLUR_WINDOW (w); BASICBLUR_SCREEN (s); nw->isBlured = FALSE; // We only want window blurring to change // if the screen is toggled if (!ns->isBlured) { addWindowDamage(w); continue; } if (w->id == d->activeWindow) { addWindowDamage(w); continue; } if (w->invisible || w->destroyed || w->hidden || w->minimized) { addWindowDamage(w); continue; } //if (!matchEval (addhelperGetWindowTypes (d), w)) //continue; nw->isBlured = TRUE; } // Tried this but nothing damageScreen (s); } //damageScreen (s); fprintf(stderr, "FinwindowWalk");}static voidbasicblurToggleWindow (CompWindow *w){ if((w->type & CompWindowTypeNormalMask) || (w->type & CompWindowTypeDesktopMask)) { BASICBLUR_WINDOW (w); nw->isBlured = !nw->isBlured; nw->first = TRUE; // Only this works, and it is a major hack that should be avoided if(w->redirected) { unredirectWindow(w); redirectWindow(w); } addWindowDamage(w); }}static voidbasicblurToggleScreen (CompScreen *s){ CompWindow *w; BASICBLUR_SCREEN (s); fprintf(stderr, "togglescreen"); ns->isBlured = !ns->isBlured; for (w = s->windows; w; w = w->next) if (w) basicblurToggleWindow (w);}static BoolbasicblurToggle (CompDisplay *d, CompAction *action, CompActionState state, CompOption *option, int nOption){ CompWindow *w; Window xid; xid = getIntOptionNamed (option, nOption, "window", 0); w = findWindowAtDisplay (d, xid); if (w) basicblurToggleWindow (w); return TRUE;}static BoolbasicblurToggleAll (CompDisplay *d, CompAction *action, CompActionState state, CompOption *option, int nOption){ CompScreen *s; Window xid; xid = getIntOptionNamed (option, nOption, "root", 0); s = findScreenAtDisplay (d, xid); fprintf(stderr, "toggleall"); // We invert the active window. // When calling the toggle all, the active window gets // the focus because it will be the only one without blur. Window xid2 = getIntOptionNamed (option, nOption, "window", 0); CompWindow * w = findWindowAtDisplay (d, xid2); if((w->type & CompWindowTypeNormalMask) || (w->type & CompWindowTypeDesktopMask)) { BASICBLUR_WINDOW (w); nw->isBlured = !nw->isBlured; nw->first = TRUE; } if (s) basicblurToggleScreen (s); return TRUE;}static voidbasicblurHandleEvent (CompDisplay *d, XEvent *event){ Window activeWindow = d->activeWindow; CompWindow *w; w = findWindowAtDisplay (d, activeWindow); // It will die if there ISNT a window.... BASICBLUR_DISPLAY (d); UNWRAP(nd, d, handleEvent); (*d->handleEvent) (d, event); WRAP(nd, d, handleEvent, basicblurHandleEvent); if (!(w)) { return; } BASICBLUR_SCREEN (w->screen); if (!ns->isBlured) { return; } //if (activeWindow != d->activeWindow) windowWalk (d); fprintf(stderr, "finHandleEvent");}static voidbasicblurDrawWindowTexture (CompWindow *w, CompTexture *texture, const FragmentAttrib *attrib, unsigned int mask){ BASICBLUR_SCREEN (w->screen); BASICBLUR_WINDOW (w); UNWRAP (ns, w->screen, drawWindowTexture); //fsize = basicblurGetBlurFactor(w->screen); //fprintf(stderr, "%i", fsize); if(nw->isBlured && !(mask & PAINT_WINDOW_DECORATION_MASK)) { // We use a convolution filter glEnable(GL_CONVOLUTION_2D); glConvolutionFilter2D (GL_CONVOLUTION_2D, GL_RGBA, fsize, fsize, GL_RGBA, GL_FLOAT, convfilter); glConvolutionParameteri (GL_CONVOLUTION_2D, GL_CONVOLUTION_BORDER_MODE, GL_REPLICATE_BORDER); (*w->screen->drawWindowTexture) (w, texture, attrib, mask); if(nw->first) { nw->first = FALSE; } glDisable(GL_CONVOLUTION_2D); } else { (*w->screen->drawWindowTexture)(w, texture, attrib, mask); } WRAP (ns, w->screen, drawWindowTexture, basicblurDrawWindowTexture);}static Bool basicblurDamageWindowRect (CompWindow *w, Bool initial, BoxPtr rect){ int status; BASICBLUR_SCREEN (w->screen); BASICBLUR_WINDOW (w); if (initial) { if (ns->isBlured && !nw->isBlured) basicblurToggleWindow (w); } UNWRAP (ns, w->screen, damageWindowRect); status = (*w->screen->damageWindowRect) (w, initial, rect); WRAP (ns, w->screen, damageWindowRect, basicblurDamageWindowRect); return status;}static voidbasicblurDonePaintScreen (CompScreen *s){ // Tried this but nothing BASICBLUR_SCREEN (s); //fprintf(stderr, "\ndonePaintScreen"); CompWindow *w; if (ns->isBlured) { for (w = s->windows; w; w = w->next) { BASICBLUR_WINDOW (w); //if (!nw->isBlured) // fprintf(stderr, "\naddWindowDamage"); damageScreen (s); } } UNWRAP (ns, s, donePaintScreen); (*s->donePaintScreen) (s); WRAP (ns, s, donePaintScreen, basicblurDonePaintScreen);}static BoolbasicblurInitDisplay (CompPlugin *p, CompDisplay *d){ basicblurDisplay *nd; nd = malloc (sizeof (basicblurDisplay)); if (!nd) return FALSE; nd->screenPrivateIndex = allocateScreenPrivateIndex (d); if (nd->screenPrivateIndex < 0) { free (nd); return FALSE; } d->base.privates[BasicBlurdisplayPrivateIndex].ptr = nd; basicblurSetWindowToggleKeyInitiate (d, basicblurToggle); basicblurSetScreenToggleKeyInitiate (d, basicblurToggleAll); WRAP (nd, d, handleEvent, basicblurHandleEvent); return TRUE;}static voidbasicblurFiniDisplay (CompPlugin *p, CompDisplay *d){ BASICBLUR_DISPLAY (d); freeScreenPrivateIndex (d, nd->screenPrivateIndex); free (nd); }static BoolbasicblurInitScreen (CompPlugin *p, CompScreen *s){ basicblurScreen *ns; BASICBLUR_DISPLAY (s->display); ns = malloc (sizeof (basicblurScreen)); if (!ns) return FALSE; ns->windowPrivateIndex = allocateWindowPrivateIndex (s); if (ns->windowPrivateIndex < 0) { free (ns); return FALSE; } ns->isBlured = FALSE; WRAP (ns, s, drawWindowTexture, basicblurDrawWindowTexture); WRAP (ns, s, damageWindowRect, basicblurDamageWindowRect); WRAP (ns, s, donePaintScreen, basicblurDonePaintScreen); // We fill in the convolution filter (gaussian blur) //fsize = basicblurGetBlurFactor(s); //fprintf(stderr, "%i", fsize); unsigned int i = 0; unsigned int j = 0; double k = (((double)fsize)-1.)/2.; double somme = 0.; double sigma2 = fsize * fsize / 4.; convfilter = malloc(4 * fsize * fsize * sizeof(GLfloat)); GLfloat * gaussien = malloc(fsize * fsize * sizeof(GLfloat)); for(i=0; i<fsize;i++) for(j=0; j<fsize;j++) { gaussien[fsize * i + j]=exp(-((double)(i-k)*(i-k)+(j-k)*(j-k))/ (2.*sigma2)); } for(i=0; i<fsize;i++) for(j=0; j<fsize;j++) somme +=gaussien[fsize * i + j]; for(i = 0; i < fsize; i++) for(j = 0; j < fsize; j++) { convfilter[4 * (fsize * i + j) ] = gaussien[(fsize * i + j)] / somme; convfilter[4 * (fsize * i + j) + 1] = gaussien[(fsize * i + j)] / somme; convfilter[4 * (fsize * i + j) + 2] = gaussien[(fsize * i + j)] / somme; convfilter[4 * (fsize * i + j) + 3] = gaussien[(fsize * i + j)] / somme; } free(gaussien); s->base.privates[nd->screenPrivateIndex].ptr = ns; return TRUE;}static voidbasicblurFiniScreen (CompPlugin *p, CompScreen *s){ BASICBLUR_SCREEN (s); freeWindowPrivateIndex (s, ns->windowPrivateIndex); UNWRAP (ns, s, drawWindowTexture); UNWRAP (ns, s, damageWindowRect); UNWRAP (ns, s, donePaintScreen); free (ns);}static BoolbasicblurInitWindow (CompPlugin *p, CompWindow *w){ basicblurWindow *nw; BASICBLUR_SCREEN (w->screen); nw = malloc (sizeof (basicblurWindow)); if (!nw) return FALSE; nw->isBlured = FALSE; nw->first = FALSE; w->base.privates[ns->windowPrivateIndex].ptr = nw; return TRUE;}static voidbasicblurFiniWindow (CompPlugin *p, CompWindow *w){ BASICBLUR_WINDOW (w); free (nw);}static BoolbasicblurInit (CompPlugin *p){ BasicBlurdisplayPrivateIndex = allocateDisplayPrivateIndex (); if (BasicBlurdisplayPrivateIndex < 0) return FALSE; return TRUE;}static voidbasicblurFini (CompPlugin *p){ if (BasicBlurdisplayPrivateIndex >= 0) freeDisplayPrivateIndex (BasicBlurdisplayPrivateIndex); free(convfilter);}static CompBoolbasicblurInitObject (CompPlugin *p, CompObject *o){ static InitPluginObjectProc dispTab[] = { (InitPluginObjectProc) 0, /* InitCore */ (InitPluginObjectProc) basicblurInitDisplay, (InitPluginObjectProc) basicblurInitScreen, (InitPluginObjectProc) basicblurInitWindow }; RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));}static voidbasicblurFiniObject (CompPlugin *p, CompObject *o){ static FiniPluginObjectProc dispTab[] = { (FiniPluginObjectProc) 0, /* FiniCore */ (FiniPluginObjectProc) basicblurFiniDisplay, (FiniPluginObjectProc) basicblurFiniScreen, (FiniPluginObjectProc) basicblurFiniWindow }; DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));}CompPluginVTable basicblurVTable = { "basicblur", 0, basicblurInit, basicblurFini, basicblurInitObject, basicblurFiniObject, 0, 0};CompPluginVTable *getCompPluginInfo (void){ return &basicblurVTable;}