/*----------------------------------------------------------------------------*\ | Copyright (C) 2009 - Rafael de O. Lopes Gonçalves and André Shoji Asato | | 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 2 | | of the License. | | | | 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, write to the Free Software | | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.| \*----------------------------------------------------------------------------*/ #include #include #include #include #include #include #include "visocor_options.h" #include "visocor.h" int visocorDisplayPrivateIndex; int visocorCorePrivateIndex; /* debug function */ void visocorPrintf(CompLogLevel level, const char *fmt, ...) { va_list args; va_start(args, fmt); char logInfo[BUFSIZ]; if (vsnprintf(logInfo, BUFSIZ, fmt, args) < 0) { va_end(args); return; } logMessage(PLUGIN_NAME, level, logInfo); va_end(args); } void visocorToggleWindowToState(CompWindow * w, VisocorWindowState state) { VISOCOR_WINDOW(w); vw->lastState = vw->currentState; vw->currentState = state; if (matchEval(visocorGetExcludeMatch(w->screen), w)) vw->currentState = OFF; /*repainting */ addWindowDamage(w); } void visocorDamageAllWindows(CompScreen * s) { CompWindow *w; for (w = s->windows; w; w = w->next) { if (w) { addWindowDamage(w); } } } CompScreen * visocorFindScreen(CompDisplay * d, CompOption * option, int nOption) { CompScreen *s; Window xid; xid = getIntOptionNamed(option, nOption, "root", 0); s = findScreenAtDisplay(d, xid); return s; } CompWindow * visocorFindWindow(CompDisplay * d, CompOption * option, int nOption) { CompWindow * w; Window xid; xid = getIntOptionNamed(option, nOption, "window", 0); w = findWindowAtDisplay(d, xid); return w; } static void VISOCORDrawWindowTexture(CompWindow * w, CompTexture * texture, const FragmentAttrib * attrib, unsigned int mask) { VISOCOR_SCREEN(w->screen); VISOCOR_WINDOW(w); if (vw->currentState != OFF && (texture->name == w->texture->name)) { if (w->screen->fragmentProgram) { FragmentAttrib fa = *attrib; /*aloca 1 argumento de programa*/ int param = allocFragmentParameters(&fa, 2); int function = 0; if (vw->currentState == FILTER) { function = getVisocorFilterFragmentFunction(w->screen, texture, param); } else { function = getVisocorSlicerFragmentFunction(w->screen, texture, param); } if (function) { addFragmentFunction(&fa, function); } UNWRAP(vs, w->screen, drawWindowTexture); (*w->screen->drawWindowTexture)(w, texture, &fa, mask); WRAP(vs, w->screen, drawWindowTexture, VISOCORDrawWindowTexture) ; } else { logMessage(PLUGIN_NAME, CompLogLevelError, "not w->screen->fragmentProgram"); } } else { UNWRAP(vs, w->screen, drawWindowTexture); (*w->screen->drawWindowTexture)(w, texture, attrib, mask); WRAP(vs, w->screen, drawWindowTexture, VISOCORDrawWindowTexture) ; } } static void VISOCORWindowAdd(CompScreen * s, CompWindow * w) { if (matchEval(visocorGetVisocorMatch(s), w)) { visocorToggleWindowToState(w, FILTER); } } static void VISOCORScreenOptionChanged(CompScreen * s, CompOption * opt, VisocorScreenOptions num) { visocorPrintf(CompLogLevelDebug, "option %d changed", num); switch (num) { case VisocorScreenOptionVisocorMatch: case VisocorScreenOptionExcludeMatch: { CompWindow *w; for (w = s->windows; w; w = w->next) { Bool notExclude; VISOCOR_WINDOW(w); notExclude = matchEval(visocorGetVisocorMatch(s), w); notExclude = notExclude && !matchEval(visocorGetExcludeMatch(s), w); if (!notExclude && vw->currentState != OFF) visocorToggleWindowToState(w, OFF); } } break; default: break; } visocorDamageAllWindows(s); } static void visocorObjectAdd(CompObject * parent, CompObject * object) { static ObjectAddProc dispTab[] = { (ObjectAddProc) 0, /* CoreAdd */ (ObjectAddProc) 0, /* DisplayAdd */ (ObjectAddProc) 0, /* ScreenAdd */ (ObjectAddProc) VISOCORWindowAdd }; VISOCOR_CORE(&core); UNWRAP(vc, &core, objectAdd); (*core.objectAdd)(parent, object); WRAP(vc, &core, objectAdd, visocorObjectAdd); DISPATCH(object, dispTab, ARRAY_SIZE(dispTab), (parent, object)); } static Bool VISOCORInitCore(CompPlugin * p, CompCore * c) { VISOCORCore *vc; if (!checkPluginABI("core", CORE_ABIVERSION)) return FALSE; if (!checkPluginABI("mousepoll", MOUSEPOLL_ABIVERSION)) return FALSE; vc = malloc(sizeof(VISOCORCore)); if (!vc) return FALSE; visocorDisplayPrivateIndex = allocateDisplayPrivateIndex(); if (visocorDisplayPrivateIndex < 0) { free(vc); return FALSE; } WRAP(vc, c, objectAdd, visocorObjectAdd); c->base.privates[visocorCorePrivateIndex].ptr = vc; return TRUE; } static void VISOCORFiniCore(CompPlugin * p, CompCore * c) { VISOCOR_CORE(c); freeDisplayPrivateIndex(visocorDisplayPrivateIndex); UNWRAP(vc, c, objectAdd); free(vc); } static Bool visocorReset(CompDisplay *d, CompAction *action, CompActionState state, CompOption *option, int nOption) { CompScreen * s; for (s = d->screens; s; s = s->next) { VISOCOR_SCREEN(s); CompWindow * w; for (w = s->windows; w; w = w->next) { if (w) { visocorToggleWindowToState(w, OFF); } } visocorResetFilter(vs); } return TRUE; } static Bool VISOCORInitDisplay(CompPlugin * p, CompDisplay * d) { VISOCORDisplay *nd; int mousePoolIndex; nd = malloc(sizeof(VISOCORDisplay)); if (!nd) return FALSE; if (!getPluginDisplayIndex(d, "mousepoll", &mousePoolIndex)) return FALSE; nd->screenPrivateIndex = allocateScreenPrivateIndex(d); if (nd->screenPrivateIndex < 0) { free(nd); return FALSE; } visocorSetIncreaseButtonInitiate(d, visocorIncreaseFilter); visocorSetDecreaseButtonInitiate(d, visocorDecreaseFilter); visocorSetWindowToggleKeyInitiate(d, visocorToggleFilter); visocorSetMousepollClickKeyInitiate(d, visocorMousepollClickKeyInitiateSlice); visocorSetMousepollClickKeyTerminate(d, visocorMousepollClickKeyTerminateSlice); visocorSetScreenResetKeyInitiate(d, visocorReset); d->base.privates[visocorDisplayPrivateIndex].ptr = nd; nd->mousepollFunc = d->base.privates[mousePoolIndex].ptr; return TRUE; } static void VISOCORFiniDisplay(CompPlugin * p, CompDisplay * d) { VISOCOR_DISPLAY(d); freeScreenPrivateIndex(d, vd->screenPrivateIndex); free(vd); } static Bool VISOCORInitScreen(CompPlugin * p, CompScreen * s) { VISOCORScreen *vs; int i; VISOCOR_DISPLAY(s->display); vs = malloc(sizeof(VISOCORScreen)); if (!vs) return FALSE; vs->windowPrivateIndex = allocateWindowPrivateIndex(s); if (vs->windowPrivateIndex < 0) { free(vs); return FALSE; } visocorResetFilter(vs); for (i = 0; i < MAX_FRAGMENT_FUNCTIONS; i++) { vs->visocorFunctions[0][i] = 0; vs->visocorFunctions[1][i] = 0; } visocorSetVisocorMatchNotify(s, VISOCORScreenOptionChanged); visocorSetExcludeMatchNotify(s, VISOCORScreenOptionChanged); WRAP(vs, s, drawWindowTexture, VISOCORDrawWindowTexture); s->base.privates[vd->screenPrivateIndex].ptr = vs; vs->pollHandle = 0; visocorDamageAllWindows(s); return TRUE; } static void VISOCORFiniScreen(CompPlugin * p, CompScreen * s) { int i; VISOCOR_SCREEN(s); VISOCOR_DISPLAY(s); freeWindowPrivateIndex(s, vs->windowPrivateIndex); UNWRAP(vs, s, drawWindowTexture); for (i = 0; i < MAX_FRAGMENT_FUNCTIONS; i++) { if (vs->visocorFunctions[0][i]) { destroyFragmentFunction(s, vs->visocorFunctions[0][i]); } if (vs->visocorFunctions[1][i]) { destroyFragmentFunction(s, vs->visocorFunctions[1][i]); } } if (vs->pollHandle) (*vd->mousepollFunc->removePositionPolling)(s, vs->pollHandle); free(vs); } static Bool VISOCORInitWindow(CompPlugin * p, CompWindow * w) { VISOCORWindow *vw; VISOCOR_SCREEN(w->screen); vw = malloc(sizeof(VISOCORWindow)); if (!vw) return FALSE; vw->currentState = OFF; vw->lastState = OFF; w->base.privates[vs->windowPrivateIndex].ptr = vw; return TRUE; } static void VISOCORFiniWindow(CompPlugin * p, CompWindow * w) { VISOCOR_WINDOW(w); free(vw); } static Bool VISOCORInit(CompPlugin * p) { visocorCorePrivateIndex = allocateCorePrivateIndex(); if (visocorCorePrivateIndex < 0) return FALSE; return TRUE; } static void VISOCORFini(CompPlugin * p) { freeCorePrivateIndex(visocorCorePrivateIndex); } static CompBool VISOCORInitObject(CompPlugin * p, CompObject * o) { static InitPluginObjectProc dispTab[] = { (InitPluginObjectProc) VISOCORInitCore, (InitPluginObjectProc) VISOCORInitDisplay, (InitPluginObjectProc) VISOCORInitScreen, (InitPluginObjectProc) VISOCORInitWindow }; RETURN_DISPATCH(o, dispTab, ARRAY_SIZE(dispTab), TRUE, (p, o)) ;} static void VISOCORFiniObject(CompPlugin * p, CompObject * o) { static FiniPluginObjectProc dispTab[] = { (FiniPluginObjectProc) VISOCORFiniCore, (FiniPluginObjectProc) VISOCORFiniDisplay, (FiniPluginObjectProc) VISOCORFiniScreen, (FiniPluginObjectProc) VISOCORFiniWindow }; DISPATCH(o, dispTab, ARRAY_SIZE(dispTab), (p, o)); } CompPluginVTable VISOCORVTable = { "visocor", 0, VISOCORInit, VISOCORFini, VISOCORInitObject, VISOCORFiniObject, 0, 0, }; CompPluginVTable * getCompPluginInfo(void) { return &VISOCORVTable; }