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); }
/* * 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); } } }
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); } }
/* * 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; }