CCSSettingValueList
readIntListValue (GVariantIter *iter, guint nItems, CCSSetting *setting, CCSObjectAllocationInterface *ai)
{
    CCSSettingValueList list = NULL;
    int *array = (*ai->calloc_) (ai->allocator, 1, nItems * sizeof (int));
    int *arrayCounter = array;
    gint value;

    if (!array)
	return NULL;

    /* Reads each item from the variant into arrayCounter */
    while (g_variant_iter_loop (iter, "i", &value))
	*arrayCounter++ = value;

    list = ccsGetValueListFromIntArray (array, nItems, setting);
    free (array);

    return list;
}
Bool
ccsIniGetList (IniDictionary       *dictionary,
   	       const char          *section,
	       const char          *entry,
	       CCSSettingValueList *value,
	       CCSSetting          *parent)
{
    CCSSettingValueList list = NULL;
    char                *valueString, *valueStart, *valString;
    char                *token;
    int                 nItems = 1, i = 0, len;

    valString = getIniString (dictionary, section, entry);
    if (!valString)
	return FALSE;

    if (isEmptyString (valString))
    {
	*value = NULL;
	return TRUE;
    }

    valueString = strdup (valString);
    valueStart = valueString;

    /* remove trailing semicolon that we added to be able to differentiate
       between an empty list and a list with one empty item */
    len = strlen (valueString);
    if (valueString[len - 1] == ';')
	valueString[len - 1] = 0;

    token = strchr (valueString, ';');
    while (token)
    {
	token = strchr (token + 1, ';');
	nItems++;
    }

    token = strsep (&valueString, ";");
    switch (parent->info.forList.listType)
    {
    case TypeString:
    case TypeMatch:
	{
	    char **array = malloc (nItems * sizeof (char*));
	    if (!array)
		break;

	    while (token)
	    {
		array[i++] = strdup (token);
		token = strsep (&valueString, ";");
	    }

	    list = ccsGetValueListFromStringArray (array, nItems, parent);

	    for (i = 0; i < nItems; i++)
		free (array[i]);

	    free (array);
	}
	break;
    case TypeColor:
	{
	    CCSSettingColorValue *array;
	    array = malloc (nItems * sizeof (CCSSettingColorValue));
	    if (!array)
		break;

	    while (token)
	    {
		memset (&array[i], 0, sizeof (CCSSettingColorValue));
		ccsStringToColor (token, &array[i]);
		token = strsep (&valueString, ";");
		i++;
	    }

	    list = ccsGetValueListFromColorArray (array, nItems, parent);
	    free (array);
	}
	break;
    case TypeBool:
	{
	    Bool *array = malloc (nItems * sizeof (Bool));
	    Bool isTrue;
	    if (!array)
		break;

	    while (token)
	    {
		isTrue = (token[0] == 'y' || token[0] == 'Y' || 
			  token[0] == '1' ||
			  token[0] == 't' || token[0] == 'T');
		array[i++] = isTrue;
		token = strsep (&valueString, ";");
	    }

	    list = ccsGetValueListFromBoolArray (array, nItems, parent);
	    free (array);
	}
	break;
    case TypeInt:
	{
	    int *array = malloc (nItems * sizeof (int));
	    if (!array)
		break;

	    while (token)
	    {
		array[i++] = strtoul (token, NULL, 10);
		token = strsep (&valueString, ";");
	    }

	    list = ccsGetValueListFromIntArray (array, nItems, parent);
	    free (array);
	}
	break;
    case TypeFloat:
	{
	    float *array = malloc (nItems * sizeof (float));
	    if (!array)
		break;

	    while (token)
	    {
		array[i++] = strtod (token, NULL);
		token = strsep (&valueString, ";");
	    }

	    list = ccsGetValueListFromFloatArray (array, nItems, parent);
	    free (array);
	}
	break;
    case TypeKey:
	{
	    CCSSettingValue *val = NULL;
	    list = NULL;

	    while (token)
	    {
		val = malloc (sizeof (CCSSettingValue));
		if (!val)
		    break;
		if (ccsStringToKeyBinding (token, &val->value.asKey))
		    list = ccsSettingValueListAppend (list, val);
		else
		    free (val);
		token = strsep (&valueString, ";");
	    }
	}
	break;
    case TypeButton:
	{
	    CCSSettingValue *val = NULL;
	    list = NULL;

	    while (token)
	    {
		val = malloc (sizeof (CCSSettingValue));
		if (!val)
		    break;
		if (ccsStringToButtonBinding (token, &val->value.asButton))
		    list = ccsSettingValueListAppend (list, val);
		else
		    free (val);
		token = strsep (&valueString, ";");
	    }
	}
	break;
    case TypeEdge:
	{
	    CCSSettingValue *val = NULL;
	    list = NULL;

	    while (token)
	    {
		val = malloc (sizeof (CCSSettingValue));
		if (!val)
		    break;
		val->value.asEdge = ccsStringToEdges (token);
		list = ccsSettingValueListAppend (list, val);
		token = strsep (&valueString, ";");
	    }
	}
	break;
    case TypeBell:
	{
	    CCSSettingValue *val = NULL;
	    list = NULL;
	    Bool isTrue;

	    while (token)
	    {
		val = malloc (sizeof (CCSSettingValue));
		if (!val)
		    break;

		isTrue = (token[0] == 'y' || token[0] == 'Y' || 
			  token[0] == '1' ||
			  token[0] == 't' || token[0] == 'T');
		
		val->value.asBell = isTrue;
		list = ccsSettingValueListAppend (list, val);
		token = strsep (&valueString, ";");
	    }
	}
	break;
    default:
	break;
    }

    *value = list;
    free (valueStart);

    return TRUE;
}
static void
readSetting (CCSContext *c,
	     CCSSetting *setting)
{
    QString key (setting->name);
    QString group (setting->parent->name);

    group += "_display";

    KConfigGroup cfg = cFiles->main->group (group);

    if (ccsGetIntegrationEnabled (c) && isIntegratedOption (setting) )
    {
	readIntegratedOption (setting, &cfg);
	return;
    }

    if (!cfg.hasKey (key) )
    {
	ccsResetToDefault (setting);
	return;
    }

    switch (setting->type)
    {

    case TypeString:
	ccsSetString (setting, cfg.readEntry (key, "").toAscii ().constData ());
	break;

    case TypeMatch:
	ccsSetMatch (setting, cfg.readEntry (key, "").toAscii ().constData ());
	break;

    case TypeFloat:
	ccsSetFloat (setting, cfg.readEntry (key, double(0.0)));
	break;

    case TypeInt:
	ccsSetInt (setting, cfg.readEntry (key, int(0)));
	break;

    case TypeBool:
	{
	    Bool val = (cfg.readEntry (key, false)) ? TRUE : FALSE;
	    ccsSetBool (setting, val);
	}
	break;

    case TypeColor:
	{
	    CCSSettingColorValue color;
	    QString value = cfg.readEntry (key, "");

	    if (ccsStringToColor (value.toAscii ().constData (), &color))
		ccsSetColor (setting, color);
	}
	break;

    case TypeList:
	{
	    switch (setting->info.forList.listType)
	    {

	    case TypeBool:
		{
		    QList<bool> list = cfg.readEntry (key, QList<bool> ());

		    Bool *array = new Bool[list.count ()];
		    int i = 0;

		    foreach (Bool val, list)
		    {
			array[i] = (val) ? TRUE : FALSE;
			i++;
		    }

		    CCSSettingValueList l =
			ccsGetValueListFromBoolArray (array, i, setting);
		    ccsSetList (setting, l);
		    ccsSettingValueListFree (l, TRUE);
		    delete array;
		}
		break;

	    case TypeInt:
		{
		    QList<int> list = cfg.readEntry (key, QList<int> ());

		    int *array = new int[list.count ()];
		    int i = 0;

		    foreach (int val, list)
		    {
			array[i] = val;
			i++;
		    }

		    CCSSettingValueList l =
			ccsGetValueListFromIntArray (array, i, setting);
		    ccsSetList (setting, l);
		    ccsSettingValueListFree (l, TRUE);
		    delete array;
		}
		break;

	    case TypeString:
		{
		    QStringList list = cfg.readEntry (key, QStringList ());

		    if (!list.count ())
			break;

		    char **array = new char *[list.count ()];

		    int i = 0;

		    foreach (QString val, list)
		    {
			array[i] = strdup (val.toAscii ().constData ());
			i++;
		    }

		    CCSSettingValueList l =
			ccsGetValueListFromStringArray (array, i, setting);
		    ccsSetList (setting, l);
		    ccsSettingValueListFree (l, TRUE);

		    for (int j = 0; j < i; j++)
			free (array[j]);

		    delete [] array;

		}
		break;

	    case TypeMatch:
		{
		    QStringList list = cfg.readEntry (key, QStringList ());

		    if (!list.count ())
			break;

		    char **array = new char *[list.count ()];

		    int i = 0;

		    foreach (QString val, list)
		    {
			array[i] = strdup (val.toAscii ().constData ());
			i++;
		    }

		    CCSSettingValueList l =
			ccsGetValueListFromStringArray (array, i, setting);
		    ccsSetList (setting, l);
		    ccsSettingValueListFree (l, TRUE);

		    for (int j = 0; j < i; j++)
			free (array[j]);

		    delete [] array;

		}
static void
readIntegratedOption (CCSSetting   *setting,
		      KConfigGroup *mcg)
{
    int option = 0;
    KConfigGroup g;

    for (unsigned int i = 0; i < N_SOPTIONS; i++)
    {
	if (setting->name == specialOptions[i].settingName &&
	    QString (setting->parent->name) == specialOptions[i].pluginName)
	{
	    option = i;
	    break;
	}
    }

    switch (specialOptions[option].type)
    {

    case OptionInt:
	KdeIntToCCS (setting, option);
	break;

    case OptionBool:
	KdeBoolToCCS (setting, option);
	break;

    case OptionKey:
	KdeKeyToCCS (setting, option);
	break;

    case OptionSpecial:
	if (specialOptions[option].settingName == "command11")
	{
	    ccsSetString (setting, "xkill");
	}
	else if (specialOptions[option].settingName == "unmaximize_window_key"
		 || specialOptions[option].settingName == "maximize_window_key"
		 || specialOptions[option].settingName == "maximize_window_horizontally_key"
		 || specialOptions[option].settingName == "maximize_window_vertically_key")
	{
	    CCSSettingKeyValue keyVal;

	    if (!ccsGetKey (setting, &keyVal) )
		break;

	    keyVal.keysym = 0;

	    keyVal.keyModMask = 0;

	    ccsSetKey (setting, keyVal);
	}
	else if (specialOptions[option].settingName == "click_to_focus")
	{
	    Bool val = (cFiles->kwin->group ("Windows").
		        readEntry ("FocusPolicy") == "ClickToFocus") ?
		        TRUE : FALSE;
	    ccsSetBool (setting, val);
	}
	else if (specialOptions[option].settingName == "mode" &&
		 specialOptions[option].pluginName == "resize")
	{
	    QString mode = cFiles->kwin->group ("Windows").
			   readEntry ("ResizeMode");
	    int     imode = -1;
	    int     result = 0;

	    if (mcg->hasKey (specialOptions[option].settingName +
			     " (Integrated)"))
		imode = mcg->readEntry (specialOptions[option].settingName + 
				        " (Integrated)", int (0));

	    if (mode == "Opaque")
	    {
		result = 0;

		if (imode == 3)
		    result = 3;
	    }
	    else if (mode == "Transparent")
	    {
		result = 1;

		if (imode == 2)
		    result = 2;
	    }

	    ccsSetInt (setting, result);
	}
	else if (specialOptions[option].settingName == "snap_type")
	{
	    static int intList[2] = {0, 1};
	    CCSSettingValueList list = ccsGetValueListFromIntArray (intList, 2,
								    setting);
	    ccsSetList (setting, list);
	    ccsSettingValueListFree (list, TRUE);
	}
	else if (specialOptions[option].settingName == "resistance_distance" ||
		 specialOptions[option].settingName == "attraction_distance")
	{
	    int val1 = 
		cFiles->kwin->group ("Windows").
		    readEntry ("WindowSnapZone", int (0));
	    int val2 = 
		cFiles->kwin->group ("Windows").
		    readEntry ("BorderSnapZone", int (0));
	    int result = qMax (val1, val2);

	    if (result == 0)
		result = mcg->readEntry ("snap_distance (Integrated)", int (0));

	    if (result > 0)
	    	ccsSetInt (setting, result);
	}
	else if (specialOptions[option].settingName == "edges_categories")
	{
	    int val1 = 
		cFiles->kwin->group ("Windows").
		    readEntry ("WindowSnapZone", int (0));
	    int val2 = 
		cFiles->kwin->group ("Windows").
		    readEntry ("BorderSnapZone", int (0));
	    int intList[2] = {0, 0};
	    int num = 0;

	    if (val2 > 0)
		num++;
	    if (val1 > 0)
	    {
		intList[num] = 1;
		num++;
	    }

	    CCSSettingValueList list = ccsGetValueListFromIntArray (intList,
								    num,
								    setting);
	    ccsSetList (setting, list);
	    ccsSettingValueListFree (list, TRUE);
	}
	else if (specialOptions[option].settingName == "edge_flip_window" ||
		 specialOptions[option].settingName == "edgeflip_move")
	{
	    int val = 
		cFiles->kwin->group ("Windows").
		    readEntry ("ElectricBorders", int (0));

	    if (val > 0)
		ccsSetBool (setting, TRUE);
	    else
		ccsSetBool (setting, FALSE);
	}
	else if (specialOptions[option].settingName == "edge_flip_pointer" ||
		 specialOptions[option].settingName == "edgeflip_pointer")
	{
	    int val = 
		cFiles->kwin->group ("Windows").
		    readEntry ("ElectricBorders", int (0));

	    if (val > 1)
		ccsSetBool (setting, TRUE);
	    else
		ccsSetBool (setting, FALSE);
	}
	else if (specialOptions[option].settingName == "mode" &&
		 specialOptions[option].pluginName == "place")
	{
	    QString mode = cFiles->kwin->group ("Windows").
			   readEntry ("Placement");
	    int     result = 0;

	    if (mode == "Smart")
		result = 2;
	    else if (mode == "Maximizing")
		result = 3;
	    else if (mode == "Cascade")
		result = 0;
	    else if (mode == "Random")
		result = 4;
	    else if (mode == "Centered")
		result = 1;

	    ccsSetInt (setting, result);
	}
	break;

    default:
	break;
    }
}