TEST (CompOption, AssignDefaultActionValueToUnsetTypeClearsOldStateKeepsInfo) { /* Value is unset at this point */ CompOption option ("testing", CompOption::TypeKey); CompAction action; /* We need to set up the state here as * the CompOption::Value constructor makes * a copy of the action */ action.setState (CompAction::StateInitKey); action.setButton (CompAction::ButtonBinding (1, 1 << 1)); CompOption::Value value (action); ASSERT_EQ (value.action ().state (), CompAction::StateInitKey); /* Actually set the action value, this will * overwrite the internal value */ option.set (value); /* We don't care about the old action's state, so get * rid of it */ ASSERT_EQ (option.value ().action ().state (), 0); /* We do want to keep the non-stateful data which is * pure info */ ASSERT_EQ (option.value ().action ().button ().button (), 1); ASSERT_EQ (option.value ().action ().button ().modifiers (), 1 << 1); }
bool PrivateCubeScreen::setOption (const CompString &name, CompOption::Value &value) { unsigned int index; bool rv = CubeOptions::setOption (name, value); if (!rv || !CompOption::findOption (getOptions (), name, &index)) return false; switch (index) { case CubeOptions::In: rv = updateGeometry (screen->vpSize ().width (), value.b () ? -1 : 1); break; case CubeOptions::Skydome: case CubeOptions::SkydomeImage: case CubeOptions::SkydomeAnimated: case CubeOptions::SkydomeGradientStartColor: case CubeOptions::SkydomeGradientEndColor: updateSkydomeTexture (); updateSkydomeList (1.0f); cScreen->damageScreen (); break; case CubeOptions::MultioutputMode: updateOutputs (); updateGeometry (screen->vpSize ().width (), mInvert); cScreen->damageScreen (); break; default: break; } return rv; }
TEST(CompOption,Value) { check_type_value<bool> (CompOption::TypeBool, true); check_type_value<bool> (CompOption::TypeBool, false); check_type_value<int> (CompOption::TypeInt, 1); check_type_value<float> (CompOption::TypeFloat, 1.f); check_type_value<CompString> (CompOption::TypeString, CompString ("Check")); check_type_value<CompString> (CompOption::TypeString, "core"); check_type_value<CompAction> (CompOption::TypeAction, CompAction()); check_type_value<CompMatch> (CompOption::TypeMatch, CompMatch()); check_type_value<unsigned short[4]> (CompOption::TypeColor, testColor); check_type_value<CompOption::Value::Vector> (CompOption::TypeList, CompOption::Value::Vector(5)); CompOption::Value v1, v2; ASSERT_EQ (v1,v2); v1.set (CompString("SomeString")); ASSERT_TRUE(v1 != v2); CompOption::Value::Vector vec; CompOption::Value v; v.set (true); vec.push_back (v); vec.push_back (v); check_list_type<bool> (CompOption::TypeBool, vec); vec.clear (); v.set (CompString ("foo")); vec.push_back (v); vec.push_back (v); check_list_type<CompString> (CompOption::TypeString, vec); }
static void finiOptionValue (CompOption::Value &v, CompOption::Type type) { switch (type) { case CompOption::TypeAction: case CompOption::TypeKey: case CompOption::TypeButton: case CompOption::TypeEdge: case CompOption::TypeBell: if (v.action ().state () & CompAction::StateAutoGrab && screen) screen->removeAction (&v.action ()); break; case CompOption::TypeList: foreach (CompOption::Value &val, v.list ()) finiOptionValue (val, v.listType ()); break; default: break; } }
bool CompOption::set (CompOption::Value &val) { if (isAction () && priv->type != CompOption::TypeAction) val.action ().copyState (priv->value.action ()); if (priv->type != val.type () && (!isAction () || !checkIsAction (val.type ()))) { compLogMessage ("core", CompLogLevelWarn, "Can't set Value with type %d to " "option \"%s\" with type %d", val.type (), priv->name.c_str (), priv->type); return false; } if (priv->value == val) return false; if (isAction () && priv->value.action ().state () & CompAction::StateAutoGrab && screen) { if (!screen->addAction (&val.action ())) return false; else screen->removeAction (&priv->value.action ()); } switch (priv->type) { case CompOption::TypeInt: if (!priv->rest.inRange (val.i ())) return false; break; case CompOption::TypeFloat: { float v, p; int sign = (val.f () < 0 ? -1 : 1); if (!priv->rest.inRange (val.f ())) return false; p = 1.0f / priv->rest.fPrecision (); v = ((int) (val.f () * p + sign * 0.5f)) / p; priv->value.set (v); return true; } case CompOption::TypeAction: return false; case CompOption::TypeKey: if (val.action ().type () == value().action ().type () && !(val.action ().type () & CompAction::BindingTypeKey)) return false; break; case CompOption::TypeButton: if (val.action ().type () == value().action ().type () && !(val.action ().type () & (CompAction::BindingTypeButton | CompAction::BindingTypeEdgeButton))) return false; break; default: break; } priv->value = val; return true; }
void PrivateAnimScreen::updateOptionSet (OptionSet *os, const char *optNamesValuesOrig) { unsigned int len = strlen (optNamesValuesOrig); char *optNamesValues = (char *)calloc (len + 1, 1); // Find the first substring with no spaces in it sscanf (optNamesValuesOrig, " %s ", optNamesValues); if (!strlen (optNamesValues)) { free (optNamesValues); return; } // Backup original, since strtok is destructive strcpy (optNamesValues, optNamesValuesOrig); char *nameTrimmed = (char *)calloc (len + 1, 1); char *valueStr = 0; const char *betweenPairs = ","; const char *betweenOptVal = "="; // Count number of pairs char *pairToken = (char *)optNamesValuesOrig; // TODO do with CompString unsigned int nPairs = 1; while ((pairToken = strchr (pairToken, betweenPairs[0]))) { ++pairToken; // skip delimiter ++nPairs; } os->pairs.clear (); os->pairs.reserve (nPairs); // Tokenize pairs char *name = strtok (optNamesValues, betweenOptVal); int errorNo = -1; unsigned int i; for (i = 0; name && i < nPairs; ++i) { errorNo = 0; if (strchr (name, betweenPairs[0])) // handle "a, b=4" case { errorNo = 1; break; } sscanf (name, " %s ", nameTrimmed); if (!strlen (nameTrimmed)) { errorNo = 2; break; } valueStr = strtok (0, 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 *chosenExtensionPlugin = NULL; CompOption *o = 0; int optId = -1; unsigned int nOptions; foreach (ExtensionPluginInfo *extensionPlugin, mExtensionPlugins) { nOptions = extensionPlugin->effectOptions->size (); for (optId = (int)extensionPlugin->firstEffectOptionIndex; optId < (int)nOptions; ++optId) { o = &(*extensionPlugin->effectOptions)[(unsigned)optId]; if (strcasecmp (nameTrimmed, o->name ().c_str ()) == 0) { matched = true; chosenExtensionPlugin = extensionPlugin; break; } } if (matched) break; } if (!matched) { errorNo = 4; break; } CompOption::Value v; os->pairs.push_back (IdValuePair ()); IdValuePair *pair = &os->pairs[i]; pair->pluginInfo = chosenExtensionPlugin; pair->optionId = optId; int valueRead = -1; switch (o->type ()) { case CompOption::TypeBool: int vb; valueRead = sscanf (valueStr, " %d ", &vb); if (valueRead) pair->value.set ((bool)vb); break; case CompOption::TypeInt: { int vi; valueRead = sscanf (valueStr, " %d ", &vi); if (valueRead > 0) { if (o->rest ().inRange (vi)) { v.set (vi); pair->value = v; } else errorNo = 7; } break; } case CompOption::TypeFloat: { float vf; valueRead = sscanf (valueStr, " %f ", &vf); if (valueRead > 0) { if (o->rest ().inRange (vf)) { v.set (vf); pair->value = v; } else errorNo = 7; } break; } case CompOption::TypeString: { v.set (CompString (valueStr)); valueRead = 1; break; } case CompOption::TypeColor: { unsigned short vc[4]; valueRead = sscanf (valueStr, " #%2hx%2hx%2hx%2hx ", &vc[0], &vc[1], &vc[2], &vc[3]); if (valueRead == 4) { CompOption::Value *pairVal = &pair->value; for (int j = 0; j < 4; ++j) vc[j] = vc[j] << 8 | vc[j]; pairVal->set (vc); } 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 (0, betweenOptVal); }
TEST(CompOption,Color) { CompOption::Value value(testColor); unsigned short * color = value.c(); ASSERT_NE((void*)0, color); for (int i = 0; i != 4; ++i) ASSERT_EQ(testColor[i], color[i]); color = value.get<unsigned short*>(); ASSERT_NE((void*)0, color); for (int i = 0; i != 4; ++i) ASSERT_EQ(testColor[i], color[i]); value.set(testColor2); color = value.c(); ASSERT_NE((void*)0, color); for (int i = 0; i != 4; ++i) ASSERT_EQ(testColor2[i], color[i]); color = value.get<unsigned short*>(); ASSERT_NE((void*)0, color); for (int i = 0; i != 4; ++i) ASSERT_EQ(testColor2[i], color[i]); CompOption::Value v; v.set (testColor); color = v.c(); ASSERT_NE((void*)0, color); for (int i = 0; i != 4; ++i) ASSERT_EQ(testColor[i], color[i]); color = v.get<unsigned short*>(); ASSERT_NE((void*)0, color); for (int i = 0; i != 4; ++i) ASSERT_EQ(testColor[i], color[i]); v.set(testColor2); color = v.c(); ASSERT_NE((void*)0, color); for (int i = 0; i != 4; ++i) ASSERT_EQ(testColor2[i], color[i]); color = v.get<unsigned short*>(); ASSERT_NE((void*)0, color); for (int i = 0; i != 4; ++i) ASSERT_EQ(testColor2[i], color[i]); v.set (static_cast <short unsigned int *> (testColor)); color = v.c(); ASSERT_NE((void*)0, color); for (int i = 0; i != 4; ++i) ASSERT_EQ(testColor[i], color[i]); color = v.get<unsigned short*>(); ASSERT_NE((void*)0, color); for (int i = 0; i != 4; ++i) ASSERT_EQ(testColor[i], color[i]); v.set(testColor2); color = v.c(); ASSERT_NE((void*)0, color); for (int i = 0; i != 4; ++i) ASSERT_EQ(testColor2[i], color[i]); color = v.get<unsigned short*>(); ASSERT_NE((void*)0, color); for (int i = 0; i != 4; ++i) ASSERT_EQ(testColor2[i], color[i]); }