Bool compSetOption(CompOption * option, CompOptionValue * value) { switch (option->type) { case CompOptionTypeBool: return compSetBoolOption(option, value); case CompOptionTypeInt: return compSetIntOption(option, value); case CompOptionTypeFloat: return compSetFloatOption(option, value); case CompOptionTypeString: return compSetStringOption(option, value); case CompOptionTypeColor: return compSetColorOption(option, value); case CompOptionTypeMatch: return compSetMatchOption(option, value); case CompOptionTypeAction: case CompOptionTypeKey: case CompOptionTypeButton: case CompOptionTypeEdge: case CompOptionTypeBell: return compSetActionOption(option, value); case CompOptionTypeList: return compSetOptionList(option, value); } return FALSE; }
static Bool minSetScreenOption(CompPlugin * plugin, CompScreen * screen, const char *name, CompOptionValue * value) { CompOption *o; int index; MIN_SCREEN(screen); o = compFindOption(ms->opt, NUM_OPTIONS(ms), name, &index); if (!o) return FALSE; switch (index) { case MIN_SCREEN_OPTION_SHADE_RESISTANCE: if (compSetIntOption(o, value)) { if (o->value.i) ms->shadeStep = o->rest.i.max - o->value.i + 1; else ms->shadeStep = 0; return TRUE; } break; default: if (compSetOption(o, value)) return TRUE; break; } return FALSE; }
static Bool scaleSetScreenOption (CompPlugin *plugin, CompScreen *screen, const char *name, CompOptionValue *value) { CompOption *o; int index; SCALE_SCREEN (screen); o = compFindOption (ss->opt, NUM_OPTIONS (ss), name, &index); if (!o) return FALSE; switch (index) { case SCALE_SCREEN_OPTION_OPACITY: if (compSetIntOption (o, value)) { ss->opacity = (OPAQUE * o->value.i) / 100; return TRUE; } break; default: return compSetScreenOption (screen, o, value); } return FALSE; }
static Bool notifySetDisplayOption (CompPlugin *p, CompDisplay *display, const char *name, CompOptionValue *value) { CompOption *o; int index; NOTIFY_DISPLAY (display); o = compFindOption (nd->opt, NUM_OPTIONS (nd), name, &index); if (!o) return FALSE; switch (index) { case NOTIFY_DISPLAY_OPTION_TIMEOUT: if (compSetIntOption (o, value)) { if (value->i == -1) nd->timeout = value->i; else nd->timeout = value->i * 1000; return TRUE; } default: if (compSetOption (o, value)) return TRUE; break; } return FALSE; }
static Bool setScreenOption (CompScreen *screen, char *name, CompOptionValue *value) { CompOption *o; int index; o = compFindOption (screen->opt, NUM_OPTIONS (screen), name, &index); if (!o) return FALSE; switch (index) { case COMP_SCREEN_OPTION_REFRESH_RATE: if (compSetIntOption (o, value)) { screen->redrawTime = 1000 / o->value.i; return TRUE; } default: break; } return FALSE; }
static Bool waterSetDisplayOption (CompPlugin *plugin, CompDisplay *display, const char *name, CompOptionValue *value) { CompOption *o; int index; WATER_DISPLAY (display); o = compFindOption (wd->opt, NUM_OPTIONS (wd), name, &index); if (!o) return FALSE; switch (index) { case WATER_DISPLAY_OPTION_OFFSET_SCALE: if (compSetFloatOption (o, value)) { wd->offsetScale = o->value.f * 50.0f; return TRUE; } break; case WATER_DISPLAY_OPTION_RAIN_DELAY: if (compSetIntOption (o, value)) { CompScreen *s; for (s = display->screens; s; s = s->next) { WATER_SCREEN (s); if (!ws->rainHandle) continue; compRemoveTimeout (ws->rainHandle); ws->rainHandle = compAddTimeout (value->i, (float)value->i * 1.2, waterRainTimeout, s); } return TRUE; } break; default: return compSetDisplayOption (display, o, value); } return FALSE; }
Bool compSetOptionList(CompOption * option, CompOptionValue * value) { CompOption o; Bool status = FALSE; int i, min; if (value->list.nValue != option->value.list.nValue) { CompOptionValue *v; v = malloc(sizeof(CompOptionValue) * value->list.nValue); if (!v) return FALSE; min = MIN(value->list.nValue, option->value.list.nValue); for (i = min; i < option->value.list.nValue; i++) { switch (option->value.list.type) { case CompOptionTypeString: if (option->value.list.value[i].s) free(option->value.list.value[i].s); break; case CompOptionTypeMatch: matchFini(&option->value.list.value[i].match); default: break; } } memset(v, 0, sizeof(CompOptionValue) * value->list.nValue); if (min) memcpy(v, option->value.list.value, sizeof(CompOptionValue) * min); if (option->value.list.value) free(option->value.list.value); option->value.list.value = v; option->value.list.nValue = value->list.nValue; status = TRUE; } o = *option; o.type = option->value.list.type; for (i = 0; i < value->list.nValue; i++) { o.value = option->value.list.value[i]; switch (o.type) { case CompOptionTypeBool: status |= compSetBoolOption(&o, &value->list.value[i]); break; case CompOptionTypeInt: status |= compSetIntOption(&o, &value->list.value[i]); break; case CompOptionTypeFloat: status |= compSetFloatOption(&o, &value->list.value[i]); break; case CompOptionTypeString: status |= compSetStringOption(&o, &value->list.value[i]); break; case CompOptionTypeColor: status |= compSetColorOption(&o, &value->list.value[i]); break; case CompOptionTypeMatch: status |= compSetMatchOption(&o, &value->list.value[i]); default: break; } option->value.list.value[i] = o.value; } return status; }
static void updateOptionSet(CompScreen *s, OptionSet *os, char *optNamesValuesOrig) { ANIM_SCREEN(s); int len = strlen(optNamesValuesOrig); char *optNamesValues = calloc(len + 1, 1); // Find the first substring with no spaces in it sscanf(optNamesValuesOrig, " %s ", optNamesValues); if (strlen(optNamesValues) == 0) { free(optNamesValues); return; } // Backup original, since strtok is destructive strcpy(optNamesValues, optNamesValuesOrig); char *name; char *nameTrimmed = calloc(len + 1, 1); char *valueStr = NULL; char *betweenPairs = ","; char *betweenOptVal = "="; // Count number of pairs char *pairToken = optNamesValuesOrig; int nPairs = 1; while ((pairToken = strchr(pairToken, betweenPairs[0]))) { pairToken++; // skip delimiter nPairs++; } if (os->pairs) free(os->pairs); os->pairs = calloc(nPairs, sizeof(IdValuePair)); if (!os->pairs) { os->nPairs = 0; free(optNamesValues); free(nameTrimmed); compLogMessage ("animation", CompLogLevelError, "Not enough memory"); return; } os->nPairs = nPairs; // Tokenize pairs name = strtok(optNamesValues, betweenOptVal); IdValuePair *pair = &os->pairs[0]; int errorNo = -1; int i; for (i = 0; name && i < nPairs; i++, pair++) { errorNo = 0; if (strchr(name, betweenPairs[0])) // handle "a, b=4" case { errorNo = 1; break; } sscanf(name, " %s ", nameTrimmed); if (strlen(nameTrimmed) == 0) { errorNo = 2; break; } valueStr = strtok(NULL, betweenPairs); if (!valueStr) { errorNo = 3; break; } // TODO: Fix: Convert to "pluginname:option_name" format // Warning: Assumes that option names in different extension plugins // will be different. Bool matched = FALSE; const ExtensionPluginInfo *extensionPluginInfo; CompOption *o; int optId; int k; for (k = 0; k < as->nExtensionPlugins; k++) { extensionPluginInfo = as->extensionPlugins[k]; unsigned int nOptions = extensionPluginInfo->nEffectOptions; o = extensionPluginInfo->effectOptions; for (optId = 0; optId < nOptions; optId++, o++) { if (strcasecmp(nameTrimmed, o->name) == 0) { matched = TRUE; break; } } if (matched) break; } if (!matched) { errorNo = 4; break; } CompOptionValue v; pair->pluginInfo = extensionPluginInfo; pair->optionId = optId; int valueRead = -1; switch (o->type) { case CompOptionTypeBool: valueRead = sscanf(valueStr, " %d ", &pair->value.b); break; case CompOptionTypeInt: valueRead = sscanf(valueStr, " %d ", &v.i); if (valueRead > 0) { // Store option's original value int backup = o->value.i; if (compSetIntOption (o, &v)) pair->value = v; else errorNo = 7; // Restore value o->value.i = backup; } break; case CompOptionTypeFloat: valueRead = sscanf(valueStr, " %f ", &v.f); if (valueRead > 0) { // Store option's original value float backup = o->value.f; if (compSetFloatOption (o, &v)) pair->value = v; else errorNo = 7; // Restore value o->value.f = backup; } break; case CompOptionTypeString: v.s = calloc (strlen(valueStr) + 1, 1); // TODO: not freed if (!v.s) { compLogMessage ("animation", CompLogLevelError, "Not enough memory"); return; } strcpy(v.s, valueStr); valueRead = 1; break; case CompOptionTypeColor: { unsigned int c[4]; valueRead = sscanf (valueStr, " #%2x%2x%2x%2x ", &c[0], &c[1], &c[2], &c[3]); if (valueRead == 4) { CompOptionValue * pv = &pair->value; int j; for (j = 0; j < 4; j++) pv->c[j] = c[j] << 8 | c[j]; } else errorNo = 6; break; } default: break; } if (valueRead == 0) errorNo = 6; if (errorNo > 0) break; // If valueRead is -1 here, then it must be a // non-(int/float/string) option, which is not supported yet. // Such an option doesn't currently exist anyway. errorNo = -1; name = strtok(NULL, betweenOptVal); } if (i < nPairs) { switch (errorNo) { case -1: case 2: compLogMessage ("animation", CompLogLevelError, "Option name missing in \"%s\"", optNamesValuesOrig); break; case 1: case 3: compLogMessage ("animation", CompLogLevelError, "Option value missing in \"%s\"", optNamesValuesOrig); break; case 4: compLogMessage ("animation", CompLogLevelError, "Unknown option \"%s\" in \"%s\"", nameTrimmed, optNamesValuesOrig); break; case 6: compLogMessage ("animation", CompLogLevelError, "Invalid value \"%s\" in \"%s\"", valueStr, optNamesValuesOrig); break; case 7: compLogMessage ("animation", CompLogLevelError, "Value \"%s\" out of range in \"%s\"", valueStr, optNamesValuesOrig); break; default: break; } free(os->pairs); os->pairs = 0; os->nPairs = 0; } free(optNamesValues); free(nameTrimmed); }