293 lines
7.6 KiB
C
293 lines
7.6 KiB
C
#include "private.h"
|
|
#include "config.h"
|
|
#include "utils.h"
|
|
#include "window.h"
|
|
|
|
# define EX_CONFIG_LIMIT(v, min, max) \
|
|
if (v > max) v = max; else if (v < min) v = min;
|
|
|
|
# define EX_CONFIG_DD_NEW(str, typ) \
|
|
_config_descriptor_new(str, sizeof(typ))
|
|
|
|
# define EX_CONFIG_DD_FREE(eed) \
|
|
if (eed) { eet_data_descriptor_free(eed); (eed) = NULL; }
|
|
|
|
# define EX_CONFIG_VAL(edd, type, member, dtype) \
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(edd, type, #member, member, dtype)
|
|
|
|
# define EX_CONFIG_SUB(edd, type, member, eddtype) \
|
|
EET_DATA_DESCRIPTOR_ADD_SUB(edd, type, #member, member, eddtype)
|
|
|
|
# define EX_CONFIG_LIST(edd, type, member, eddtype) \
|
|
EET_DATA_DESCRIPTOR_ADD_LIST(edd, type, #member, member, eddtype)
|
|
|
|
# define EX_CONFIG_HASH(edd, type, member, eddtype) \
|
|
EET_DATA_DESCRIPTOR_ADD_HASH(edd, type, #member, member, eddtype)
|
|
|
|
# define EX_CONFIG_FILE_EPOCH 0x0001
|
|
# define EX_CONFIG_FILE_GENERATION 0x008d
|
|
# define EX_CONFIG_FILE_VERSION \
|
|
((EX_CONFIG_FILE_EPOCH << 16) | EX_CONFIG_FILE_GENERATION)
|
|
|
|
typedef Eet_Data_Descriptor Ex_Config_DD;
|
|
|
|
/* local variables */
|
|
static Ex_Config_DD *_ex_cfg_edd = NULL;
|
|
static Ex_Config_DD *_ex_cfg_srv_edd = NULL;
|
|
static Ex_Config_DD *_ex_cfg_net_edd = NULL;
|
|
static Ex_Config_DD *_ex_cfg_chl_edd = NULL;
|
|
|
|
/* external variables */
|
|
Config *_ex_cfg = NULL;
|
|
|
|
/* local functions */
|
|
static Ex_Config_DD *
|
|
_config_descriptor_new(const char *name, int size)
|
|
{
|
|
Eet_Data_Descriptor_Class eddc;
|
|
|
|
if (!eet_eina_stream_data_descriptor_class_set(&eddc, sizeof(eddc),
|
|
name, size))
|
|
return NULL;
|
|
|
|
return (Ex_Config_DD *)eet_data_descriptor_stream_new(&eddc);
|
|
}
|
|
|
|
static void
|
|
_config_cb_free(void)
|
|
{
|
|
Config_Network *net;
|
|
|
|
EINA_LIST_FREE(_ex_cfg->networks, net)
|
|
{
|
|
Config_Server *srv;
|
|
Config_Channel *chl;
|
|
|
|
EINA_LIST_FREE(net->servers, srv)
|
|
{
|
|
if (srv->name) eina_stringshare_del(srv->name);
|
|
free(srv);
|
|
}
|
|
|
|
EINA_LIST_FREE(net->channels, chl)
|
|
{
|
|
if (chl->name) eina_stringshare_del(chl->name);
|
|
free(chl);
|
|
}
|
|
|
|
if (net->name) eina_stringshare_del(net->name);
|
|
if (net->nick_passwd) eina_stringshare_del(net->nick_passwd);
|
|
if (net->server_passwd) eina_stringshare_del(net->server_passwd);
|
|
|
|
free(net);
|
|
}
|
|
|
|
if (_ex_cfg->font.name) eina_stringshare_del(_ex_cfg->font.name);
|
|
if (_ex_cfg->nick) eina_stringshare_del(_ex_cfg->nick);
|
|
if (_ex_cfg->name) eina_stringshare_del(_ex_cfg->name);
|
|
|
|
free(_ex_cfg);
|
|
_ex_cfg = NULL;
|
|
}
|
|
|
|
static void *
|
|
_config_domain_load(const char *domain, Ex_Config_DD *edd)
|
|
{
|
|
Eet_File *ef;
|
|
char buff[PATH_MAX];
|
|
|
|
if (!domain) return NULL;
|
|
snprintf(buff, sizeof(buff),
|
|
"%s/%s.cfg", _util_user_dir_get(), domain);
|
|
ef = eet_open(buff, EET_FILE_MODE_READ);
|
|
if (ef)
|
|
{
|
|
void *data;
|
|
|
|
data = eet_data_read(ef, edd, "config");
|
|
eet_close(ef);
|
|
if (data) return data;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_config_domain_save(const char *domain, Ex_Config_DD *edd, const void *data)
|
|
{
|
|
Eet_File *ef;
|
|
char buff[PATH_MAX];
|
|
const char *userdir;
|
|
|
|
if (!domain) return 0;
|
|
userdir = _util_user_dir_get();
|
|
snprintf(buff, sizeof(buff), "%s/", userdir);
|
|
if (!ecore_file_exists(buff)) ecore_file_mkpath(buff);
|
|
snprintf(buff, sizeof(buff), "%s/%s.tmp", userdir, domain);
|
|
ef = eet_open(buff, EET_FILE_MODE_WRITE);
|
|
if (ef)
|
|
{
|
|
char buff2[PATH_MAX];
|
|
|
|
snprintf(buff2, sizeof(buff2), "%s/%s.cfg", userdir, domain);
|
|
if (!eet_data_write(ef, edd, "config", data, 1))
|
|
{
|
|
eet_close(ef);
|
|
return EINA_FALSE;
|
|
}
|
|
if (eet_close(ef) > 0) return EINA_FALSE;
|
|
if (!ecore_file_mv(buff, buff2)) return EINA_FALSE;
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
/* external functions */
|
|
Eina_Bool
|
|
_config_init(void)
|
|
{
|
|
elm_need_efreet();
|
|
if (!efreet_init()) return EINA_FALSE;
|
|
|
|
_ex_cfg_chl_edd = EX_CONFIG_DD_NEW("Config_Channel", Config_Channel);
|
|
#undef T
|
|
#undef D
|
|
#define T Config_Channel
|
|
#define D _ex_cfg_chl_edd
|
|
EX_CONFIG_VAL(D, T, name, EET_T_STRING);
|
|
|
|
_ex_cfg_srv_edd = EX_CONFIG_DD_NEW("Config_Server", Config_Server);
|
|
#undef T
|
|
#undef D
|
|
#define T Config_Server
|
|
#define D _ex_cfg_srv_edd
|
|
EX_CONFIG_VAL(D, T, name, EET_T_STRING);
|
|
EX_CONFIG_VAL(D, T, port, EET_T_INT);
|
|
|
|
_ex_cfg_net_edd = EX_CONFIG_DD_NEW("Config_Network", Config_Network);
|
|
#undef T
|
|
#undef D
|
|
#define T Config_Network
|
|
#define D _ex_cfg_net_edd
|
|
EX_CONFIG_VAL(D, T, name, EET_T_STRING);
|
|
EX_CONFIG_VAL(D, T, nick_passwd, EET_T_STRING);
|
|
EX_CONFIG_VAL(D, T, server_passwd, EET_T_STRING);
|
|
EX_CONFIG_VAL(D, T, autoconnect, EET_T_UCHAR);
|
|
EX_CONFIG_VAL(D, T, bypass_proxy, EET_T_UCHAR);
|
|
EX_CONFIG_VAL(D, T, use_ssl, EET_T_UCHAR);
|
|
EX_CONFIG_LIST(D, T, servers, _ex_cfg_srv_edd);
|
|
EX_CONFIG_LIST(D, T, channels, _ex_cfg_chl_edd);
|
|
|
|
_ex_cfg_edd = EX_CONFIG_DD_NEW("Config", Config);
|
|
#undef T
|
|
#undef D
|
|
#define T Config
|
|
#define D _ex_cfg_edd
|
|
EX_CONFIG_VAL(D, T, version, EET_T_INT);
|
|
EX_CONFIG_VAL(D, T, nick, EET_T_STRING);
|
|
EX_CONFIG_VAL(D, T, name, EET_T_STRING);
|
|
EX_CONFIG_VAL(D, T, font.name, EET_T_STRING);
|
|
EX_CONFIG_VAL(D, T, font.size, EET_T_INT);
|
|
EX_CONFIG_VAL(D, T, font.bitmap, EET_T_UCHAR);
|
|
EX_CONFIG_VAL(D, T, gui.translucent, EET_T_UCHAR);
|
|
EX_CONFIG_VAL(D, T, gui.zoom, EET_T_DOUBLE);
|
|
EX_CONFIG_VAL(D, T, gui.scrollback, EET_T_INT);
|
|
EX_CONFIG_LIST(D, T, networks, _ex_cfg_net_edd);
|
|
|
|
_config_load();
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_config_shutdown(void)
|
|
{
|
|
_config_cb_free();
|
|
|
|
EX_CONFIG_DD_FREE(_ex_cfg_chl_edd);
|
|
EX_CONFIG_DD_FREE(_ex_cfg_srv_edd);
|
|
EX_CONFIG_DD_FREE(_ex_cfg_net_edd);
|
|
EX_CONFIG_DD_FREE(_ex_cfg_edd);
|
|
|
|
efreet_shutdown();
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
void
|
|
_config_load(void)
|
|
{
|
|
Eina_Bool save = EINA_FALSE;
|
|
|
|
_ex_cfg = _config_domain_load(PACKAGE_NAME, _ex_cfg_edd);
|
|
if (_ex_cfg)
|
|
{
|
|
Eina_Bool reload = EINA_FALSE;
|
|
|
|
if ((_ex_cfg->version >> 16) < EX_CONFIG_FILE_EPOCH)
|
|
{
|
|
/* config too old */
|
|
reload = EINA_TRUE;
|
|
}
|
|
else if (_ex_cfg->version > EX_CONFIG_FILE_VERSION)
|
|
{
|
|
/* config too new, WTF ? */
|
|
reload = EINA_TRUE;
|
|
}
|
|
|
|
/* if too old or too new, clear it so we can create new */
|
|
if (reload) _config_cb_free();
|
|
}
|
|
|
|
if (!_ex_cfg)
|
|
{
|
|
_ex_cfg = malloc(sizeof(Config));
|
|
save = EINA_TRUE;
|
|
}
|
|
|
|
/* define some convenient macros */
|
|
#define IFCFG(v) if ((_ex_cfg->version & 0xffff) < (v)) {
|
|
#define IFCFGELSE } else {
|
|
#define IFCFGEND }
|
|
|
|
/* setup defaults */
|
|
IFCFG(0x008d);
|
|
char *usr;
|
|
|
|
if ((usr = _util_user_name_get()))
|
|
_ex_cfg->nick = eina_stringshare_add(usr);
|
|
else
|
|
_ex_cfg->nick = NULL;
|
|
if ((usr = _util_user_fullname_get()))
|
|
_ex_cfg->name = eina_stringshare_add(usr);
|
|
else
|
|
_ex_cfg->name = NULL;
|
|
_ex_cfg->font.size = 10;
|
|
_ex_cfg->font.bitmap = EINA_TRUE;
|
|
_ex_cfg->font.name = eina_stringshare_add("nexus.pcf");
|
|
_ex_cfg->gui.translucent = EINA_TRUE;
|
|
_ex_cfg->gui.zoom = 0.5;
|
|
_ex_cfg->gui.scrollback = 2000;
|
|
_ex_cfg->networks = NULL;
|
|
IFCFGEND;
|
|
|
|
/* limit config values so they are sane */
|
|
EX_CONFIG_LIMIT(_ex_cfg->font.size, 3, 400);
|
|
EX_CONFIG_LIMIT(_ex_cfg->gui.zoom, 0.1, 1.0);
|
|
EX_CONFIG_LIMIT(_ex_cfg->gui.scrollback, 0, 200000);
|
|
|
|
_ex_cfg->version = EX_CONFIG_FILE_VERSION;
|
|
|
|
if (save) _config_save();
|
|
}
|
|
|
|
void
|
|
_config_save(void)
|
|
{
|
|
if (_config_domain_save(PACKAGE_NAME, _ex_cfg_edd, _ex_cfg))
|
|
{
|
|
/* update window, channels, etc */
|
|
_window_update();
|
|
}
|
|
}
|