diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index 746573938..eb914f42f 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -28,6 +28,7 @@ #include "e_place.h" #include "e_resist.h" #include "e_startup.h" +#include "e_state.h" #include "e_signals.h" #include "e_xinerama.h" #include "e_layout.h" diff --git a/src/bin/e_main.c b/src/bin/e_main.c index 5fff4e13d..521ab5a76 100644 --- a/src/bin/e_main.c +++ b/src/bin/e_main.c @@ -698,6 +698,11 @@ main(int argc, char **argv) TS("E_Ipc Init Done"); _e_main_shutdown_push(e_ipc_shutdown); + TS("E_State Init"); + e_state_init(); + TS("E_State Init Done"); + _e_main_shutdown_push(e_state_shutdown); + TS("E_Font Init"); if (!e_font_init()) { diff --git a/src/bin/e_state.c b/src/bin/e_state.c new file mode 100644 index 000000000..e66552517 --- /dev/null +++ b/src/bin/e_state.c @@ -0,0 +1,249 @@ +#include "e.h" + +/* public variables */ +E_API int E_EVENT_STATE_CHANGE = 0; + +static Eina_Hash *_e_state_items = NULL; + +static void +_state_item_free(void *data) +{ + E_State_Item *it = data; + + if (it->name) eina_stringshare_del(it->name); + if (it->type == E_STATE_STRING) eina_stringshare_del(it->val.s); + free(data); +} + +static void +_state_event_free(void *data EINA_UNUSED, void *ev) +{ + E_Event_State *e = ev; + + if (e->item.name) eina_stringshare_del(e->item.name); + if (e->item.type == E_STATE_STRING) eina_stringshare_del(e->item.val.s); + free(e); +} + +/* public functions */ +EINTERN int +e_state_init(void) +{ + E_EVENT_STATE_CHANGE = ecore_event_type_new(); + + _e_state_items = eina_hash_string_superfast_new(_state_item_free); + + return 1; +} + +EINTERN int +e_state_shutdown(void) +{ + E_FREE_FUNC(_e_state_items, eina_hash_free); + return 1; +} + +E_API E_State_Item +e_state_item_get(const char *name) +{ + E_State_Item it = { NULL, E_STATE_UNKNOWN, { 0 } }; + E_State_Item *it2 = eina_hash_find(_e_state_items, name); + + if (it2) it = *it2; + return it; +} + +E_API void +e_state_item_set(E_State_Item it) +{ + E_State_Item *it2 = eina_hash_find(_e_state_items, it.name); + Eina_Bool changed = EINA_FALSE; + + if (!it2) + { + it2 = calloc(1, sizeof(E_State_Item)); + if (!it2) return; + it2->name = eina_stringshare_add(it.name); + eina_hash_add(_e_state_items, it2->name, it2); + changed = EINA_TRUE; + } + if (!changed) + { + if (it2->type != it.type) changed = EINA_TRUE; + } + if (!changed) + { + switch (it2->type) + { + case E_STATE_UNKNOWN: + changed = EINA_TRUE; + break; + case E_STATE_BOOL: + if (it2->val.b != it.val.b) changed = EINA_TRUE; + break; + case E_STATE_INT: + if (it2->val.i != it.val.i) changed = EINA_TRUE; + break; + case E_STATE_UINT: + if (it2->val.u != it.val.u) changed = EINA_TRUE; + break; + case E_STATE_DOUBLE: + if (!EINA_FLT_EQ(it2->val.d, it.val.d)) changed = EINA_TRUE; + break; + case E_STATE_STRING: + if (!((it2->val.s) && (it.val.s) && + (!strcmp(it2->val.s, it.val.s)))) + changed = EINA_TRUE; + break; + default: + break; + } + } + if (changed) + { + E_Event_State *e; + + if (it2->type == E_STATE_STRING) + { + eina_stringshare_del(it2->val.s); + it2->val.s = NULL; + } + it2->type = it.type; + if (it2->type == E_STATE_STRING) + it2->val.s = eina_stringshare_add(it.val.s); + else + it2->val = it.val; + e = calloc(1, sizeof(E_Event_State)); + if (e) + { + e->event = E_STATE_CHANGE; + e->item = *it2; + e->item.name = eina_stringshare_add(e->item.name); + if (e->item.type == E_STATE_STRING) + e->item.val.s = eina_stringshare_add(e->item.val.s); + ecore_event_add(E_EVENT_STATE_CHANGE, e, _state_event_free, NULL); + } + } +} + +E_API void +e_state_item_del(const char *name) +{ + E_State_Item *it2 = eina_hash_find(_e_state_items, name); + + if (it2) + { + E_Event_State *e = calloc(1, sizeof(E_Event_State)); + + if (e) + { + e->event = E_STATE_DEL; + e->item = *it2; + e->item.name = eina_stringshare_add(e->item.name); + if (e->item.type == E_STATE_STRING) + e->item.val.s = eina_stringshare_add(e->item.val.s); + ecore_event_add(E_EVENT_STATE_CHANGE, e, _state_event_free, NULL); + } + eina_hash_del_by_key(_e_state_items, name); + } +} + +E_API Eina_Bool +e_state_item_val_bool_get(const char *name) +{ + E_State_Item it = e_state_item_get(name); + + if (it.type != E_STATE_BOOL) return EINA_FALSE; + return it.val.b; +} + +E_API int +e_state_item_val_int_get(const char *name) +{ + E_State_Item it = e_state_item_get(name); + + if (it.type != E_STATE_INT) return 0; + return it.val.i; +} + +E_API unsigned int +e_state_item_val_uint_get(const char *name) +{ + E_State_Item it = e_state_item_get(name); + + if (it.type != E_STATE_UINT) return 0; + return it.val.u; +} + +E_API double +e_state_item_val_double_get(const char *name) +{ + E_State_Item it = e_state_item_get(name); + + if (it.type != E_STATE_DOUBLE) return 0.0; + return it.val.d; +} + +E_API const char * +e_state_item_val_string_get(const char *name) +{ + E_State_Item it = e_state_item_get(name); + + if (it.type != E_STATE_STRING) return NULL; + return it.val.s; +} + +E_API void +e_state_item_val_bool_set(const char *name, Eina_Bool b) +{ + E_State_Item it; + + it.name = name; + it.type = E_STATE_BOOL; + it.val.b = b; + e_state_item_set(it); +} + +E_API void +e_state_item_val_int_set(const char *name, int i) +{ + E_State_Item it; + + it.name = name; + it.type = E_STATE_INT; + it.val.i = i; + e_state_item_set(it); +} + +E_API void +e_state_item_val_uint_set(const char *name, unsigned int u) +{ + E_State_Item it; + + it.name = name; + it.type = E_STATE_UINT; + it.val.u = u; + e_state_item_set(it); +} + +E_API void +e_state_item_val_double_set(const char *name, double d) +{ + E_State_Item it; + + it.name = name; + it.type = E_STATE_DOUBLE; + it.val.d = d; + e_state_item_set(it); +} + +E_API void +e_state_item_val_string_set(const char *name, const char *s) +{ + E_State_Item it; + + it.name = name; + it.type = E_STATE_STRING; + it.val.s = s; + e_state_item_set(it); +} diff --git a/src/bin/e_state.h b/src/bin/e_state.h new file mode 100644 index 000000000..04e8a4bdd --- /dev/null +++ b/src/bin/e_state.h @@ -0,0 +1,73 @@ +#ifdef E_TYPEDEFS + +/* struct used to pass to event handlers */ +typedef struct _E_Event_State E_Event_State; + +typedef struct _E_State_Item E_State_Item; +typedef union _E_State_Val E_State_Val; + +typedef enum +{ + E_STATE_UNKNOWN, + E_STATE_BOOL, + E_STATE_INT, + E_STATE_UINT, + E_STATE_DOUBLE, + E_STATE_STRING +} E_State_Type; + +typedef enum +{ + E_STATE_CHANGE, + E_STATE_DEL +} E_State_Event; + +#else +# ifndef E_STATE_H +# define E_STATE_H + +union _E_State_Val +{ + Eina_Bool b; + int i; + unsigned int u; + double d; + const char *s; +}; + +struct _E_State_Item +{ + const char *name; + E_State_Type type; + E_State_Val val; +}; + +struct _E_Event_State +{ + E_State_Event event; + E_State_Item item; +}; + +EINTERN int e_state_init(void); +EINTERN int e_state_shutdown(void); + +E_API E_State_Item e_state_item_get(const char *name); +E_API void e_state_item_set(E_State_Item it); + +E_API void e_state_item_del(const char *name); + +E_API Eina_Bool e_state_item_val_bool_get(const char *name); +E_API int e_state_item_val_int_get(const char *name); +E_API unsigned int e_state_item_val_uint_get(const char *name); +E_API double e_state_item_val_double_get(const char *name); +E_API const char *e_state_item_val_string_get(const char *name); +E_API void e_state_item_val_bool_set(const char *name, Eina_Bool b); +E_API void e_state_item_val_int_set(const char *name, int i); +E_API void e_state_item_val_uint_set(const char *name, unsigned int u); +E_API void e_state_item_val_double_set(const char *name, double d); +E_API void e_state_item_val_string_set(const char *name, const char *s); + +extern E_API int E_EVENT_STATE_CHANGE; + +# endif +#endif diff --git a/src/bin/meson.build b/src/bin/meson.build index 8f773ed89..ebffff5b4 100644 --- a/src/bin/meson.build +++ b/src/bin/meson.build @@ -181,6 +181,7 @@ src = [ 'e_slidesel.c', 'e_spectrum.c', 'e_startup.c', + 'e_state.c', 'e_sys.c', 'e_system.c', 'e_test.c', @@ -361,6 +362,7 @@ hdr = [ 'e_slidesel.h', 'e_spectrum.h', 'e_startup.h', + 'e_state.h', 'e_sys.h', 'e_system.h', 'e_test.h',