Visocor: Color Blind Compiz Plugin Code
Status: Beta
Brought to you by:
rafaelolg
--- a +++ b/filter.c @@ -0,0 +1,165 @@ + +/*----------------------------------------------------------------------------*\ + | 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 3 | + | 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 <stdio.h> +#include <stdlib.h> +#include "visocor.h" + +static const int LAST_FILTER = N_FILTER_VARIATIONS - 1; +static const int FIRST_FILTER = 0; +static const int FILTER_STEP = 1; + +static void recalculateColorFilter(CompScreen * s) { + VISOCOR_SCREEN(s); + int middle; + + middle = (LAST_FILTER + FIRST_FILTER) / 2; + if (vs->filterIntensity > middle) { + vs->ir = ((float) vs->filterIntensity - middle) + / (LAST_FILTER - middle); + vs->ig = 0; + } else { + vs->ig = ((float) middle - vs->filterIntensity) / (middle + - FIRST_FILTER); + vs->ir = 0; + } + vs->ib = 1.0 - vs->ig - vs->ir; + visocorPrintf(CompLogLevelDebug, "ir = %f\tig = %f\tib = %f", vs->ir, + vs->ig, vs->ib); +} + +void visocorResetFilter(VISOCORScreen * vs) { + int middle; + + middle = (LAST_FILTER + FIRST_FILTER) / 2; + vs->filterIntensity = middle; + vs->ig = 0; + vs->ir = 0; + vs->ib = 1; +} + +Bool visocorToggleFilter(CompDisplay * d, CompAction * action, + CompActionState state, CompOption * option, int nOption) { + CompWindow *w; + + w = visocorFindWindow(d, option, nOption); + + if (w) { + VISOCOR_WINDOW(w); + if (vw->currentState != FILTER) { + visocorToggleWindowToState(w, FILTER); + } else { + visocorToggleWindowToState(w, vw->lastState); + } + } + + return TRUE; +} + +Bool visocorDecreaseFilter(CompDisplay * d, CompAction * action, + CompActionState state, CompOption * option, int nOption) { + + int value; + + CompScreen *s; + + s = visocorFindScreen(d, option, nOption); + + if (s) { + VISOCOR_SCREEN(s); + value = MAX(FIRST_FILTER, vs->filterIntensity - FILTER_STEP); + vs->filterIntensity = value; + recalculateColorFilter(s); + + visocorDamageAllWindows(s); + + return TRUE; + + } + return FALSE; + +} + +Bool visocorIncreaseFilter(CompDisplay * d, CompAction * action, + CompActionState state, CompOption * option, int nOption) { + + CompScreen *s; + + int value; + + s = visocorFindScreen(d, option, nOption); + if (s) { + VISOCOR_SCREEN(s); + value = MIN(LAST_FILTER, vs->filterIntensity + FILTER_STEP); + vs->filterIntensity = value; + recalculateColorFilter(s); + + visocorDamageAllWindows(s); + return TRUE; + + } + return FALSE; +} + +int getVisocorFilterFragmentFunction(CompScreen * s, CompTexture * texture, + int param) { + VISOCOR_SCREEN(s); + + if (vs->visocorFunctions[FILTER][param] == 0) { + CompFunctionData *data; + int target; + char filter_operation[1024]; + Bool ok = TRUE; + + visocorPrintf(CompLogLevelDebug, "criando um FILTER com a variavel %d", + param); + if (texture->target == GL_TEXTURE_2D) + target = COMP_FETCH_TARGET_2D; + else + target = COMP_FETCH_TARGET_RECT; + + data = createFunctionData(); + if (data) { + + ok &= addTempHeaderOpToFunctionData(data, "tex"); + ok &= addTempHeaderOpToFunctionData(data, "temp"); + ok &= addFetchOpToFunctionData(data, "tex", NULL, target); + char * format = "DP3 temp.r, tex, {1 , 0 , 0 , 0};\n" + "DP3 temp.g, tex, {0 , 1 , 0 , 0};\n" + "DP3 temp.b, tex, program.env[%d].xyzw;\n" + "MOV temp.a, tex.a;"; + sprintf(filter_operation, format, param); + } + ok &= addDataOpToFunctionData(data, filter_operation); + ok &= addColorOpToFunctionData(data, "output", "temp"); + if (!ok) { + destroyFunctionData(data); + return 0; + } + + vs->visocorFunctions[FILTER][param] = createFragmentFunction(s, + "visocor", data); + ; + } + + (*s->programEnvParameter4f)(GL_FRAGMENT_PROGRAM_ARB, param, vs->ir, vs->ig, + vs->ib, 1.0f); + + return vs->visocorFunctions[FILTER][param]; + +}