--- 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];
+
+}