#include #include #include #include #include "basicblur_options.h" #include #include #ifndef PAINT_WINDOW_DECORATION_MASK #define PAINT_WINDOW_DECORATION_MASK (1 << 4) #endif static 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 system typedef 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 void basicblurToggleWindow (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 void basicblurToggleScreen (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 Bool basicblurToggle (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 Bool basicblurToggleAll (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 void basicblurHandleEvent (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 void basicblurDrawWindowTexture (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 void basicblurDonePaintScreen (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 Bool basicblurInitDisplay (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 void basicblurFiniDisplay (CompPlugin *p, CompDisplay *d) { BASICBLUR_DISPLAY (d); freeScreenPrivateIndex (d, nd->screenPrivateIndex); free (nd); } static Bool basicblurInitScreen (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; ibase.privates[nd->screenPrivateIndex].ptr = ns; return TRUE; } static void basicblurFiniScreen (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 Bool basicblurInitWindow (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 void basicblurFiniWindow (CompPlugin *p, CompWindow *w) { BASICBLUR_WINDOW (w); free (nw); } static Bool basicblurInit (CompPlugin *p) { BasicBlurdisplayPrivateIndex = allocateDisplayPrivateIndex (); if (BasicBlurdisplayPrivateIndex < 0) return FALSE; return TRUE; } static void basicblurFini (CompPlugin *p) { if (BasicBlurdisplayPrivateIndex >= 0) freeDisplayPrivateIndex (BasicBlurdisplayPrivateIndex); free(convfilter); } static CompBool basicblurInitObject (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 void basicblurFiniObject (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; }