static void
colorFilterFiniWindow (CompPlugin * p, CompWindow * w)
{
    if (!w->screen->fragmentProgram)
	return;

    FILTER_WINDOW (w);
    free (cfw);
}
/*
 * Wrapper that enables filters if the window is filtered
 */
static void
colorFilterDrawWindowTexture (CompWindow *w, CompTexture *texture,
			      const FragmentAttrib *attrib, unsigned int mask)
{
    int i, function;

    FILTER_SCREEN (w->screen);
    FILTER_WINDOW (w);

    /* Check if filters have to be loaded and load them if so
     * Maybe should this check be done only if a filter is going to be applied
     * for this texture? */
    if (!cfs->filtersLoaded)
	loadFilters (w->screen, texture);    

    /* Filter texture if :
     *   o GL_ARB_fragment_program available
     *   o Filters are loaded
     *   o Texture's window is filtered */
    /* Note : if required, filter window contents only and not decorations
     * (use that w->texture->name != texture->name for decorations) */
    if (cfs->filtersCount && cfw->isFiltered &&
	(colorfilterGetFilterDecorations (w->screen) ||
	 (texture->name == w->texture->name)))
    {
	FragmentAttrib fa = *attrib;
	if (cfs->currentFilter == 0) /* Cumulative filters mode */
	{
	    /* Enable each filter one by one */
	    for (i = 0; i < cfs->filtersCount; i++)
	    {
		function = cfs->filtersFunctions[i];
		if (function)
		    addFragmentFunction (&fa, function);
	    }
	}
	/* Single filter mode */
	else if (cfs->currentFilter <= cfs->filtersCount)
	{
	    /* Enable the currently selected filter if possible (i.e. if it
	     * was successfully loaded) */
	    function = cfs->filtersFunctions[cfs->currentFilter - 1];
	    if (function)
		addFragmentFunction (&fa, function);
	}
	UNWRAP (cfs, w->screen, drawWindowTexture);
	(*w->screen->drawWindowTexture) (w, texture, &fa, mask);
	WRAP(cfs, w->screen, drawWindowTexture, colorFilterDrawWindowTexture);
    }
    else /* Not filtering */
    {
	UNWRAP (cfs, w->screen, drawWindowTexture);
	(*w->screen->drawWindowTexture) (w, texture, attrib, mask);
	WRAP(cfs, w->screen, drawWindowTexture, colorFilterDrawWindowTexture);
    }
}
/*
 * Toggle filtering for a specific window
 */
static void
colorFilterToggleWindow (CompWindow * w)
{
    FILTER_WINDOW (w);

    /* Toggle window filtering flag */
    cfw->isFiltered = !cfw->isFiltered;

    /* Check exclude list */
    if (matchEval (colorfilterGetExcludeMatch (w->screen), w))
	cfw->isFiltered = FALSE;

    /* Ensure window is going to be repainted */
    addWindowDamage (w);
}
Example #4
0
/*
 * Switch current filter
 */
static void
colorFilterSwitchFilter (CompScreen *s)
{
	int id;
	CompFunction *function;
	CompWindow *w;

	FILTER_SCREEN (s);

	/* % (count + 1) because of the cumulative filters mode */
	cfs->currentFilter++;
	if (cfs->currentFilter >= cfs->filtersCount + 1)
		cfs->currentFilter = 0;

	if (cfs->currentFilter == 0)
		compLogMessage ("colorfilter", CompLogLevelInfo,
		                "Cumulative filters mode");
	else
	{
		id = cfs->filtersFunctions[cfs->currentFilter - 1];

		if (id)
		{
			function = findFragmentFunction (s, id);
			compLogMessage ("colorfilter", CompLogLevelInfo,
			                "Single filter mode (using %s filter)",
			                function->name);
		}
		else
		{
			compLogMessage ("colorfilter", CompLogLevelInfo,
			                "Single filter mode (filter loading failure)");
		}
	}

	/* Damage currently filtered windows */
	for (w = s->windows; w; w = w->next)
	{
		FILTER_WINDOW (w);

		if (cfw->isFiltered)
			addWindowDamage (w);
	}
}
/*
 * Filtering match settings update callback
 */
static void
colorFilterMatchsChanged (CompScreen *s, CompOption *opt,
			  ColorfilterScreenOptions num)
{
    CompWindow *w;

    FILTER_SCREEN (s);

    /* Re-check every window against new match settings */
    for (w = s->windows; w; w = w->next)
    {
	FILTER_WINDOW (w);
	if (matchEval (colorfilterGetFilterMatch (s), w) &&
	    cfs->isFiltered && !cfw->isFiltered)
	{
	    colorFilterToggleWindow (w);
	}
    }
}
Example #6
0
static void
colorFilterChangeNotify (const char        *optionName,
                         BananaType        optionType,
                         const BananaValue *optionValue,
                         int               screenNum)
{
	FILTER_DISPLAY (&display);

	if (strcasecmp (optionName, "toggle_window_key") == 0)
		updateKey (optionValue->s, &cfd->toggle_window_key);

	else if (strcasecmp (optionName, "toggle_screen_key") == 0)
		updateKey (optionValue->s, &cfd->toggle_screen_key);

	else if (strcasecmp (optionName, "switch_filter_key") == 0)
		updateKey (optionValue->s, &cfd->switch_filter_key);

	else if (strcasecmp (optionName, "filter_match") == 0)
	{
		CompWindow *w;
		CompScreen *s = getScreenFromScreenNum (screenNum);

		FILTER_SCREEN (s);

		//Re-check every window against new match settings
		for (w = s->windows; w; w = w->next)
		{
			FILTER_WINDOW (w);

			if (matchEval (&cfs->filter_match, w) &&
			    cfs->isFiltered && !cfw->isFiltered)
			{
				colorFilterToggleWindow (w);
			}
		}
	}

	else if (strcasecmp (optionName, "exclude_match") == 0)
	{
		CompWindow *w;
		CompScreen *s = getScreenFromScreenNum (screenNum);

		FILTER_SCREEN (s);

		// Re-check every window against new match settings
		for (w = s->windows; w; w = w->next)
		{
			Bool isExcluded;

			FILTER_WINDOW (w);

			isExcluded = matchEval (&cfs->exclude_match, w);

			if (isExcluded && cfw->isFiltered)
				colorFilterToggleWindow (w);
			else if (!isExcluded && cfs->isFiltered && !cfw->isFiltered)
				colorFilterToggleWindow (w);
		}
	}

	else if (strcasecmp (optionName, "filters") == 0)
	{
		CompScreen *s = getScreenFromScreenNum (screenNum);

		FILTER_SCREEN (s);

		/* Just set the filtersLoaded boolean to FALSE, unloadFilters will be
		 * called in loadFilters */

		cfs->filtersLoaded = FALSE;
	}

	else if (strcasecmp (optionName, "filter_decorations") == 0)
	{
		CompScreen *s = getScreenFromScreenNum (screenNum);

		damageScreen (s);
	}
}
Example #7
0
/*
 * Load filters from a list of files for current screen
 */
static int
loadFilters (CompScreen  *s,
             CompTexture *texture)
{
	int i, target, loaded, function, count;
	char *name;
	CompWindow *w;

	FILTER_SCREEN (s);

	cfs->filtersLoaded = TRUE;

	/* Fetch filters filenames */
	const BananaValue *
	option_filters = bananaGetOption (bananaIndex,
	                                  "filters",
	                                  s->screenNum);

	count = option_filters->list.nItem;

	/* The texture target that will be used for some ops */
	if (texture->target == GL_TEXTURE_2D)
		target = COMP_FETCH_TARGET_2D;
	else
		target = COMP_FETCH_TARGET_RECT;

	/* Free previously loaded filters and malloc */
	unloadFilters (s);
	cfs->filtersFunctions = malloc (sizeof (int) * count);

	if (!cfs->filtersFunctions)
		return 0;

	cfs->filtersCount = count;

	/* Load each filter one by one */
	loaded = 0;

	for (i = 0; i < count; i++)
	{
		name = base_name (option_filters->list.item[i].s);
		if (!name || !strlen (name))
		{
			if (name)
				free (name);

			cfs->filtersFunctions[i] = 0;
			continue;
		}

		compLogMessage ("colorfilter", CompLogLevelInfo,
		                "Loading filter %s (item %s).", name,
		                option_filters->list.item[i].s);

		function = loadFragmentProgram (option_filters->list.item[i].s, name, s, target);
		free (name);

		cfs->filtersFunctions[i] = function;

		if (function)
			loaded++;
	}

	/* Warn if there was at least one loading failure */
	if (loaded < count)
		compLogMessage ("colorfilter", CompLogLevelWarn,
		                "Tried to load %d filter(s), %d succeeded.",
		                count, loaded);

	if (!loaded)
		cfs->filtersCount = 0;

	/* Damage currently filtered windows */
	for (w = s->windows; w; w = w->next)
	{
		FILTER_WINDOW (w);

		if (cfw->isFiltered)
			addWindowDamage (w);
	}

	return loaded;
}