[go: up one dir, main page]

Menu

Diff of /visocor.c [000000] .. [r1]  Maximize  Restore

Switch to side-by-side view

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