rendered paste body//LIBBERYLSETTINGS
//SO VERSION 0
//see spec in header
#include <beryl-settings.h>
#include <string.h>
#include <malloc.h>
#include <libintl.h>
#include <dlfcn.h>
#include <beryl.h>
CompDisplay *display = NULL;
#define USE_GCONF
#ifdef USE_GCONF
#include <gconf/gconf.h>
#include <gconf/gconf-client.h>
#include <gconf/gconf-value.h>
static GConfClient * client = NULL;
GConfValueType beryl_to_gconf_type(BerylSettingType bst);
#endif
#define NEW(a,b) \
a * b = malloc(sizeof(a)); memset((b),0,sizeof(a))
// some function prototypes
static void set_array_from_binding(gint * array, BerylSettingValue * value);
static void set_array_from_color(BerylSettingValue * value, gint * array);
static GSList *set_gslist_from_color(GSList *list, BerylSettingValue *value);
static GSList *set_gslist_from_binding(GSList * list, BerylSettingValue * value);
//STATIC FUNCTIONS
static void copy_value(BerylSettingValue * dest, BerylSettingValue * src)
{
BerylSettingType type;
if (src->is_list_child)
type=src->parent->info.for_list.list_of_type;
else
type=src->parent->type;
dest->parent=src->parent;
dest->is_list_child=src->is_list_child;
if (type != BERYL_SETTING_TYPE_LIST)
{
if (type != BERYL_SETTING_TYPE_STRING)
memcpy(&dest->value,&src->value,sizeof(BerylSettingValueUnion));
else
dest->value.as_string=g_strdup(src->value.as_string);
}
else
{
GSList * newsrc;
dest->value.as_list=NULL;
for (newsrc=src->value.as_list;newsrc;newsrc=newsrc->next)
{
NEW(BerylSettingValue,newdest);
copy_value(newdest,newsrc->data);
dest->value.as_list=g_slist_append(dest->value.as_list,newdest);
}
}
}
static void copy_from_default(BerylSetting * setting)
{
copy_value(&setting->value,&setting->default_value);
}
static void init_info(BerylSettingInfo * info, CompOption * o, BerylSettingType type,
gchar * gettext_domain)
{
switch(type)
{
case BERYL_SETTING_TYPE_INT:
info->for_int.min=o->rest.i.min;
info->for_int.max=o->rest.i.max;
break;
case BERYL_SETTING_TYPE_FLOAT:
info->for_float.min=o->rest.f.min;
info->for_float.max=o->rest.f.max;
info->for_float.precision=o->rest.f.precision;
break;
case BERYL_SETTING_TYPE_STRING:
if (o->rest.s.nString && o->rest.s.string)
{
int i;
for (i=0;i<o->rest.s.nString;i++)
{
info->for_string.raw_values=g_slist_append(
info->for_string.raw_values,g_strdup(o->rest.s.string[i]));
info->for_string.allowed_values=g_slist_append(
info->for_string.allowed_values,
g_strdup(dgettext(gettext_domain,o->rest.s.string[i])));
}
}
break;
case BERYL_SETTING_TYPE_BINDING:
info->for_bind.key=(o->value.action.state &
CompActionStateInitKey) && TRUE;
info->for_bind.button=(o->value.action.state &
CompActionStateInitButton) && TRUE;
info->for_bind.edge=(o->value.action.state &
CompActionStateInitEdge) && TRUE;
info->for_bind.bell=(o->value.action.state &
CompActionStateInitBell) && TRUE;
break;
default:
break;
}
}
static void init_value(BerylSettingValue * value, CompOptionValue * from, BerylSettingType type,
gchar * gettext_domain)
{
switch(type)
{
case BERYL_SETTING_TYPE_INT:
value->value.as_int=from->i;
break;
case BERYL_SETTING_TYPE_FLOAT:
value->value.as_float=from->f;
break;
case BERYL_SETTING_TYPE_BOOL:
value->value.as_bool=from->b;
break;
case BERYL_SETTING_TYPE_COLOR:
{
int i;
for (i=0;i<4;i++)
value->value.as_color.array.array[i]=from->c[i];
}
break;
case BERYL_SETTING_TYPE_STRING:
value->value.as_string=g_strdup(from->s);
break;
case BERYL_SETTING_TYPE_BINDING:
value->value.as_binding.enabled.value.key=(from->action.type &
CompBindingTypeKey)?TRUE:FALSE;
value->value.as_binding.enabled.value.button=(from->action.type &
CompBindingTypeButton)?TRUE:FALSE;
value->value.as_binding.button=from->action.button.button;
value->value.as_binding.button_mod_mask=from->action.button.modifiers;
value->value.as_binding.keysym=from->action.key.keysym;
value->value.as_binding.key_mod_mask=from->action.key.modifiers;
value->value.as_binding.on_bell=from->action.bell;
value->value.as_binding.edge_mask=from->action.edgeMask;
break;
default:
break;
}
}
static BerylSettingType translate_type(CompOptionType type)
{
switch(type)
{
case CompOptionTypeInt:
return BERYL_SETTING_TYPE_INT;
case CompOptionTypeFloat:
return BERYL_SETTING_TYPE_FLOAT;
case CompOptionTypeString:
return BERYL_SETTING_TYPE_STRING;
case CompOptionTypeColor:
return BERYL_SETTING_TYPE_COLOR;
case CompOptionTypeBool:
return BERYL_SETTING_TYPE_BOOL;
case CompOptionTypeAction:
return BERYL_SETTING_TYPE_BINDING;
case CompOptionTypeList:
return BERYL_SETTING_TYPE_LIST;
default:
break;
}
return BERYL_SETTING_TYPE_COUNT;
}
static void init_option(BerylSettingsPlugin * plugin, CompOption * o, gboolean is_screen)
{
NEW(BerylSetting,setting);
setting->parent=plugin;
setting->is_screen=is_screen;
setting->is_default=TRUE;
setting->name=g_strdup(o->name);
setting->short_desc=g_strdup(
dgettext(plugin->gettext_domain,o->shortDesc));
setting->long_desc=g_strdup(dgettext(plugin->gettext_domain,o->longDesc));
setting->type=translate_type(o->type);
setting->default_value.parent=setting;
if (setting->type==BERYL_SETTING_TYPE_LIST)
{
NEW(BerylSettingInfo,list_info);
setting->info.for_list.list_of_type=translate_type(o->value.list.type);
setting->info.for_list.list_of_info=list_info;
init_info(setting->info.for_list.list_of_info,o,
setting->info.for_list.list_of_type,plugin->gettext_domain);
int i;
for (i=0;i<o->value.list.nValue;i++)
{
NEW(BerylSettingValue,val);
val->parent=setting;
val->is_list_child=TRUE;
init_value(val,&o->value.list.value[i],setting->info.for_list.list_of_type,
plugin->gettext_domain);
setting->default_value.value.as_list=
g_slist_append(setting->default_value.value.as_list,val);
}
}
else
{
init_info(&setting->info,o,setting->type,plugin->gettext_domain);
init_value(&setting->default_value,&o->value,setting->type,plugin->gettext_domain);
}
plugin->settings=g_slist_append(plugin->settings,setting);
copy_from_default(setting);
}
static void comp_value_to_setting_value(CompOptionValue * comp_value, BerylSettingValue * beryl_value)
{
BerylSettingType type;
if (beryl_value->is_list_child)
type=beryl_value->parent->info.for_list.list_of_type;
else
type=beryl_value->parent->type;
beryl_value->parent->is_default=FALSE;
switch(type)
{
case BERYL_SETTING_TYPE_INT:
beryl_value->value.as_int=comp_value->i;
break;
case BERYL_SETTING_TYPE_FLOAT:
beryl_value->value.as_float=comp_value->f;
break;
case BERYL_SETTING_TYPE_BOOL:
beryl_value->value.as_bool=comp_value->b;
break;
case BERYL_SETTING_TYPE_COLOR:
{
int i;
for (i=0;i<4;i++)
beryl_value->value.as_color.array.array[i]=comp_value->c[i];
}
break;
case BERYL_SETTING_TYPE_STRING:
if (beryl_value->value.as_string)
free(beryl_value->value.as_string);
beryl_value->value.as_string=g_strdup(comp_value->s);
break;
case BERYL_SETTING_TYPE_BINDING:
beryl_value->value.as_binding.enabled.value.key =
(comp_value->action.type & CompBindingTypeKey) != 0;
beryl_value->value.as_binding.key_mod_mask = comp_value->action.key.modifiers;
beryl_value->value.as_binding.keysym = comp_value->action.key.keysym;
beryl_value->value.as_binding.enabled.value.button =
(comp_value->action.type & CompBindingTypeButton) != 0;
beryl_value->value.as_binding.button_mod_mask = comp_value->action.button.modifiers;
beryl_value->value.as_binding.button = comp_value->action.button.button;
beryl_value->value.as_binding.edge_mask = comp_value->action.edgeMask;
beryl_value->value.as_binding.on_bell = comp_value->action.bell;
break;
case BERYL_SETTING_TYPE_LIST:
{
int i;
beryl_setting_list_clear(beryl_value->parent);
for (i=0;i<comp_value->list.nValue;i++)
{
BerylSettingValue * val = beryl_setting_list_append(beryl_value->parent);
comp_value_to_setting_value(&comp_value->list.value[i],val);
}
}
break;
default:
break;
}
}
static void setting_value_to_comp_value(BerylSettingValue * beryl_value, CompOptionValue * comp_value)
{
BerylSettingType type;
if (beryl_value->is_list_child)
type=beryl_value->parent->info.for_list.list_of_type;
else
type=beryl_value->parent->type;
switch(type)
{
case BERYL_SETTING_TYPE_INT:
comp_value->i=beryl_value->value.as_int;
break;
case BERYL_SETTING_TYPE_FLOAT:
comp_value->f=beryl_value->value.as_float;
break;
case BERYL_SETTING_TYPE_BOOL:
comp_value->b=beryl_value->value.as_bool;
break;
case BERYL_SETTING_TYPE_COLOR:
{
int i;
for (i=0;i<4;i++)
comp_value->c[i]=beryl_value->value.as_color.array.array[i];
}
break;
case BERYL_SETTING_TYPE_STRING:
comp_value->s=strdup(beryl_value->value.as_string);
break;
case BERYL_SETTING_TYPE_BINDING:
comp_value->action.type = CompBindingTypeNone;
if (beryl_value->value.as_binding.enabled.value.key)
comp_value->action.type |= CompBindingTypeKey;
comp_value->action.key.modifiers = beryl_value->value.as_binding.key_mod_mask;
comp_value->action.key.keysym = beryl_value->value.as_binding.keysym;
if (beryl_value->value.as_binding.enabled.value.button)
comp_value->action.type |= CompBindingTypeButton;
comp_value->action.button.modifiers = beryl_value->value.as_binding.button_mod_mask;
comp_value->action.button.button = beryl_value->value.as_binding.button;
comp_value->action.edgeMask=beryl_value->value.as_binding.edge_mask;
comp_value->action.bell=beryl_value->value.as_binding.on_bell;
break;
case BERYL_SETTING_TYPE_LIST:
{
int len=g_slist_length(beryl_value->value.as_list);
comp_value->list.nValue=len;
if (len)
{
comp_value->list.value=malloc(sizeof(CompOptionValue)*len);
memset(comp_value->list.value,0,
sizeof(CompOptionValue)*len);
GSList * i;
int j=0;
for (i=beryl_value->value.as_list;i;i=i->next)
{
setting_value_to_comp_value(i->data,&comp_value->list.value[j]);
j++;
}
}
}
break;
default:
break;
}
}
static void load_plugin(BerylSettingsContext * context, gchar * filename)
{
void * dlhand;
gchar * err;
PluginGetInfoProc getInfo;
CompPluginVTable * vt;
dlhand=dlopen(filename,RTLD_LAZY);
if (!dlhand)
{
err=dlerror();
if (err)
fprintf(stderr, _("libberylsettings: dlopen: %s\n"),err);
return;
}
dlerror();
getInfo = (PluginGetInfoProc) dlsym (dlhand, "getCompPluginInfo");
if ((err=dlerror()))
{
fprintf (stderr, _("libberylsettings: dlsym: %s\n"), err);
dlclose(dlhand);
return;
}
vt=getInfo();
if (vt->version != BERYL_VERSION ||
vt->struct_plugin_size != sizeof (CompPlugin) ||
vt->struct_display_size != sizeof (CompDisplay) ||
vt->struct_screen_size != sizeof (CompScreen) ||
vt->struct_window_size != sizeof (CompWindow) ||
vt->struct_texture_size != sizeof (CompTexture) ||
vt->struct_icon_size != sizeof (CompIcon))
{
fprintf (stderr, _("libberylsettings: Couldn't get vtable from '%s' plugin\n"), filename);
dlclose (dlhand);
return;
}
//make sure a plugin by the same name isn't already loaded
if (beryl_settings_context_find_plugin(context,vt->name))
{
dlclose(dlhand);
return;
}
NEW(BerylSettingsPlugin,plugin);
plugin->name=g_strdup(vt->name);
plugin->gettext_domain=g_strdup(vt->gettext_domain);
plugin->short_desc=g_strdup(dgettext(plugin->gettext_domain,vt->shortDesc));
plugin->long_desc=g_strdup(dgettext(plugin->gettext_domain,vt->longDesc));
int n;
for (n=0;n<vt->nDeps;n++)
{
switch(vt->deps[n].rule)
{
case CompPluginRuleBefore:
plugin->load_before=g_slist_append(
plugin->load_before,g_strdup(vt->deps[n].name));
break;
case CompPluginRuleAfter:
plugin->load_after=g_slist_append(
plugin->load_after,g_strdup(vt->deps[n].name));
break;
case CompPluginRuleRequire:
plugin->requires=g_slist_append(
plugin->requires,g_strdup(vt->deps[n].name));
break;
default:
break;
}
}
for (n=0;n<vt->nFeatures;n++)
{
plugin->provides=g_slist_append(plugin->provides,
g_strdup(vt->features[n].name));
}
if (vt->getDisplayOptions)
{
int n;
CompOption * o;
o = vt->getDisplayOptions(NULL,&n);
for (;n;n--)
{
init_option(plugin,o,FALSE);
o++;
}
}
if (vt->getScreenOptions)
{
int n;
CompOption * o;
o = vt->getScreenOptions(NULL,&n);
for (;n;n--)
{
init_option(plugin,o,TRUE);
o++;
}
}
dlclose(dlhand);
context->plugins=g_slist_append(context->plugins,plugin);
}
static void load_plugins(BerylSettingsContext * context, gchar * path)
/* iterates through $path and adds any plugins found to the context
$context the context to add to
$path the path to search for plugins (any .so file) */
{
GDir * d;
const gchar * n;
d=g_dir_open(path,0,NULL);
if (!d)
return; // no such path
while((n=g_dir_read_name(d)))
{
if (g_str_has_suffix(n,".so") && g_str_has_prefix(n,"lib"))
{
gchar * p;
p=g_strconcat(path,"/",n,NULL);
//actually load the plugin
load_plugin(context,p);
g_free(p);
}
}
g_dir_close(d);
}
static void init_core_settings (BerylSettingsContext * context)
{
NEW(BerylSettingsPlugin,plugin);
int n;
CompOption * o;
display = malloc(sizeof(CompDisplay));
compDisplayInitOptions(display,NULL,0);
plugin->gettext_domain=g_strdup("beryl-core");
o=compGetDisplayOptions(NULL,&n);
for (;n;n--)
{
init_option(plugin,o,FALSE);
o++;
}
o=compGetOptions(&n);
for (;n;n--)
{
init_option(plugin,o,TRUE);
o++;
}
context->plugins=g_slist_append(context->plugins,plugin);
}
static void free_value(BerylSettingValue * value)
{
BerylSettingType type;
if (value->is_list_child)
type=value->parent->info.for_list.list_of_type;
else
type=value->parent->type;
switch (type)
{
case BERYL_SETTING_TYPE_LIST:
g_slist_foreach(value->value.as_list,
(GFunc)free_value,NULL);
if (value->value.as_list)
g_slist_free(value->value.as_list);
break;
case BERYL_SETTING_TYPE_STRING:
if (value->value.as_string)
g_free(value->value.as_string);
default:
break;
}
if (value->is_list_child)
free(value);
}
static void free_string_info(BerylSettingInfo * info)
{
g_slist_foreach(info->for_string.allowed_values,
(GFunc)g_free,NULL);
g_slist_foreach(info->for_string.raw_values,
(GFunc)g_free,NULL);
if (info->for_string.allowed_values)
g_slist_free(info->for_string.allowed_values);
if (info->for_string.raw_values)
g_slist_free(info->for_string.raw_values);
}
static void free_setting(BerylSetting * setting)
{
if (setting->name) g_free(setting->name);
if (setting->short_desc) g_free(setting->short_desc);
if (setting->long_desc) g_free(setting->long_desc);
free_value(&setting->default_value);
free_value(&setting->value);
if (setting->type == BERYL_SETTING_TYPE_STRING)
free_string_info(&setting->info);
if (setting->type == BERYL_SETTING_TYPE_LIST &&
setting->info.for_list.list_of_type == BERYL_SETTING_TYPE_STRING)
free_string_info(setting->info.for_list.list_of_info);
if (setting->type == BERYL_SETTING_TYPE_LIST)
free(setting->info.for_list.list_of_info);
free(setting);
}
static void free_plugin(BerylSettingsPlugin * plugin)
{
if (plugin->name) g_free(plugin->name);
if (plugin->short_desc) g_free(plugin->short_desc);
if (plugin->long_desc) g_free(plugin->long_desc);
if (plugin->gettext_domain) g_free(plugin->gettext_domain);
g_slist_foreach(plugin->load_after,(GFunc)g_free,NULL);
g_slist_foreach(plugin->load_before,(GFunc)g_free,NULL);
g_slist_foreach(plugin->provides,(GFunc)g_free,NULL);
g_slist_foreach(plugin->requires,(GFunc)g_free,NULL);
g_slist_foreach(plugin->settings,(GFunc)free_setting,NULL);
if (plugin->load_after) g_slist_free(plugin->load_after);
if (plugin->load_before) g_slist_free(plugin->load_before);
if (plugin->provides) g_slist_free(plugin->provides);
if (plugin->requires) g_slist_free(plugin->requires);
if (plugin->settings) g_slist_free(plugin->settings);
free(plugin);
}
typedef struct _BerylSettingsFindPlugin
{
gchar * search_for;
BerylSettingsPlugin * found;
} BerylSettingsFindPlugin;
static void find_plugin(BerylSettingsPlugin * plugin, BerylSettingsFindPlugin * find)
{
if (find->found)
return;
if (find->search_for==NULL && plugin->name==NULL)
{
find->found=plugin;
return;
}
if (find->search_for && plugin->name && strcmp(find->search_for,plugin->name)==0)
find->found=plugin;
}
typedef struct _BerylSettingsFindSetting
{
gchar * search_for;
gboolean is_screen;
BerylSetting * found;
} BerylSettingsFindSetting;
static void find_setting(BerylSetting * setting, BerylSettingsFindSetting * find)
{
if (find->found)
return;
if (find->search_for &&
setting->name &&
find->is_screen==setting->is_screen &&
strcmp(find->search_for,setting->name)==0)
find->found=setting;
}
static void set_binding_value_from_array(BerylSettingValue * value, gint * array, gsize array_count)
{
gboolean button_enabled;
gboolean key_enabled;
if (array_count==8)
{
//it's 8 if new-style semantics are used, allowing the enabled to be set separately
//this should reintroduce some features gconf allowed but csm didn't
button_enabled=array[6]?TRUE:FALSE;
key_enabled=array[7]?TRUE:FALSE;
}
else if (array_count==6)
{
button_enabled=array[1]?TRUE:FALSE;
key_enabled=array[3]?TRUE:FALSE;
}
if (array_count==6 || array_count==8)
{
beryl_setting_value_set_key_enabled(value,&key_enabled);
beryl_setting_value_set_button_enabled(value,&button_enabled);
beryl_setting_value_set_buttonmods(value,&array[0]);
beryl_setting_value_set_button(value,&array[1]);
beryl_setting_value_set_keymods(value,&array[2]);
beryl_setting_value_set_keysym(value,&array[3]);
beryl_setting_value_set_edgemask(value,&array[4]);
gboolean bell_set=array[5]?TRUE:FALSE;
beryl_setting_value_set_bell(value,&bell_set);
}
}
static void set_color_value_from_array(BerylSettingValue * value, gint * array)
{
BerylSettingColorValue color_val;
memcpy(color_val.array.array,array,sizeof(gint)*4);
beryl_setting_value_set_color(value,&color_val);
}
// g_slist_nth_data(data,n) returns a gpointer, so * to dereference?
static void set_binding_value_from_gslist(BerylSettingValue * value, GSList *data, gint num_per, gint start)
{
gboolean button_enabled;
gboolean key_enabled;
if (num_per==8)
{
//it's 8 if new-style semantics are used, allowing the enabled to be set separately
//this should reintroduce some features gconf allowed but csm didn't
button_enabled = g_slist_nth_data(data,start+6)?TRUE:FALSE;
key_enabled = g_slist_nth_data(data,start+7)?TRUE:FALSE;
}
else if (num_per==6)
{
button_enabled = g_slist_nth_data(data, start + 1)?TRUE:FALSE;
key_enabled = g_slist_nth_data(data, start + 3)?TRUE:FALSE;
};
if (num_per==6 || num_per==8)
{
beryl_setting_value_set_key_enabled(value,&key_enabled);
beryl_setting_value_set_button_enabled(value,&button_enabled);
beryl_setting_value_set_buttonmods(value,g_slist_nth_data(data, start + 0));
beryl_setting_value_set_button(value,g_slist_nth_data(data, start + 1));
beryl_setting_value_set_keymods(value,g_slist_nth_data(data, start + 2));
beryl_setting_value_set_keysym(value,g_slist_nth_data(data, start + 3));
beryl_setting_value_set_edgemask(value, g_slist_nth_data(data, start + 4));
gboolean bell_set = g_slist_nth_data(data, start + 5)?TRUE:FALSE;
beryl_setting_value_set_bell(value,&bell_set);
};
}
static void set_color_value_from_gslist(BerylSettingValue *value, GSList *data, gint start)
{
BerylSettingColorValue color_val;
color_val.array.array[0] = (gint) g_slist_nth_data(data, start + 0);
color_val.array.array[1] = (gint) g_slist_nth_data(data, start + 1);
color_val.array.array[2] = (gint) g_slist_nth_data(data, start + 2);
color_val.array.array[3] = (gint) g_slist_nth_data(data, start + 3);
beryl_setting_value_set_color(value,&color_val);
}
#ifdef USE_GCONF
GConfValueType beryl_to_gconf_type(BerylSettingType bst)
{
switch(bst)
{
case BERYL_SETTING_TYPE_BOOL:
return GCONF_VALUE_BOOL;
break;
case BERYL_SETTING_TYPE_INT:
case BERYL_SETTING_TYPE_COLOR:
case BERYL_SETTING_TYPE_BINDING:
return GCONF_VALUE_INT;
break;
case BERYL_SETTING_TYPE_STRING:
return GCONF_VALUE_STRING;
break;
case BERYL_SETTING_TYPE_FLOAT:
return GCONF_VALUE_FLOAT;
break;
case BERYL_SETTING_TYPE_COUNT:
printf("A count...\n");
return GCONF_VALUE_INT;
default:
return GCONF_VALUE_INVALID;
break;
}
}
static void read_setting(BerylSetting * setting, GConfClient *client)
{
gboolean bool_val;
gint int_val;
gdouble float_val;
gchar * str_val;
gsize ret_count;
GSList *list = NULL;
int i = 0;
beryl_setting_reset_to_default(setting);
// TODO: If it's a key that metacity also uses... load from that instead
gchar *keyname=g_strconcat(setting->is_screen?"s_":"a_",setting->name,NULL);
gchar *groupname = setting->parent->name?setting->parent->name:"_";
gchar *temp = g_strconcat("/apps/beryl/",groupname,NULL);
groupname=g_strconcat(temp, "/", NULL);
g_free(temp);
gchar *gconf_path = g_strconcat(groupname,keyname, NULL);
g_free(groupname);
g_free(keyname);
GConfValue *key = gconf_client_get_without_default(client, gconf_path, NULL);
g_free(gconf_path);
if (key == NULL)
return;
setting->is_default=FALSE;
switch(setting->type)
{
case BERYL_SETTING_TYPE_INT:
int_val = gconf_value_get_int(key);
beryl_setting_value_set_int(&setting->value, &int_val);
break;
case BERYL_SETTING_TYPE_FLOAT:
float_val = gconf_value_get_float(key);
beryl_setting_value_set_float(&setting->value, &float_val);
break;
case BERYL_SETTING_TYPE_BOOL:
bool_val = gconf_value_get_bool(key);
beryl_setting_value_set_bool(&setting->value, &bool_val);
break;
case BERYL_SETTING_TYPE_COLOR:
list = gconf_value_get_list(key);
if (list && g_slist_length(list) == 4)
set_color_value_from_gslist(&setting->value,list, 0);
g_slist_free(list);
break;
case BERYL_SETTING_TYPE_STRING:
//FIXME probably need _set_raw_string here
//but since beryl_setting_value_set_string(&setting->value,(const gchar **) &str_val);
str_val = gconf_value_get_string(key);
setting->value.value.as_string=g_strdup(str_val);
setting->is_default=FALSE;
g_free(str_val);
break;
case BERYL_SETTING_TYPE_BINDING:
list=gconf_value_get_list(key);
if (list)
set_binding_value_from_gslist(&setting->value,list, g_slist_length(list), 0);
g_slist_free(list);
break;
case BERYL_SETTING_TYPE_LIST:
list = gconf_value_get_list(key);
ret_count = g_slist_length(list);
if (!list || ret_count == 0)
{
g_slist_free(list);
break;
};
switch(setting->info.for_list.list_of_type)
{
case BERYL_SETTING_TYPE_STRING:
beryl_setting_list_clear(setting);
for (i = 0;i < ret_count; i++)
{
BerylSettingValue * value=beryl_setting_list_append(setting);
value->value.as_string = g_strdup(g_slist_nth_data(list, i));
value->parent->is_default=FALSE;
//beryl_setting_value_set_string(value,(const gchar **) &str_ret[i]);
}
g_slist_free(list);
break;
case BERYL_SETTING_TYPE_FLOAT:
beryl_setting_list_clear(setting);
for (i=0;i<ret_count;i++)
{
BerylSettingValue * value=beryl_setting_list_append(setting);
beryl_setting_value_set_float(value, g_slist_nth_data(list, i));
}
g_slist_free(list);
break;
case BERYL_SETTING_TYPE_INT:
beryl_setting_list_clear(setting);
for (i=0;i<ret_count;i++)
{
BerylSettingValue * value=beryl_setting_list_append(setting);
beryl_setting_value_set_int(value,g_slist_nth_data(list, i));
}
g_slist_free(list);
break;
case BERYL_SETTING_TYPE_BOOL:
beryl_setting_list_clear(setting);
for (i=0;i<ret_count;i++)
{
BerylSettingValue * value=beryl_setting_list_append(setting);
beryl_setting_value_set_bool(value,g_slist_nth_data(list, i));
}
g_slist_free(list);
break;
case BERYL_SETTING_TYPE_COLOR:
if (ret_count%4==0)
{
beryl_setting_list_clear(setting);
for (i = 0; i < ret_count / 4; i++)
{
BerylSettingValue * value=beryl_setting_list_append(setting);
set_color_value_from_gslist(value,list, i*4);
}
}
g_slist_free(list);
break;
case BERYL_SETTING_TYPE_BINDING:
if (ret_count%6==0 || ret_count%8==0)
{
beryl_setting_list_clear(setting);
int num_per=(ret_count%6==0)?6:8;
for (i=0;i<ret_count/num_per;i++)
{
BerylSettingValue * value=beryl_setting_list_append(setting);
set_binding_value_from_gslist(value, list, num_per, i*num_per);
}
}
g_slist_free(list);
break;
default:
break;
}
break;
default:
break;
}
// Some memory loss here? :(
// if (key) gconf_value_free(key);
}
static void write_setting(BerylSetting * setting, GConfClient *client)
{
GSList *list = NULL;
int i;
// TODO: If it's a key that metacity also uses... write to that as well
gchar *keyname=g_strconcat(setting->is_screen?"s_":"a_",setting->name,NULL);
gchar *groupname = setting->parent->name?setting->parent->name:"_";
gchar *temp = g_strconcat("/apps/beryl/",groupname,NULL);
groupname=g_strconcat(temp, "/", NULL);
g_free(temp);
gchar *gconf_path = g_strconcat(groupname,keyname, NULL);
g_free(groupname);
g_free(keyname);
// if (setting->is_default && setting->is_screen)
// {
// gconf_client_unset(client, gconf_path, NULL);
// g_free(gconf_path);
// return;
// }
if (!gconf_client_key_is_writable(client, gconf_path, NULL))
{
printf("libberylsettings: main.c: write_setting: key \"%s\" not writable", gconf_path);
g_free(gconf_path);
return;
};
switch(setting->type)
{
case BERYL_SETTING_TYPE_STRING:
gconf_client_set_string(client, gconf_path, setting->value.value.as_string, NULL);
break;
case BERYL_SETTING_TYPE_FLOAT:
gconf_client_set_float(client, gconf_path, setting->value.value.as_float, NULL);
break;
case BERYL_SETTING_TYPE_INT:
gconf_client_set_int(client,gconf_path, setting->value.value.as_int, NULL);
break;
case BERYL_SETTING_TYPE_BOOL:
gconf_client_set_bool(client,gconf_path, setting->value.value.as_bool, NULL);
break;
case BERYL_SETTING_TYPE_BINDING:
{
list = set_gslist_from_binding(list,&setting->value);
gconf_client_set_list(client,gconf_path, GCONF_VALUE_INT, list, NULL);
g_slist_free(list);
}
break;
case BERYL_SETTING_TYPE_COLOR:
{
list = set_gslist_from_color(list, &setting->value);
gconf_client_set_list(client, gconf_path,GCONF_VALUE_INT,list, NULL);
g_slist_free(list);
}
break;
case BERYL_SETTING_TYPE_LIST:
{
GSList *data = g_slist_alloc();
BerylSettingValue *v;
for (i = 0; i < g_slist_length(setting->value.value.as_list); i++)
{
v = g_slist_nth_data(setting->value.value.as_list, i);
switch (setting->info.for_list.list_of_type)
{
case BERYL_SETTING_TYPE_STRING:
data = g_slist_append(data, v->value.as_string);
break;
default: break;
};
};
gconf_client_set_list(client, gconf_path, beryl_to_gconf_type(setting->info.for_list.list_of_type), data, NULL);
g_slist_free(data);
}
break;
default:
break;
}
g_free(gconf_path);
}
static void read_settings_for_plugin(BerylSettingsPlugin * plugin, GConfClient *client)
{
g_slist_foreach(plugin->settings,(GFunc)read_setting, client);
}
static void write_settings_for_plugin(BerylSettingsPlugin * plugin, GConfClient *client)
{
g_slist_foreach(plugin->settings,(GFunc)write_setting, client);
gconf_client_suggest_sync(client, NULL);
}
void beryl_settings_context_read(BerylSettingsContext * context)
{
g_type_init();
if (!client)
client = gconf_client_get_default();
if (!GCONF_IS_CLIENT(client))
{
printf("Error getting client :(\n");
return;
};
if (gconf_client_dir_exists(client, "/apps/beryl", NULL))
gconf_client_add_dir(client, "/apps/beryl", GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
g_slist_foreach(context->plugins,(GFunc)read_settings_for_plugin, client);
}
void beryl_settings_context_write(BerylSettingsContext * context)
{
g_type_init();
if (!client)
client = gconf_client_get_default();
if (gconf_client_dir_exists(client, "/apps/beryl", NULL))
gconf_client_add_dir(client, "/apps/beryl", GCONF_CLIENT_PRELOAD_NONE, NULL);
g_slist_foreach(context->plugins,(GFunc)write_settings_for_plugin,client);
}
#else
static void read_setting(BerylSetting * setting, GKeyFile * f)
{
const gchar * groupname;
gchar * keyname;
gboolean bool_val;
gint int_val;
gdouble float_val;
gchar * str_val;
gchar ** str_ret;
gsize ret_count;
gint * int_ret;
gboolean * bool_ret;
GError * e;
beryl_setting_reset_to_default(setting);
if (setting->parent->name)
groupname=setting->parent->name;
else
groupname="_"; // pseudo-plugin for core
if (setting->is_screen)
keyname=g_strconcat("s_",setting->name,NULL);
else
keyname=g_strconcat("a_",setting->name,NULL);
if (!g_key_file_has_key(f,groupname,keyname,NULL))
{
g_free(keyname);
return;
}
e=NULL;
setting->is_default=FALSE;
switch(setting->type)
{
case BERYL_SETTING_TYPE_INT:
int_val=g_key_file_get_integer(f,groupname,keyname,&e);
if (!e)
beryl_setting_value_set_int(&setting->value,&int_val);
break;
case BERYL_SETTING_TYPE_FLOAT:
str_val=g_key_file_get_string(f,groupname,keyname,&e);
if (!e && str_val)
{
float_val=g_ascii_strtod(str_val,NULL);
beryl_setting_value_set_float(&setting->value,&float_val);
g_free(str_val);
}
break;
case BERYL_SETTING_TYPE_BOOL:
bool_val=g_key_file_get_boolean(f,groupname,keyname,&e);
if (!e)
beryl_setting_value_set_bool(&setting->value,&bool_val);
break;
case BERYL_SETTING_TYPE_COLOR:
int_ret=g_key_file_get_integer_list(f,groupname,keyname,&ret_count,&e);
if (!e && int_ret)
{
if (ret_count==4)
set_color_value_from_array(&setting->value,int_ret);
g_free(int_ret);
}
break;
case BERYL_SETTING_TYPE_STRING:
str_val=g_key_file_get_string(f,groupname,keyname,&e);
if (!e && str_val)
{
//FIXME probably need _set_raw_string here
//but since
//beryl_setting_value_set_string(&setting->value,(const gchar **) &str_val);
setting->value.value.as_string=g_strdup(str_val);
setting->is_default=FALSE;
g_free(str_val);
}
break;
case BERYL_SETTING_TYPE_BINDING:
int_ret=g_key_file_get_integer_list(f,groupname,keyname,&ret_count,&e);
if (!e && int_ret)
{
set_binding_value_from_array(&setting->value,int_ret,ret_count);
g_free(int_ret);
}
break;
case BERYL_SETTING_TYPE_LIST:
switch(setting->info.for_list.list_of_type)
{
case BERYL_SETTING_TYPE_STRING:
str_ret=g_key_file_get_string_list(f,groupname,keyname,&ret_count,&e);
if (!e && str_ret)
{
beryl_setting_list_clear(setting);
int i;
for (i=0;i<ret_count;i++)
{
BerylSettingValue * value=beryl_setting_list_append(setting);
value->value.as_string=g_strdup(str_ret[i]);
value->parent->is_default=FALSE;
//beryl_setting_value_set_string(value,(const gchar **) &str_ret[i]);
}
g_strfreev(str_ret);
}
break;
case BERYL_SETTING_TYPE_FLOAT:
str_ret=g_key_file_get_string_list(f,groupname,keyname,&ret_count,&e);
if (!e && str_ret)
{
beryl_setting_list_clear(setting);
int i;
for (i=0;i<ret_count;i++)
{
BerylSettingValue * value=beryl_setting_list_append(setting);
float_val=g_ascii_strtod(str_ret[i],NULL);
beryl_setting_value_set_float(value,&float_val);
}
g_strfreev(str_ret);
}
break;
case BERYL_SETTING_TYPE_INT:
int_ret=g_key_file_get_integer_list(f,groupname,keyname,&ret_count,&e);
if (!e && int_ret)
{
beryl_setting_list_clear(setting);
int i;
for (i=0;i<ret_count;i++)
{
BerylSettingValue * value=beryl_setting_list_append(setting);
beryl_setting_value_set_int(value,&int_ret[i]);
}
g_free(int_ret);
}
break;
case BERYL_SETTING_TYPE_BOOL:
bool_ret=g_key_file_get_boolean_list(f,groupname,keyname,&ret_count,&e);
if (!e && bool_ret)
{
beryl_setting_list_clear(setting);
int i;
for (i=0;i<ret_count;i++)
{
BerylSettingValue * value=beryl_setting_list_append(setting);
beryl_setting_value_set_bool(value,&bool_ret[i]);
}
g_free(bool_ret);
}
break;
case BERYL_SETTING_TYPE_COLOR:
int_ret=g_key_file_get_integer_list(f,groupname,keyname,&ret_count,&e);
if (!e && int_ret)
{
if (ret_count%4==0)
{
beryl_setting_list_clear(setting);
int i;
for (i=0;i<ret_count/4;i++)
{
BerylSettingValue * value=beryl_setting_list_append(setting);
set_color_value_from_array(value,&int_ret[i*4]);
}
}
g_free(int_ret);
}
break;
case BERYL_SETTING_TYPE_BINDING:
int_ret=g_key_file_get_integer_list(f,groupname,keyname,&ret_count,&e);
if (!e && int_ret)
{
if (ret_count%6==0 || ret_count%8==0)
{
beryl_setting_list_clear(setting);
int num_per=(ret_count%6==0)?6:8;
int i;
for (i=0;i<ret_count/num_per;i++)
{
BerylSettingValue * value=beryl_setting_list_append(setting);
set_binding_value_from_array(value,&int_ret[i*num_per],num_per);
}
}
g_free(int_ret);
}
break;
default:
break;
}
break;
default:
break;
}
g_free(keyname);
}
static void write_setting(BerylSetting * setting, GKeyFile * f)
{
gchar * groupname=setting->parent->name?setting->parent->name:"_";
gchar * keyname=g_strconcat(setting->is_screen?"s_":"a_",setting->name,NULL);
if (setting->is_default)
{
g_key_file_remove_key(f,groupname,keyname,NULL);
g_free(keyname);
return;
}
switch(setting->type)
{
case BERYL_SETTING_TYPE_STRING:
g_key_file_set_string(f,groupname,keyname,setting->value.value.as_string);
break;
case BERYL_SETTING_TYPE_FLOAT:
{
gchar buffer[G_ASCII_DTOSTR_BUF_SIZE];
g_ascii_dtostr(buffer,G_ASCII_DTOSTR_BUF_SIZE,setting->value.value.as_float);
g_key_file_set_string(f,groupname,keyname,buffer);
}
break;
case BERYL_SETTING_TYPE_INT:
g_key_file_set_integer(f,groupname,keyname,setting->value.value.as_int);
break;
case BERYL_SETTING_TYPE_BOOL:
g_key_file_set_boolean(f,groupname,keyname,setting->value.value.as_bool);
break;
case BERYL_SETTING_TYPE_BINDING:
{
gint bindval[8];
set_array_from_binding(bindval,&setting->value);
g_key_file_set_integer_list(f,groupname,keyname,bindval,8);
}
break;
case BERYL_SETTING_TYPE_COLOR:
{
gint colorval[4];
set_array_from_color(&setting->value,colorval);
g_key_file_set_integer_list(f,groupname,keyname,colorval,4);
}
break;
case BERYL_SETTING_TYPE_LIST:
{
gsize len=g_slist_length(setting->value.value.as_list);
switch(setting->info.for_list.list_of_type)
{
case BERYL_SETTING_TYPE_BOOL:
{
gboolean * list = malloc(len*sizeof(gboolean));
gboolean * ptr = list;
g_slist_foreach(setting->value.value.as_list,(GFunc)copy_bool,&ptr);
g_key_file_set_boolean_list(f,groupname,keyname,list,len);
free(list);
}
break;
case BERYL_SETTING_TYPE_INT:
{
gint * list = malloc(len*sizeof(gint));
gint * ptr = list;
g_slist_foreach(setting->value.value.as_list,(GFunc)copy_int,&ptr);
g_key_file_set_integer_list(f,groupname,keyname,list,len);
free(list);
}
break;
case BERYL_SETTING_TYPE_STRING:
{
gchar ** list = malloc((len+1)*sizeof(gchar *));
list[len]=NULL;
gchar ** ptr=list;
g_slist_foreach(setting->value.value.as_list,(GFunc)copy_string,&ptr);
g_key_file_set_string_list(f,groupname,keyname,(const gchar * const *)list,
len);
g_strfreev(list); // TODO - I think this is safe with malloc()'d arrays
}
break;
case BERYL_SETTING_TYPE_FLOAT:
{
gchar ** list = malloc((len+1)*sizeof(gchar *));
list[len]=NULL;
gchar ** ptr=list;
g_slist_foreach(setting->value.value.as_list,(GFunc)copy_float,&ptr);
g_key_file_set_string_list(f,groupname,keyname,(const gchar * const *)list,
len);
g_strfreev(list); // TODO - I think this is safe with malloc()'d arrays
}
break;
case BERYL_SETTING_TYPE_COLOR:
{
gint * list = malloc(len*sizeof(gint)*4);
gint * ptr = list;
g_slist_foreach(setting->value.value.as_list,(GFunc)copy_color,&ptr);
g_key_file_set_integer_list(f,groupname,keyname,list,len);
free(list);
}
break;
case BERYL_SETTING_TYPE_BINDING:
{
gint * list = malloc(len*sizeof(gint)*8);
gint * ptr = list;
g_slist_foreach(setting->value.value.as_list,(GFunc)copy_binding,&ptr);
g_key_file_set_integer_list(f,groupname,keyname,list,len);
free(list);
}
break;
default:
break;
}
}
break;
default:
break;
}
g_free(keyname);
}
static void read_settings_for_plugin(BerylSettingsPlugin * plugin, GKeyFile * f)
{
g_slist_foreach(plugin->settings,(GFunc)read_setting,f);
}
static void write_settings_for_plugin(BerylSettingsPlugin * plugin, GKeyFile * f)
{
g_slist_foreach(plugin->settings,(GFunc)write_setting,f);
}
void beryl_settings_context_read(BerylSettingsContext * context)
{
GKeyFile * f;
gchar * path = g_strconcat(g_get_home_dir(),"/.beryl/settings",NULL);
f=g_key_file_new();
if (!g_key_file_load_from_file(f,path,0,NULL))
{
g_key_file_free(f);
g_free(path);
return;
}
g_free(path);
g_slist_foreach(context->plugins,(GFunc)read_settings_for_plugin,f);
g_key_file_free(f);
}
void beryl_settings_context_write(BerylSettingsContext * context)
{
GKeyFile * f;
gchar * path = g_strconcat(g_get_home_dir(),"/.beryl/",NULL);
gchar * data;
g_mkdir_with_parents(path,00755); // ensure path exists
g_free(path);
path=g_strconcat(g_get_home_dir(),"/.beryl/settings",NULL);
f=g_key_file_new();
g_key_file_load_from_file(f,path,0,NULL);
g_slist_foreach(context->plugins,(GFunc)write_settings_for_plugin,f);
if (g_file_test(path,G_FILE_TEST_IS_SYMLINK))
{
gchar * tmp = path;
path=g_file_read_link(path,NULL);
g_free(tmp);
}
data = g_key_file_to_data(f,NULL,NULL);
g_file_set_contents(path,data,-1,NULL);
g_free(path);
g_free(data);
g_key_file_free(f);
}
#endif
static void set_array_from_binding(gint * array, BerylSettingValue * value)
{
array[0]=value->value.as_binding.button_mod_mask;
array[1]=value->value.as_binding.button;
array[2]=value->value.as_binding.key_mod_mask;
array[3]=value->value.as_binding.keysym;
array[4]=value->value.as_binding.edge_mask;
array[5]=value->value.as_binding.on_bell?1:0;
array[6]=value->value.as_binding.enabled.value.button?1:0;
array[7]=value->value.as_binding.enabled.value.key?1:0;
}
static void set_array_from_color(BerylSettingValue * value, gint * array)
{
memcpy(array,value->value.as_color.array.array,sizeof(gint)*4);
}
static GSList *set_gslist_from_binding(GSList * list, BerylSettingValue * value)
{
gboolean bindval = value->value.as_binding.on_bell?1:0;
gboolean bindbtn = value->value.as_binding.enabled.value.button?1:0;
gboolean bindkey = value->value.as_binding.enabled.value.key?1:0;
// Get us some happy empty RAM
if (list) g_slist_free(list);
list = g_slist_alloc();
list = g_slist_append(list, &value->value.as_binding.button_mod_mask);
list = g_slist_append(list, &value->value.as_binding.button);
list = g_slist_append(list, &value->value.as_binding.key_mod_mask);
list = g_slist_append(list, &value->value.as_binding.keysym);
list = g_slist_append(list, &value->value.as_binding.edge_mask);
list = g_slist_append(list, &bindval);
list = g_slist_append(list, &bindbtn);
list = g_slist_append(list, &bindkey);
return list;
}
static GSList *set_gslist_from_color(GSList *list, BerylSettingValue *value)
{
if (list) g_slist_free(list);
list = g_slist_alloc();
list = g_slist_append(list, &value->value.as_color.array.array[0]);
list = g_slist_append(list, &value->value.as_color.array.array[1]);
list = g_slist_append(list, &value->value.as_color.array.array[2]);
list = g_slist_append(list, &value->value.as_color.array.array[3]);
return list;
}
static void copy_bool(BerylSettingValue * value, gboolean ** ptr)
{
*(*ptr++)=value->value.as_bool;
}
static void copy_int(BerylSettingValue * value, gint ** ptr)
{
*(*ptr++)=value->value.as_int;
}
static void copy_float(BerylSettingValue * value, gchar *** ptr)
{
gchar buffer[G_ASCII_DTOSTR_BUF_SIZE];
*(*ptr++)=g_strdup(g_ascii_dtostr(buffer,G_ASCII_DTOSTR_BUF_SIZE,value->value.as_float));
}
static void copy_binding(BerylSettingValue * value, gint ** ptr)
{
set_array_from_binding(*ptr,value);
*ptr+=8;
}
static void copy_string(BerylSettingValue * value, gchar *** ptr)
{
*(*ptr)=g_strdup(value->value.as_string);
*ptr=*ptr+1;
}
static void copy_color(BerylSettingValue * value, gint ** ptr)
{
set_array_from_color(value,*ptr);
*ptr+=4;
}
typedef struct _BerylFindListSettingIndex
{
int index;
gboolean found;
BerylSettingValue * value;
} BerylFindListSettingIndex;
static void find_index_of(BerylSettingValue * value, BerylFindListSettingIndex * find)
{
if (find->found)
return;
if (find->value==value)
find->found=TRUE;
else
find->index++;
}
static gboolean check_s_type(BerylSetting * setting, BerylSettingType type)
{
if (setting->type==BERYL_SETTING_TYPE_LIST)
return setting->info.for_list.list_of_type==type;
else
return setting->type==type;
}
static BerylSettingInfo * get_s_info(BerylSetting * setting)
{
if (setting->type==BERYL_SETTING_TYPE_LIST)
return setting->info.for_list.list_of_info;
else
return &setting->info;
}
static gboolean check_type(BerylSettingValue * value, BerylSettingType type)
{
if (value->is_list_child)
return value->parent->info.for_list.list_of_type==type;
else
return value->parent->type==type;
}
static BerylSettingInfo * get_info(BerylSettingValue * value)
{
if (value->is_list_child)
return value->parent->info.for_list.list_of_info;
else
return &value->parent->info;
}
//EXPORTED FUNCTIONS
BerylSettingsContext * beryl_settings_context_new(void)
{
gchar * homeplugins=g_strconcat(g_get_home_dir(),"/.beryl/plugins",NULL);
NEW(BerylSettingsContext,context);
init_core_settings(context);
load_plugins(context,homeplugins);
load_plugins(context,PLUGINDIR); // load after, because that way name conflicts
// will lead to the home version being loaded
g_free(homeplugins);
return context;
}
void beryl_settings_context_destroy(BerylSettingsContext * context)
{
g_slist_foreach(context->plugins,(GFunc)free_plugin,NULL);
if (context->plugins) g_slist_free(context->plugins);
free(context);
free(display);
}
BerylSettingsPlugin * beryl_settings_context_find_plugin(BerylSettingsContext * context, gchar * name)
{
BerylSettingsFindPlugin find;
find.found=NULL;
find.search_for=name;
g_slist_foreach(context->plugins,(GFunc)find_plugin,&find);
return find.found;
}
BerylSetting * beryl_settings_plugin_find_setting(BerylSettingsPlugin * plugin, gchar * name,
gboolean is_screen)
{
BerylSettingsFindSetting find;
find.found=NULL;
find.search_for=name;
find.is_screen=is_screen;
g_slist_foreach(plugin->settings,(GFunc)find_setting,&find);
return find.found;
}
BerylSettingsContext * beryl_settings_context_comp_new(void)
{
NEW(BerylSettingsContext,context);
context->is_comp=TRUE;
return context;
}
gboolean beryl_settings_context_comp_add_plugin(BerylSettingsContext * context, gchar * name)
{
if (!context->is_comp) return FALSE;
if (beryl_settings_context_find_plugin(context,name))
return FALSE;
NEW(BerylSettingsPlugin,plugin);
if (name)
plugin->name=g_strdup(name);
plugin->gettext_domain=g_strdup("");
context->plugins=g_slist_append(context->plugins,plugin);
return TRUE;
}
#if 0 /* Incomplete */
void beryl_settings_context_comp_free_option(s_plugin, option)
{
BerylSetting * setting;
g_free(setting->name);
g_free(setting->short_desc);
g_free(setting->long_desc);
free_value(setting->value);
}
#endif
gboolean beryl_settings_context_comp_add_option(BerylSettingsContext * context,
gchar * plugin, CompOption * option, gboolean is_screen)
{
if (!context->is_comp) return FALSE;
BerylSettingsPlugin * s_plugin;
if (!(s_plugin=beryl_settings_context_find_plugin(context,plugin)))
return FALSE;
if (beryl_settings_plugin_find_setting(s_plugin,option->name,is_screen))
return FALSE;
init_option(s_plugin,option,is_screen);
return TRUE;
}
gboolean beryl_settings_context_comp_get_option_value(BerylSettingsContext * context,
gchar * plugin, gchar * name, gboolean is_screen, CompOptionValue * value)
{
if (!context->is_comp) return FALSE;
BerylSettingsPlugin * s_plugin;
BerylSetting * setting;
if (!(s_plugin=beryl_settings_context_find_plugin(context,plugin)))
{
return FALSE;
}
if (!(setting=beryl_settings_plugin_find_setting(s_plugin,name,is_screen)))
{
return FALSE;
}
setting_value_to_comp_value(&setting->value,value);
return TRUE;
}
gboolean beryl_settings_context_comp_set_option_value(BerylSettingsContext * context,
gchar * plugin, gchar * name, gboolean is_screen, CompOptionValue * value)
{
if (!context->is_comp) return FALSE;
BerylSettingsPlugin * s_plugin;
BerylSetting * setting;
if (!(s_plugin=beryl_settings_context_find_plugin(context,plugin)))
return FALSE;
if (!(setting=beryl_settings_plugin_find_setting(s_plugin,name,is_screen)))
return FALSE;
setting->is_default=FALSE;
comp_value_to_setting_value(value,&setting->value);
return TRUE;
}
gboolean beryl_settings_send_reload_signal(void)
{
gchar * args[] =
{"killall","-u",(gchar *)g_get_user_name(),"-SIGUSR1","-r","^beryl$|^beryl-xgl$",NULL};
gchar * ret=NULL;
if (!g_spawn_sync(NULL,args,NULL,G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_SEARCH_PATH,
NULL,NULL,&ret,NULL,NULL,NULL) || !ret)
return FALSE;
return TRUE;
}
void beryl_setting_reset_to_default(BerylSetting * setting)
{
//if (!setting->is_default)
free_value(&setting->value);
copy_from_default(setting);
setting->is_default=TRUE;
}
void beryl_setting_list_clear(BerylSetting * setting)
{
if (setting->type != BERYL_SETTING_TYPE_LIST)
return;
setting->is_default=FALSE;
g_slist_foreach(setting->value.value.as_list,
(GFunc)free_value,NULL);
if (setting->value.value.as_list)
g_slist_free(setting->value.value.as_list);
setting->value.value.as_list=NULL;
}
BerylSettingValue * beryl_setting_list_append(BerylSetting * setting)
{
if (setting->type != BERYL_SETTING_TYPE_LIST)
return NULL;
setting->is_default=FALSE;
NEW(BerylSettingValue,value);
value->parent=setting;
value->is_list_child=TRUE;
setting->value.value.as_list=g_slist_append(setting->value.value.as_list,value);
return value;
}
gint beryl_setting_list_length(BerylSetting * setting)
{
if (setting->type != BERYL_SETTING_TYPE_LIST)
return -1;
return g_slist_length(setting->value.value.as_list);
}
gint beryl_setting_list_value_index(BerylSettingValue * value)
{
if (!value->is_list_child)
return -1;
BerylFindListSettingIndex find;
find.found=FALSE;
find.index=0;
find.value=value;
g_slist_foreach(value->parent->value.value.as_list,(GFunc)find_index_of,&find);
if (find.found)
return find.index;
else
return -1;
}
void beryl_setting_list_value_swap_with(BerylSettingValue * value, guint n)
{
if (!value->is_list_child)
return;
GSList * a = g_slist_nth(value->parent->value.value.as_list,n);
GSList * b = g_slist_find(value->parent->value.value.as_list,value);
if (!a || !b)
return;
value->parent->is_default=FALSE;
b->data=a->data;
a->data=value;
}
void beryl_setting_list_value_move_before(BerylSettingValue * value, guint n)
{
if (!value->is_list_child)
return;
GSList * a = g_slist_nth(value->parent->value.value.as_list,n);
if (a && a->data==value)
return;
value->parent->is_default=FALSE;
if (!a)
{
value->parent->value.value.as_list=g_slist_append(g_slist_remove(
value->parent->value.value.as_list,value),value);
return;
}
value->parent->value.value.as_list=g_slist_insert_before(
g_slist_remove(value->parent->value.value.as_list,value),a,value);
}
void beryl_setting_list_value_remove(BerylSettingValue * value)
{
if (!value->is_list_child)
return;
value->parent->is_default=FALSE;
value->parent->value.value.as_list=g_slist_remove(
value->parent->value.value.as_list,value);
free_value(value);
}
BerylSettingValue * beryl_setting_get_primary_value(BerylSetting * setting)
{
return &setting->value;
}
gboolean beryl_setting_value_get_int(BerylSettingValue * value, gint * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_INT))
return FALSE;
*data=value->value.as_int;
return TRUE;
}
gboolean beryl_setting_value_get_float(BerylSettingValue * value, gdouble * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_FLOAT))
return FALSE;
*data=value->value.as_float;
return TRUE;
}
gboolean beryl_setting_value_get_bool(BerylSettingValue * value, gboolean * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BOOL))
return FALSE;
*data=value->value.as_bool;
return TRUE;
}
gboolean beryl_setting_value_get_string(BerylSettingValue * value, const gchar ** data)
{
if (!check_type(value,BERYL_SETTING_TYPE_STRING))
return FALSE;
BerylSettingInfo * info=get_info(value);
if (info->for_string.raw_values)
{
GSList * reststring=info->for_string.raw_values;
GSList * xlatstring=info->for_string.allowed_values;
while(reststring)
{
if (strcmp(value->value.as_string,reststring->data)==0)
{
*data=xlatstring->data;
return TRUE;
}
reststring=reststring->next;
xlatstring=xlatstring->next;
}
}
else
{
*data=value->value.as_string;
return TRUE;
}
return FALSE;
}
gboolean beryl_setting_value_get_keysym(BerylSettingValue * value, gint * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
*data=value->value.as_binding.keysym;
return TRUE;
}
gboolean beryl_setting_value_get_keymods(BerylSettingValue * value, gint * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
*data=value->value.as_binding.key_mod_mask;
return TRUE;
}
gboolean beryl_setting_value_get_button(BerylSettingValue * value, gint * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
*data=value->value.as_binding.button;
return TRUE;
}
gboolean beryl_setting_value_get_buttonmods(BerylSettingValue * value, gint * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
*data=value->value.as_binding.button_mod_mask;
return TRUE;
}
gboolean beryl_setting_value_get_edgemask(BerylSettingValue * value, gint * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
*data=value->value.as_binding.edge_mask;
return TRUE;
}
gboolean beryl_setting_value_get_bell(BerylSettingValue * value, gboolean * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
*data=value->value.as_binding.on_bell;
return TRUE;
}
gboolean beryl_setting_value_get_key_enabled(BerylSettingValue * value, gboolean * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
*data=value->value.as_binding.enabled.value.key;
return TRUE;
}
gboolean beryl_setting_value_get_button_enabled(BerylSettingValue * value, gboolean * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
*data=value->value.as_binding.enabled.value.button;
return TRUE;
}
gboolean beryl_setting_value_get_color(BerylSettingValue * value, BerylSettingColorValue * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_COLOR))
return FALSE;
memcpy(data,&value->value.as_color,sizeof(BerylSettingColorValue));
return TRUE;
}
gboolean beryl_setting_value_get_value_list(BerylSettingValue * value, GSList ** data)
{
if (!check_type(value,BERYL_SETTING_TYPE_LIST))
return FALSE;
*data=value->value.as_list;
return TRUE;
}
gboolean beryl_setting_value_set_int(BerylSettingValue * value, gint * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_INT))
return FALSE;
BerylSettingInfo * info = get_info(value);
if (*data<info->for_int.min || *data>info->for_int.max)
return FALSE;
value->parent->is_default=FALSE;
value->value.as_int=*data;
return TRUE;
}
gboolean beryl_setting_value_set_float(BerylSettingValue * value, gdouble * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_FLOAT))
return FALSE;
BerylSettingInfo * info = get_info(value);
if (*data<info->for_float.min || *data>info->for_float.max)
return FALSE;
value->parent->is_default=FALSE;
value->value.as_float=*data;
return TRUE;
}
gboolean beryl_setting_value_set_bool(BerylSettingValue * value, gboolean * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BOOL))
return FALSE;
value->parent->is_default=FALSE;
value->value.as_bool=*data;
return TRUE;
}
gboolean beryl_setting_value_set_string(BerylSettingValue * value, const gchar ** data)
{
if (!check_type(value,BERYL_SETTING_TYPE_STRING))
return FALSE;
BerylSettingInfo * info = get_info(value);
if (info->for_string.raw_values)
{
GSList * reststring=info->for_string.raw_values;
GSList * xlatstring=info->for_string.allowed_values;
while(reststring)
{
if (strcmp(*data,xlatstring->data)==0)
{
if (value->value.as_string)
g_free(value->value.as_string);
value->value.as_string=g_strdup(reststring->data);
value->parent->is_default=FALSE;
return TRUE;
}
reststring=reststring->next;
xlatstring=xlatstring->next;
}
}
else
{
if (value->value.as_string)
g_free(value->value.as_string);
value->value.as_string=g_strdup(*data);
value->parent->is_default=FALSE;
return TRUE;
}
return FALSE;
}
gboolean beryl_setting_value_set_keysym(BerylSettingValue * value, gint * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
if (!get_info(value)->for_bind.key)
return FALSE;
value->value.as_binding.keysym=*data;
value->parent->is_default=FALSE;
return TRUE;
}
gboolean beryl_setting_value_set_keymods(BerylSettingValue * value, gint * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
if (!get_info(value)->for_bind.key)
return FALSE;
value->value.as_binding.key_mod_mask=*data;
value->parent->is_default=FALSE;
return TRUE;
}
gboolean beryl_setting_value_set_button(BerylSettingValue * value, gint * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
if (!get_info(value)->for_bind.button)
return FALSE;
value->value.as_binding.button=*data;
value->parent->is_default=FALSE;
return TRUE;
}
gboolean beryl_setting_value_set_buttonmods(BerylSettingValue * value, gint * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
if (!get_info(value)->for_bind.button)
return FALSE;
value->value.as_binding.button_mod_mask=*data;
value->parent->is_default=FALSE;
return TRUE;
}
gboolean beryl_setting_value_set_edgemask(BerylSettingValue * value, gint * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
if (!get_info(value)->for_bind.edge)
return FALSE;
value->value.as_binding.edge_mask=*data;
value->parent->is_default=FALSE;
return TRUE;
}
gboolean beryl_setting_value_set_bell(BerylSettingValue * value, gboolean * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
if (!get_info(value)->for_bind.bell)
return FALSE;
value->value.as_binding.on_bell=*data;
value->parent->is_default=FALSE;
return TRUE;
}
gboolean beryl_setting_value_set_key_enabled(BerylSettingValue * value, gboolean * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
if (!get_info(value)->for_bind.key)
return FALSE;
value->value.as_binding.enabled.value.key=*data;
value->parent->is_default=FALSE;
return TRUE;
}
gboolean beryl_setting_value_set_button_enabled(BerylSettingValue * value, gboolean * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_BINDING))
return FALSE;
if (!get_info(value)->for_bind.button)
return FALSE;
value->value.as_binding.enabled.value.button=*data;
value->parent->is_default=FALSE;
return TRUE;
}
gboolean beryl_setting_value_set_color(BerylSettingValue * value, BerylSettingColorValue * data)
{
if (!check_type(value,BERYL_SETTING_TYPE_COLOR))
return FALSE;
memcpy(&value->value.as_color,data,sizeof(BerylSettingColorValue));
value->parent->is_default=FALSE;
return TRUE;
}
gboolean beryl_setting_get_can_set_key(BerylSetting * setting, gboolean * data)
{
if (!check_s_type(setting,BERYL_SETTING_TYPE_BINDING))
return FALSE;
*data=get_s_info(setting)->for_bind.key;
return TRUE;
}
gboolean beryl_setting_get_can_set_button(BerylSetting * setting, gboolean * data)
{
if (!check_s_type(setting,BERYL_SETTING_TYPE_BINDING))
return FALSE;
*data=get_s_info(setting)->for_bind.button;
return TRUE;
}
gboolean beryl_setting_get_can_set_edgemask(BerylSetting * setting, gboolean * data)
{
if (!check_s_type(setting,BERYL_SETTING_TYPE_BINDING))
return FALSE;
*data=get_s_info(setting)->for_bind.edge;
return TRUE;
}
gboolean beryl_setting_get_can_set_bell(BerylSetting * setting, gboolean * data)
{
if (!check_s_type(setting,BERYL_SETTING_TYPE_BINDING))
return FALSE;
*data=get_s_info(setting)->for_bind.bell;
return TRUE;
}
gboolean beryl_setting_get_allowed_strings(BerylSetting * setting, GSList ** data)
{
if (!check_s_type(setting,BERYL_SETTING_TYPE_STRING))
return FALSE;
*data=get_s_info(setting)->for_string.allowed_values;
return TRUE;
}
gboolean beryl_setting_get_raw_allowed_strings(BerylSetting * setting, GSList ** data)
{
if (!check_s_type(setting,BERYL_SETTING_TYPE_STRING))
return FALSE;
*data=get_s_info(setting)->for_string.raw_values;
return TRUE;
}
gboolean beryl_setting_get_int_max(BerylSetting * setting, gint * data)
{
if (!check_s_type(setting,BERYL_SETTING_TYPE_INT))
return FALSE;
*data=get_s_info(setting)->for_int.max;
return TRUE;
}
gboolean beryl_setting_get_int_min(BerylSetting * setting, gint * data)
{
if (!check_s_type(setting,BERYL_SETTING_TYPE_INT))
return FALSE;
*data=get_s_info(setting)->for_int.min;
return TRUE;
}
gboolean beryl_setting_get_float_min(BerylSetting * setting, gdouble * data)
{
if (!check_s_type(setting,BERYL_SETTING_TYPE_FLOAT))
return FALSE;
*data=get_s_info(setting)->for_float.min;
return TRUE;
}
gboolean beryl_setting_get_float_max(BerylSetting * setting, gdouble * data)
{
if (!check_s_type(setting,BERYL_SETTING_TYPE_FLOAT))
return FALSE;
*data=get_s_info(setting)->for_float.max;
return TRUE;
}
gboolean beryl_setting_get_float_precision(BerylSetting * setting, gdouble * data)
{
if (!check_s_type(setting,BERYL_SETTING_TYPE_FLOAT))
return FALSE;
*data=get_s_info(setting)->for_float.precision;
return TRUE;
}
gboolean beryl_setting_get_list_type(BerylSetting * setting, BerylSettingType * data)
{
if (setting->type != BERYL_SETTING_TYPE_LIST)
return FALSE;
*data=setting->info.for_list.list_of_type;
return TRUE;
}
BerylSettingType beryl_setting_get_type(BerylSetting * setting)
{
return setting->type;
}
const gchar * beryl_setting_get_short_desc(BerylSetting * setting)
{
return setting->short_desc;
}
const gchar * beryl_setting_get_long_desc(BerylSetting * setting)
{
return setting->long_desc;
}
const gchar * beryl_setting_get_name(BerylSetting * setting)
{
return setting->name;
}
const gchar * beryl_settings_plugin_get_short_desc(BerylSettingsPlugin * plugin)
{
return plugin->short_desc;
}
const gchar * beryl_settings_plugin_get_long_desc(BerylSettingsPlugin * plugin)
{
return plugin->long_desc;
}
const gchar * beryl_settings_plugin_get_name(BerylSettingsPlugin * plugin)
{
return plugin->name;
}
GSList * beryl_settings_context_get_plugins(BerylSettingsContext * context)
{
return context->plugins;
}
GSList * beryl_settings_plugin_get_settings(BerylSettingsPlugin * plugin)
{
return plugin->settings;
}
gpointer beryl_settings_context_get_private(BerylSettingsContext * context)
{
return context->private_ptr;
}
void beryl_settings_context_set_private(BerylSettingsContext * context, gpointer private_ptr)
{
context->private_ptr = private_ptr;
}
gpointer beryl_settings_plugin_get_private(BerylSettingsPlugin * plugin)
{
return plugin->private_ptr;
}
void beryl_settings_plugin_set_private(BerylSettingsPlugin * plugin, gpointer private_ptr)
{
plugin->private_ptr = private_ptr;
}
gpointer beryl_setting_get_private(BerylSetting * setting)
{
return setting->private_ptr;
}
void beryl_setting_set_private(BerylSetting * setting, gpointer private_ptr)
{
setting->private_ptr = private_ptr;
}