Visocor: Color Blind Compiz Plugin Code
Status: Beta
Brought to you by:
rafaelolg
--- a +++ b/visocor.c @@ -0,0 +1,396 @@ + +/*----------------------------------------------------------------------------*\ + | 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 <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <stdarg.h> + +#include <compiz-core.h> +#include <compiz-mousepoll.h> +#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; +}