968 lines
26 KiB
C
968 lines
26 KiB
C
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include "efreet_alloca.h"
|
|
|
|
#ifdef HAVE_EVIL
|
|
# include <Evil.h>
|
|
#endif
|
|
|
|
#include <Ecore_File.h>
|
|
|
|
/* define macros and variable for using the eina logging system */
|
|
#define EFREET_MODULE_LOG_DOM _efreet_desktop_log_dom
|
|
int _efreet_desktop_log_dom = -1;
|
|
|
|
#include "Efreet.h"
|
|
#include "efreet_private.h"
|
|
|
|
#define DESKTOP_VERSION "1.0"
|
|
|
|
/**
|
|
* The current desktop environment (e.g. "Enlightenment" or "Gnome")
|
|
*/
|
|
static const char *desktop_environment = NULL;
|
|
|
|
/**
|
|
* A list of the desktop types available
|
|
*/
|
|
static Eina_List *efreet_desktop_types = NULL;
|
|
|
|
EAPI int EFREET_DESKTOP_TYPE_APPLICATION = 0;
|
|
EAPI int EFREET_DESKTOP_TYPE_LINK = 0;
|
|
EAPI int EFREET_DESKTOP_TYPE_DIRECTORY = 0;
|
|
|
|
/**
|
|
* @internal
|
|
* Information about custom types
|
|
*/
|
|
typedef struct Efreet_Desktop_Type_Info Efreet_Desktop_Type_Info;
|
|
struct Efreet_Desktop_Type_Info
|
|
{
|
|
int id;
|
|
const char *type;
|
|
Efreet_Desktop_Type_Parse_Cb parse_func;
|
|
Efreet_Desktop_Type_Save_Cb save_func;
|
|
Efreet_Desktop_Type_Free_Cb free_func;
|
|
};
|
|
|
|
static int efreet_desktop_read(Efreet_Desktop *desktop);
|
|
static Efreet_Desktop_Type_Info *efreet_desktop_type_parse(const char *type_str);
|
|
static void efreet_desktop_type_info_free(Efreet_Desktop_Type_Info *info);
|
|
static void *efreet_desktop_application_fields_parse(Efreet_Desktop *desktop,
|
|
Efreet_Ini *ini);
|
|
static void efreet_desktop_application_fields_save(Efreet_Desktop *desktop,
|
|
Efreet_Ini *ini);
|
|
static void *efreet_desktop_link_fields_parse(Efreet_Desktop *desktop,
|
|
Efreet_Ini *ini);
|
|
static void efreet_desktop_link_fields_save(Efreet_Desktop *desktop,
|
|
Efreet_Ini *ini);
|
|
static int efreet_desktop_generic_fields_parse(Efreet_Desktop *desktop,
|
|
Efreet_Ini *ini);
|
|
static void efreet_desktop_generic_fields_save(Efreet_Desktop *desktop,
|
|
Efreet_Ini *ini);
|
|
static Eina_Bool efreet_desktop_x_fields_parse(const Eina_Hash *hash,
|
|
const void *key,
|
|
void *data,
|
|
void *fdata);
|
|
static Eina_Bool efreet_desktop_x_fields_save(const Eina_Hash *hash,
|
|
const void *key,
|
|
void *value,
|
|
void *fdata);
|
|
static int efreet_desktop_environment_check(Efreet_Desktop *desktop);
|
|
|
|
/**
|
|
* @internal
|
|
* @return Returns > 0 on success or 0 on failure
|
|
* @brief Initialize the Desktop parser subsystem
|
|
*/
|
|
int
|
|
efreet_desktop_init(void)
|
|
{
|
|
_efreet_desktop_log_dom = eina_log_domain_register
|
|
("efreet_desktop", EFREET_DEFAULT_LOG_COLOR);
|
|
if (_efreet_desktop_log_dom < 0)
|
|
{
|
|
EINA_LOG_ERR("Efreet: Could not create a log domain for efreet_desktop");
|
|
return 0;
|
|
}
|
|
|
|
#ifdef HAVE_EVIL
|
|
if (!evil_sockets_init())
|
|
{
|
|
ERR("Could not initialize Winsock system");
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
efreet_desktop_types = NULL;
|
|
|
|
EFREET_DESKTOP_TYPE_APPLICATION = efreet_desktop_type_add("Application",
|
|
efreet_desktop_application_fields_parse,
|
|
efreet_desktop_application_fields_save,
|
|
NULL);
|
|
EFREET_DESKTOP_TYPE_LINK = efreet_desktop_type_add("Link",
|
|
efreet_desktop_link_fields_parse,
|
|
efreet_desktop_link_fields_save, NULL);
|
|
EFREET_DESKTOP_TYPE_DIRECTORY = efreet_desktop_type_add("Directory", NULL,
|
|
NULL, NULL);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* @returns the number of initializations left for this system
|
|
* @brief Attempts to shut down the subsystem if nothing else is using it
|
|
*/
|
|
void
|
|
efreet_desktop_shutdown(void)
|
|
{
|
|
Efreet_Desktop_Type_Info *info;
|
|
|
|
IF_RELEASE(desktop_environment);
|
|
EINA_LIST_FREE(efreet_desktop_types, info)
|
|
efreet_desktop_type_info_free(info);
|
|
#ifdef HAVE_EVIL
|
|
evil_sockets_shutdown();
|
|
#endif
|
|
eina_log_domain_unregister(_efreet_desktop_log_dom);
|
|
_efreet_desktop_log_dom = -1;
|
|
}
|
|
|
|
EAPI Efreet_Desktop *
|
|
efreet_desktop_get(const char *file)
|
|
{
|
|
Efreet_Desktop *desktop;
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
|
|
|
|
desktop = efreet_desktop_new(file);
|
|
if (!desktop) return NULL;
|
|
|
|
/* If we didn't find this file in the eet cache, add path to search path */
|
|
if (!desktop->eet)
|
|
{
|
|
/* Check whether the desktop type is a system type,
|
|
* and therefor known by the cache builder */
|
|
Efreet_Desktop_Type_Info *info;
|
|
|
|
info = eina_list_nth(efreet_desktop_types, desktop->type);
|
|
if (info && (
|
|
info->id == EFREET_DESKTOP_TYPE_APPLICATION ||
|
|
info->id == EFREET_DESKTOP_TYPE_LINK ||
|
|
info->id == EFREET_DESKTOP_TYPE_DIRECTORY
|
|
))
|
|
efreet_cache_desktop_add(desktop);
|
|
}
|
|
|
|
return desktop;
|
|
}
|
|
|
|
EAPI int
|
|
efreet_desktop_ref(Efreet_Desktop *desktop)
|
|
{
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(desktop, 0);
|
|
desktop->ref++;
|
|
return desktop->ref;
|
|
}
|
|
|
|
EAPI Efreet_Desktop *
|
|
efreet_desktop_empty_new(const char *file)
|
|
{
|
|
Efreet_Desktop *desktop;
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
|
|
|
|
desktop = NEW(Efreet_Desktop, 1);
|
|
if (!desktop) return NULL;
|
|
|
|
desktop->orig_path = strdup(file);
|
|
desktop->load_time = ecore_file_mod_time(file);
|
|
|
|
desktop->ref = 1;
|
|
|
|
return desktop;
|
|
}
|
|
|
|
EAPI Efreet_Desktop *
|
|
efreet_desktop_new(const char *file)
|
|
{
|
|
Efreet_Desktop *desktop = NULL;
|
|
char *tmp;
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
|
|
|
|
tmp = eina_file_path_sanitize(file);
|
|
if (!tmp) return NULL;
|
|
|
|
desktop = efreet_cache_desktop_find(tmp);
|
|
free(tmp);
|
|
if (desktop)
|
|
{
|
|
desktop->ref++;
|
|
if (!efreet_desktop_environment_check(desktop))
|
|
{
|
|
efreet_desktop_free(desktop);
|
|
return NULL;
|
|
}
|
|
return desktop;
|
|
}
|
|
return efreet_desktop_uncached_new(file);
|
|
}
|
|
|
|
EAPI Efreet_Desktop *
|
|
efreet_desktop_uncached_new(const char *file)
|
|
{
|
|
Efreet_Desktop *desktop = NULL;
|
|
char *tmp;
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
|
|
if (!ecore_file_exists(file)) return NULL;
|
|
|
|
tmp = eina_file_path_sanitize(file);
|
|
if (!tmp) return NULL;
|
|
|
|
desktop = NEW(Efreet_Desktop, 1);
|
|
if (!desktop)
|
|
{
|
|
free(tmp);
|
|
return NULL;
|
|
}
|
|
desktop->orig_path = tmp;
|
|
desktop->ref = 1;
|
|
if (!efreet_desktop_read(desktop))
|
|
{
|
|
efreet_desktop_free(desktop);
|
|
return NULL;
|
|
}
|
|
|
|
return desktop;
|
|
}
|
|
|
|
EAPI int
|
|
efreet_desktop_save(Efreet_Desktop *desktop)
|
|
{
|
|
Efreet_Desktop_Type_Info *info;
|
|
Efreet_Ini *ini;
|
|
int ok = 1;
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(desktop, 0);
|
|
|
|
ini = efreet_ini_new(NULL);
|
|
if (!ini) return 0;
|
|
efreet_ini_section_add(ini, "Desktop Entry");
|
|
efreet_ini_section_set(ini, "Desktop Entry");
|
|
|
|
info = eina_list_nth(efreet_desktop_types, desktop->type);
|
|
if (info)
|
|
{
|
|
efreet_ini_string_set(ini, "Type", info->type);
|
|
if (info->save_func) info->save_func(desktop, ini);
|
|
}
|
|
else
|
|
ok = 0;
|
|
|
|
if (ok)
|
|
{
|
|
char *val;
|
|
|
|
if (desktop->only_show_in)
|
|
{
|
|
val = efreet_desktop_string_list_join(desktop->only_show_in);
|
|
if (val)
|
|
{
|
|
efreet_ini_string_set(ini, "OnlyShowIn", val);
|
|
FREE(val);
|
|
}
|
|
}
|
|
if (desktop->not_show_in)
|
|
{
|
|
val = efreet_desktop_string_list_join(desktop->not_show_in);
|
|
if (val)
|
|
{
|
|
efreet_ini_string_set(ini, "NotShowIn", val);
|
|
FREE(val);
|
|
}
|
|
}
|
|
efreet_desktop_generic_fields_save(desktop, ini);
|
|
/* When we save the file, it should be updated to the
|
|
* latest version that we support! */
|
|
efreet_ini_string_set(ini, "Version", DESKTOP_VERSION);
|
|
|
|
if (!efreet_ini_save(ini, desktop->orig_path)) ok = 0;
|
|
}
|
|
efreet_ini_free(ini);
|
|
return ok;
|
|
}
|
|
|
|
EAPI int
|
|
efreet_desktop_save_as(Efreet_Desktop *desktop, const char *file)
|
|
{
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(desktop, 0);
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
|
|
|
|
/* If we save data from eet as new, we will be in trouble */
|
|
if (desktop->eet) return 0;
|
|
|
|
IF_FREE(desktop->orig_path);
|
|
desktop->orig_path = strdup(file);
|
|
return efreet_desktop_save(desktop);
|
|
}
|
|
|
|
EAPI void
|
|
efreet_desktop_free(Efreet_Desktop *desktop)
|
|
{
|
|
if (!desktop) return;
|
|
|
|
desktop->ref--;
|
|
if (desktop->ref > 0) return;
|
|
|
|
if (desktop->eet)
|
|
{
|
|
efreet_cache_desktop_free(desktop);
|
|
}
|
|
else
|
|
{
|
|
IF_FREE(desktop->orig_path);
|
|
|
|
IF_FREE(desktop->version);
|
|
IF_FREE(desktop->name);
|
|
IF_FREE(desktop->generic_name);
|
|
IF_FREE(desktop->comment);
|
|
IF_FREE(desktop->icon);
|
|
IF_FREE(desktop->url);
|
|
|
|
IF_FREE(desktop->try_exec);
|
|
IF_FREE(desktop->exec);
|
|
IF_FREE(desktop->path);
|
|
IF_FREE(desktop->startup_wm_class);
|
|
|
|
IF_FREE_LIST(desktop->only_show_in, eina_stringshare_del);
|
|
IF_FREE_LIST(desktop->not_show_in, eina_stringshare_del);
|
|
|
|
IF_FREE_LIST(desktop->categories, eina_stringshare_del);
|
|
IF_FREE_LIST(desktop->mime_types, eina_stringshare_del);
|
|
|
|
IF_FREE_HASH(desktop->x);
|
|
|
|
if (desktop->type_data)
|
|
{
|
|
Efreet_Desktop_Type_Info *info;
|
|
info = eina_list_nth(efreet_desktop_types, desktop->type);
|
|
if (info->free_func)
|
|
info->free_func(desktop->type_data);
|
|
}
|
|
free(desktop);
|
|
}
|
|
}
|
|
|
|
EAPI void
|
|
efreet_desktop_environment_set(const char *environment)
|
|
{
|
|
if (desktop_environment) eina_stringshare_del(desktop_environment);
|
|
if (environment) desktop_environment = eina_stringshare_add(environment);
|
|
else desktop_environment = NULL;
|
|
}
|
|
|
|
EAPI const char *
|
|
efreet_desktop_environment_get(void)
|
|
{
|
|
return desktop_environment;
|
|
}
|
|
|
|
EAPI unsigned int
|
|
efreet_desktop_category_count_get(Efreet_Desktop *desktop)
|
|
{
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(desktop, 0);
|
|
return eina_list_count(desktop->categories);
|
|
}
|
|
|
|
EAPI void
|
|
efreet_desktop_category_add(Efreet_Desktop *desktop, const char *category)
|
|
{
|
|
EINA_SAFETY_ON_NULL_RETURN(desktop);
|
|
EINA_SAFETY_ON_NULL_RETURN(category);
|
|
|
|
if (eina_list_search_unsorted(desktop->categories,
|
|
EINA_COMPARE_CB(strcmp), category)) return;
|
|
|
|
desktop->categories = eina_list_append(desktop->categories,
|
|
(void *)eina_stringshare_add(category));
|
|
}
|
|
|
|
EAPI int
|
|
efreet_desktop_category_del(Efreet_Desktop *desktop, const char *category)
|
|
{
|
|
char *found = NULL;
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(desktop, 0);
|
|
|
|
if ((found = eina_list_search_unsorted(desktop->categories,
|
|
EINA_COMPARE_CB(strcmp), category)))
|
|
{
|
|
eina_stringshare_del(found);
|
|
desktop->categories = eina_list_remove(desktop->categories, found);
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
EAPI int
|
|
efreet_desktop_type_add(const char *type, Efreet_Desktop_Type_Parse_Cb parse_func,
|
|
Efreet_Desktop_Type_Save_Cb save_func,
|
|
Efreet_Desktop_Type_Free_Cb free_func)
|
|
{
|
|
int id;
|
|
Efreet_Desktop_Type_Info *info;
|
|
|
|
info = NEW(Efreet_Desktop_Type_Info, 1);
|
|
if (!info) return 0;
|
|
|
|
id = eina_list_count(efreet_desktop_types);
|
|
|
|
info->id = id;
|
|
info->type = eina_stringshare_add(type);
|
|
info->parse_func = parse_func;
|
|
info->save_func = save_func;
|
|
info->free_func = free_func;
|
|
|
|
efreet_desktop_types = eina_list_append(efreet_desktop_types, info);
|
|
|
|
return id;
|
|
}
|
|
|
|
EAPI int
|
|
efreet_desktop_type_alias(int from_type, const char *alias)
|
|
{
|
|
Efreet_Desktop_Type_Info *info;
|
|
info = eina_list_nth(efreet_desktop_types, from_type);
|
|
if (!info) return -1;
|
|
|
|
return efreet_desktop_type_add(alias, info->parse_func, info->save_func, info->free_func);
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
efreet_desktop_x_field_set(Efreet_Desktop *desktop, const char *key, const char *data)
|
|
{
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(desktop, EINA_FALSE);
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(strncmp(key, "X-", 2), EINA_FALSE);
|
|
|
|
if (!desktop->x)
|
|
desktop->x = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
|
|
|
|
eina_hash_del_by_key(desktop->x, key);
|
|
eina_hash_add(desktop->x, key, eina_stringshare_add(data));
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI const char *
|
|
efreet_desktop_x_field_get(Efreet_Desktop *desktop, const char *key)
|
|
{
|
|
const char *ret;
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(desktop, NULL);
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(desktop->x, NULL);
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(strncmp(key, "X-", 2), NULL);
|
|
|
|
ret = eina_hash_find(desktop->x, key);
|
|
if (!ret)
|
|
return NULL;
|
|
|
|
return eina_stringshare_add(ret);
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
efreet_desktop_x_field_del(Efreet_Desktop *desktop, const char *key)
|
|
{
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(desktop, EINA_FALSE);
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(strncmp(key, "X-", 2), EINA_FALSE);
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(desktop->x, EINA_FALSE);
|
|
|
|
return eina_hash_del_by_key(desktop->x, key);
|
|
}
|
|
|
|
EAPI void *
|
|
efreet_desktop_type_data_get(Efreet_Desktop *desktop)
|
|
{
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(desktop, NULL);
|
|
return desktop->type_data;
|
|
}
|
|
|
|
EAPI Eina_List *
|
|
efreet_desktop_string_list_parse(const char *string)
|
|
{
|
|
Eina_List *list = NULL;
|
|
char *tmp;
|
|
char *s, *p;
|
|
size_t len;
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(string, NULL);
|
|
|
|
len = strlen(string) + 1;
|
|
tmp = alloca(len);
|
|
memcpy(tmp, string, len);
|
|
s = tmp;
|
|
|
|
while ((p = strchr(s, ';')))
|
|
{
|
|
if (p > tmp && *(p-1) == '\\') continue;
|
|
*p = '\0';
|
|
list = eina_list_append(list, (void *)eina_stringshare_add(s));
|
|
s = p + 1;
|
|
}
|
|
/* If this is true, the .desktop file does not follow the standard */
|
|
if (*s)
|
|
{
|
|
#ifdef STRICT_SPEC
|
|
WRN("[Efreet]: Found a string list without ';' "
|
|
"at the end: %s", string);
|
|
#endif
|
|
list = eina_list_append(list, (void *)eina_stringshare_add(s));
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
EAPI char *
|
|
efreet_desktop_string_list_join(Eina_List *list)
|
|
{
|
|
Eina_List *l;
|
|
const char *elem;
|
|
char *string;
|
|
size_t size, pos, len;
|
|
|
|
if (!list) return strdup("");
|
|
|
|
size = 1024;
|
|
string = malloc(size);
|
|
if (!string) return NULL;
|
|
pos = 0;
|
|
|
|
EINA_LIST_FOREACH(list, l, elem)
|
|
{
|
|
len = strlen(elem);
|
|
/* +1 for ';' */
|
|
if ((len + pos + 1) >= size)
|
|
{
|
|
char *tmp;
|
|
size = len + pos + 1024;
|
|
tmp = realloc(string, size);
|
|
if (!tmp)
|
|
{
|
|
free(string);
|
|
return NULL;
|
|
}
|
|
string = tmp;
|
|
}
|
|
strcpy(string + pos, elem);
|
|
pos += len;
|
|
strcpy(string + pos, ";");
|
|
pos += 1;
|
|
}
|
|
return string;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* @param desktop The desktop to fill
|
|
* @return Returns 1 on success, 0 on failure
|
|
* @brief initialize an Efreet_Desktop from the contents of @a file
|
|
*/
|
|
static int
|
|
efreet_desktop_read(Efreet_Desktop *desktop)
|
|
{
|
|
Efreet_Ini *ini;
|
|
int error = 0;
|
|
int ok;
|
|
|
|
ini = efreet_ini_new(desktop->orig_path);
|
|
if (!ini) return 0;
|
|
if (!ini->data)
|
|
{
|
|
efreet_ini_free(ini);
|
|
return 0;
|
|
}
|
|
|
|
ok = efreet_ini_section_set(ini, "Desktop Entry");
|
|
if (!ok) ok = efreet_ini_section_set(ini, "KDE Desktop Entry");
|
|
if (!ok)
|
|
{
|
|
ERR("efreet_desktop_new error: no Desktop Entry section");
|
|
error = 1;
|
|
}
|
|
|
|
if (!error)
|
|
{
|
|
Efreet_Desktop_Type_Info *info;
|
|
|
|
info = efreet_desktop_type_parse(efreet_ini_string_get(ini, "Type"));
|
|
if (info)
|
|
{
|
|
const char *val;
|
|
|
|
desktop->type = info->id;
|
|
val = efreet_ini_string_get(ini, "Version");
|
|
if (val) desktop->version = strdup(val);
|
|
|
|
if (info->parse_func)
|
|
desktop->type_data = info->parse_func(desktop, ini);
|
|
}
|
|
else
|
|
error = 1;
|
|
}
|
|
|
|
if (!error && !efreet_desktop_generic_fields_parse(desktop, ini)) error = 1;
|
|
if (!error && !efreet_desktop_environment_check(desktop)) error = 1;
|
|
if (!error)
|
|
eina_hash_foreach(ini->section, efreet_desktop_x_fields_parse, desktop);
|
|
|
|
efreet_ini_free(ini);
|
|
|
|
desktop->load_time = ecore_file_mod_time(desktop->orig_path);
|
|
|
|
if (error) return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* @param type_str the type as a string
|
|
* @return the parsed type
|
|
* @brief parse the type string into an Efreet_Desktop_Type
|
|
*/
|
|
static Efreet_Desktop_Type_Info *
|
|
efreet_desktop_type_parse(const char *type_str)
|
|
{
|
|
Efreet_Desktop_Type_Info *info;
|
|
Eina_List *l;
|
|
|
|
if (!type_str) return NULL;
|
|
|
|
EINA_LIST_FOREACH(efreet_desktop_types, l, info)
|
|
{
|
|
if (!strcmp(info->type, type_str))
|
|
return info;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* @brief Free an Efreet Desktop_Type_Info struct
|
|
*/
|
|
static void
|
|
efreet_desktop_type_info_free(Efreet_Desktop_Type_Info *info)
|
|
{
|
|
if (!info) return;
|
|
IF_RELEASE(info->type);
|
|
free(info);
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* @param desktop the Efreet_Desktop to store parsed fields in
|
|
* @param ini the Efreet_Ini to parse fields from
|
|
* @return No value
|
|
* @brief Parse application specific desktop fields
|
|
*/
|
|
static void *
|
|
efreet_desktop_application_fields_parse(Efreet_Desktop *desktop, Efreet_Ini *ini)
|
|
{
|
|
const char *val;
|
|
|
|
val = efreet_ini_string_get(ini, "TryExec");
|
|
if (val) desktop->try_exec = strdup(val);
|
|
|
|
val = efreet_ini_string_get(ini, "Exec");
|
|
if (val) desktop->exec = strdup(val);
|
|
|
|
val = efreet_ini_string_get(ini, "Path");
|
|
if (val) desktop->path = strdup(val);
|
|
|
|
val = efreet_ini_string_get(ini, "StartupWMClass");
|
|
if (val) desktop->startup_wm_class = strdup(val);
|
|
|
|
val = efreet_ini_string_get(ini, "Categories");
|
|
if (val)
|
|
desktop->categories = efreet_desktop_string_list_parse(val);
|
|
val = efreet_ini_string_get(ini, "MimeType");
|
|
if (val) desktop->mime_types = efreet_desktop_string_list_parse(val);
|
|
|
|
desktop->terminal = efreet_ini_boolean_get(ini, "Terminal");
|
|
desktop->startup_notify = efreet_ini_boolean_get(ini, "StartupNotify");
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* @param desktop the Efreet_Desktop to save fields from
|
|
* @param ini the Efreet_Ini to save fields to
|
|
* @return Returns no value
|
|
* @brief Save application specific desktop fields
|
|
*/
|
|
static void
|
|
efreet_desktop_application_fields_save(Efreet_Desktop *desktop, Efreet_Ini *ini)
|
|
{
|
|
char *val;
|
|
|
|
if (desktop->try_exec)
|
|
efreet_ini_string_set(ini, "TryExec", desktop->try_exec);
|
|
|
|
if (desktop->exec)
|
|
efreet_ini_string_set(ini, "Exec", desktop->exec);
|
|
|
|
if (desktop->path)
|
|
efreet_ini_string_set(ini, "Path", desktop->path);
|
|
|
|
if (desktop->startup_wm_class)
|
|
efreet_ini_string_set(ini, "StartupWMClass", desktop->startup_wm_class);
|
|
|
|
if (desktop->categories)
|
|
{
|
|
val = efreet_desktop_string_list_join(desktop->categories);
|
|
if (val)
|
|
{
|
|
efreet_ini_string_set(ini, "Categories", val);
|
|
FREE(val);
|
|
}
|
|
}
|
|
|
|
if (desktop->mime_types)
|
|
{
|
|
val = efreet_desktop_string_list_join(desktop->mime_types);
|
|
if (val)
|
|
{
|
|
efreet_ini_string_set(ini, "MimeType", val);
|
|
FREE(val);
|
|
}
|
|
}
|
|
|
|
efreet_ini_boolean_set(ini, "Terminal", desktop->terminal);
|
|
efreet_ini_boolean_set(ini, "StartupNotify", desktop->startup_notify);
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* @param desktop the Efreet_Desktop to store parsed fields in
|
|
* @param ini the Efreet_Ini to parse fields from
|
|
* @return Returns no value
|
|
* @brief Parse link specific desktop fields
|
|
*/
|
|
static void *
|
|
efreet_desktop_link_fields_parse(Efreet_Desktop *desktop, Efreet_Ini *ini)
|
|
{
|
|
const char *val;
|
|
|
|
val = efreet_ini_string_get(ini, "URL");
|
|
if (val) desktop->url = strdup(val);
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* @param desktop the Efreet_Desktop to save fields from
|
|
* @param ini the Efreet_Ini to save fields in
|
|
* @return Returns no value
|
|
* @brief Save link specific desktop fields
|
|
*/
|
|
static void
|
|
efreet_desktop_link_fields_save(Efreet_Desktop *desktop, Efreet_Ini *ini)
|
|
{
|
|
if (desktop->url) efreet_ini_string_set(ini, "URL", desktop->url);
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* @param desktop the Efreet_Desktop to store parsed fields in
|
|
* @param ini the Efreet_Ini to parse fields from
|
|
* @return 1 if parsed successfully, 0 otherwise
|
|
* @brief Parse desktop fields that all types can include
|
|
*/
|
|
static int
|
|
efreet_desktop_generic_fields_parse(Efreet_Desktop *desktop, Efreet_Ini *ini)
|
|
{
|
|
const char *val;
|
|
const char *not_show_in = NULL, *only_show_in = NULL;
|
|
|
|
val = efreet_ini_localestring_get(ini, "Name");
|
|
#ifndef STRICT_SPEC
|
|
if (!val) val = efreet_ini_localestring_get(ini, "_Name");
|
|
#endif
|
|
if (val) desktop->name = strdup(val);
|
|
else
|
|
{
|
|
ERR("efreet_desktop_generic_fields_parse error: no Name or _Name fields");
|
|
return 0;
|
|
}
|
|
|
|
val = efreet_ini_localestring_get(ini, "GenericName");
|
|
if (val) desktop->generic_name = strdup(val);
|
|
|
|
val = efreet_ini_localestring_get(ini, "Comment");
|
|
#ifndef STRICT_SPEC
|
|
if (!val) val = efreet_ini_localestring_get(ini, "_Comment");
|
|
#endif
|
|
if (val) desktop->comment = strdup(val);
|
|
|
|
val = efreet_ini_localestring_get(ini, "Icon");
|
|
if (val) desktop->icon = strdup(val);
|
|
|
|
desktop->no_display = efreet_ini_boolean_get(ini, "NoDisplay");
|
|
desktop->hidden = efreet_ini_boolean_get(ini, "Hidden");
|
|
|
|
only_show_in = efreet_ini_string_get(ini, "OnlyShowIn");
|
|
not_show_in = efreet_ini_string_get(ini, "NotShowIn");
|
|
if (only_show_in && not_show_in)
|
|
WRN("Both OnlyShowIn and NotShowIn in %s, preferring OnlyShowIn", desktop->orig_path);
|
|
if (only_show_in) desktop->only_show_in = efreet_desktop_string_list_parse(only_show_in);
|
|
else if (not_show_in) desktop->not_show_in = efreet_desktop_string_list_parse(not_show_in);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* @param desktop the Efreet_Desktop to save fields from
|
|
* @param ini the Efreet_Ini to save fields to
|
|
* @return Returns nothing
|
|
* @brief Save desktop fields that all types can include
|
|
*/
|
|
static void
|
|
efreet_desktop_generic_fields_save(Efreet_Desktop *desktop, Efreet_Ini *ini)
|
|
{
|
|
const char *val;
|
|
|
|
if (desktop->name)
|
|
{
|
|
efreet_ini_localestring_set(ini, "Name", desktop->name);
|
|
val = efreet_ini_string_get(ini, "Name");
|
|
if (!val)
|
|
efreet_ini_string_set(ini, "Name", desktop->name);
|
|
}
|
|
if (desktop->generic_name)
|
|
{
|
|
efreet_ini_localestring_set(ini, "GenericName", desktop->generic_name);
|
|
val = efreet_ini_string_get(ini, "GenericName");
|
|
if (!val)
|
|
efreet_ini_string_set(ini, "GenericName", desktop->generic_name);
|
|
}
|
|
if (desktop->comment)
|
|
{
|
|
efreet_ini_localestring_set(ini, "Comment", desktop->comment);
|
|
val = efreet_ini_string_get(ini, "Comment");
|
|
if (!val)
|
|
efreet_ini_string_set(ini, "Comment", desktop->comment);
|
|
}
|
|
if (desktop->icon)
|
|
{
|
|
efreet_ini_localestring_set(ini, "Icon", desktop->icon);
|
|
val = efreet_ini_string_get(ini, "Icon");
|
|
if (!val)
|
|
efreet_ini_string_set(ini, "Icon", desktop->icon);
|
|
}
|
|
|
|
efreet_ini_boolean_set(ini, "NoDisplay", desktop->no_display);
|
|
efreet_ini_boolean_set(ini, "Hidden", desktop->hidden);
|
|
|
|
if (desktop->x) eina_hash_foreach(desktop->x, efreet_desktop_x_fields_save,
|
|
ini);
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* @param node The node to work with
|
|
* @param desktop The desktop file to work with
|
|
* @return Returns always true, to be used in eina_hash_foreach()
|
|
* @brief Parses out an X- key from @a node and stores in @a desktop
|
|
*/
|
|
static Eina_Bool
|
|
efreet_desktop_x_fields_parse(const Eina_Hash *hash __UNUSED__, const void *key, void *value, void *fdata)
|
|
{
|
|
Efreet_Desktop * desktop = fdata;
|
|
|
|
if (!desktop) return EINA_TRUE;
|
|
if (strncmp(key, "X-", 2)) return EINA_TRUE;
|
|
|
|
if (!desktop->x)
|
|
desktop->x = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
|
|
eina_hash_del_by_key(desktop->x, key);
|
|
eina_hash_add(desktop->x, key, (void *)eina_stringshare_add(value));
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* @param node The node to work with
|
|
* @param ini The ini file to work with
|
|
* @return Returns no value
|
|
* @brief Stores an X- key from @a node and stores in @a ini
|
|
*/
|
|
static Eina_Bool
|
|
efreet_desktop_x_fields_save(const Eina_Hash *hash __UNUSED__, const void *key, void *value, void *fdata)
|
|
{
|
|
Efreet_Ini *ini = fdata;
|
|
efreet_ini_string_set(ini, key, value);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
|
|
/**
|
|
* @internal
|
|
* @param ini The Efreet_Ini to parse values from
|
|
* @return 1 if desktop should be included in current environement, 0 otherwise
|
|
* @brief Determines if a desktop should be included in the current environment,
|
|
* based on the values of the OnlyShowIn and NotShowIn fields
|
|
*/
|
|
static int
|
|
efreet_desktop_environment_check(Efreet_Desktop *desktop)
|
|
{
|
|
Eina_List *list;
|
|
int found = 0;
|
|
char *val;
|
|
|
|
if (!desktop_environment)
|
|
{
|
|
//if (desktop->only_show_in) return 0;
|
|
return 1;
|
|
}
|
|
|
|
if (desktop->only_show_in)
|
|
{
|
|
EINA_LIST_FOREACH(desktop->only_show_in, list, val)
|
|
{
|
|
if (!strcmp(val, desktop_environment))
|
|
{
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
return found;
|
|
}
|
|
|
|
|
|
if (desktop->not_show_in)
|
|
{
|
|
EINA_LIST_FOREACH(desktop->not_show_in, list, val)
|
|
{
|
|
if (!strcmp(val, desktop_environment))
|
|
{
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
return !found;
|
|
}
|
|
|
|
return 1;
|
|
}
|