/src/lib/evas/canvas/evas_smart.c
https://bitbucket.org/hchbaw/efl · C · 332 lines · 265 code · 61 blank · 6 comment · 54 complexity · e13aa02c4a62398a641d69d41a17f0ec MD5 · raw file
- #include "evas_common_private.h"
- #include "evas_private.h"
- static void _evas_smart_class_callbacks_create(Evas_Smart *s);
- static void _evas_smart_class_interfaces_create(Evas_Smart *s);
- /* all public */
- EAPI void
- evas_smart_free(Evas_Smart *s)
- {
- MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
- return;
- MAGIC_CHECK_END();
- s->delete_me = 1;
- if (s->usage > 0) return;
- if (s->class_allocated) free((void *)s->smart_class);
- free(s->callbacks.array);
- free(s->interfaces.array);
- free(s);
- }
- EAPI Evas_Smart *
- evas_smart_class_new(const Evas_Smart_Class *sc)
- {
- Evas_Smart *s;
- if (!sc) return NULL;
- /* api does not match abi! for now refuse as we only have 1 version */
- if (sc->version != EVAS_SMART_CLASS_VERSION) return NULL;
- s = evas_mem_calloc(sizeof(Evas_Smart));
- if (!s) return NULL;
- s->magic = MAGIC_SMART;
- s->smart_class = sc;
- _evas_smart_class_callbacks_create(s);
- _evas_smart_class_interfaces_create(s);
- return s;
- }
- EAPI const Evas_Smart_Class *
- evas_smart_class_get(const Evas_Smart *s)
- {
- MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
- return NULL;
- MAGIC_CHECK_END();
- return s->smart_class;
- }
- EAPI void *
- evas_smart_data_get(const Evas_Smart *s)
- {
- MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
- return NULL;
- MAGIC_CHECK_END();
- return (void *)s->smart_class->data;
- }
- EAPI const Evas_Smart_Cb_Description **
- evas_smart_callbacks_descriptions_get(const Evas_Smart *s, unsigned int *count)
- {
- MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
- if (count) *count = 0;
- return NULL;
- MAGIC_CHECK_END();
- if (count) *count = s->callbacks.size;
- return s->callbacks.array;
- }
- EAPI const Evas_Smart_Cb_Description *
- evas_smart_callback_description_find(const Evas_Smart *s, const char *name)
- {
- if (!name) return NULL;
- MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
- return NULL;
- MAGIC_CHECK_END();
- return evas_smart_cb_description_find(&s->callbacks, name);
- }
- EAPI Eina_Bool
- evas_smart_class_inherit_full(Evas_Smart_Class *sc, const Evas_Smart_Class *parent_sc, unsigned int parent_sc_size)
- {
- unsigned int off;
- /* api does not match abi! for now refuse as we only have 1 version */
- if (parent_sc->version != EVAS_SMART_CLASS_VERSION) return EINA_FALSE;
- #define _CP(m) sc->m = parent_sc->m
- _CP(add);
- _CP(del);
- _CP(move);
- _CP(resize);
- _CP(show);
- _CP(hide);
- _CP(color_set);
- _CP(clip_set);
- _CP(clip_unset);
- _CP(calculate);
- _CP(member_add);
- _CP(member_del);
- #undef _CP
- sc->parent = parent_sc;
- off = sizeof(Evas_Smart_Class);
- if (parent_sc_size == off) return EINA_TRUE;
- memcpy(((char *)sc) + off, ((char *)parent_sc) + off, parent_sc_size - off);
- return EINA_TRUE;
- }
- EAPI int
- evas_smart_usage_get(const Evas_Smart *s)
- {
- MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
- return 0;
- MAGIC_CHECK_END();
- return s->usage;
- }
- /* internal funcs */
- void
- evas_object_smart_use(Evas_Smart *s)
- {
- s->usage++;
- }
- void
- evas_object_smart_unuse(Evas_Smart *s)
- {
- s->usage--;
- if ((s->usage <= 0) && (s->delete_me)) evas_smart_free(s);
- }
- Eina_Bool
- evas_smart_cb_descriptions_resize(Evas_Smart_Cb_Description_Array *a, unsigned int size)
- {
- void *tmp;
- if (size == a->size)
- return EINA_TRUE;
- if (size == EINA_FALSE)
- {
- free(a->array);
- a->array = NULL;
- a->size = 0;
- return EINA_TRUE;
- }
- tmp = realloc(a->array, (size + 1) * sizeof(Evas_Smart_Cb_Description *));
- if (tmp)
- {
- a->array = tmp;
- a->size = size;
- a->array[size] = NULL;
- return EINA_TRUE;
- }
- else
- {
- ERR("realloc failed!");
- return EINA_FALSE;
- }
- }
- static int
- _evas_smart_cb_description_cmp_sort(const void *p1, const void *p2)
- {
- const Evas_Smart_Cb_Description **a = (const Evas_Smart_Cb_Description **)p1;
- const Evas_Smart_Cb_Description **b = (const Evas_Smart_Cb_Description **)p2;
- return strcmp((*a)->name, (*b)->name);
- }
- void
- evas_smart_cb_descriptions_fix(Evas_Smart_Cb_Description_Array *a)
- {
- unsigned int i, j;
- if (!a)
- {
- ERR("no array to fix!");
- return;
- }
- qsort(a->array, a->size, sizeof(Evas_Smart_Cb_Description *),
- _evas_smart_cb_description_cmp_sort);
- DBG("%u callbacks", a->size);
- if (a->size)
- DBG("%s [type=%s]", a->array[0]->name, a->array[0]->type);
- for (i = 0, j = 1; j < a->size; j++)
- {
- const Evas_Smart_Cb_Description *cur, *prev;
- cur = a->array[j];
- prev = a->array[i];
- DBG("%s [type=%s]", cur->name, cur->type);
- if (strcmp(cur->name, prev->name) != 0)
- {
- i++;
- if (i != j)
- a->array[i] = a->array[j];
- }
- else
- {
- if (strcmp(cur->type, prev->type) == 0)
- WRN("duplicated smart callback description"
- " with name '%s' and type '%s'", cur->name, cur->type);
- else
- ERR("callback descriptions named '%s' differ"
- " in type, keeping '%s', ignoring '%s'",
- cur->name, prev->type, cur->type);
- }
- }
- evas_smart_cb_descriptions_resize(a, i + 1);
- }
- static void
- _evas_smart_class_callbacks_create(Evas_Smart *s)
- {
- const Evas_Smart_Class *sc;
- unsigned int n = 0;
- for (sc = s->smart_class; sc; sc = sc->parent)
- {
- const Evas_Smart_Cb_Description *d;
- for (d = sc->callbacks; d && d->name; d++)
- n++;
- }
- if (n == 0) return;
- if (!evas_smart_cb_descriptions_resize(&s->callbacks, n)) return;
- s->callbacks.size = n;
- for (n = 0, sc = s->smart_class; sc; sc = sc->parent)
- {
- const Evas_Smart_Cb_Description *d;
- for (d = sc->callbacks; d && d->name; d++)
- s->callbacks.array[n++] = d;
- }
- evas_smart_cb_descriptions_fix(&s->callbacks);
- }
- static void
- _evas_smart_class_interfaces_create(Evas_Smart *s)
- {
- unsigned int i, total_priv_sz = 0;
- const Evas_Smart_Class *sc;
- /* get number of interfaces on the smart */
- for (i = 0, sc = s->smart_class; sc; sc = sc->parent)
- {
- const Evas_Smart_Interface **ifaces_array = sc->interfaces;
- if (!ifaces_array) continue;
- while (*ifaces_array)
- {
- const Evas_Smart_Interface *iface = *ifaces_array;
- if (!iface->name) break;
- i++;
- if (iface->private_size > 0)
- {
- unsigned int size = iface->private_size;
- if (size % sizeof(void *) != 0)
- size += sizeof(void *) - (size % sizeof(void *));
- total_priv_sz += size;
- }
- ifaces_array++;
- }
- }
- if (!i) return;
- s->interfaces.array = malloc(i * sizeof(Evas_Smart_Interface *));
- if (!s->interfaces.array)
- {
- ERR("malloc failed!");
- return;
- }
- s->interfaces.size = i;
- for (i = 0, sc = s->smart_class; sc; sc = sc->parent)
- {
- const Evas_Smart_Interface **ifaces_array = sc->interfaces;
- if (!ifaces_array) continue;
- while (*ifaces_array)
- {
- const Evas_Smart_Interface *iface = *ifaces_array;
- if (!iface->name) break;
- s->interfaces.array[i++] = iface;
- ifaces_array++;
- }
- }
- }
- static int
- _evas_smart_cb_description_cmp_search(const void *p1, const void *p2)
- {
- const char *name = p1;
- const Evas_Smart_Cb_Description **v = (const Evas_Smart_Cb_Description **)p2;
- /* speed up string shares searches (same pointers) */
- if (name == (*v)->name) return 0;
- return strcmp(name, (*v)->name);
- }
- const Evas_Smart_Cb_Description *
- evas_smart_cb_description_find(const Evas_Smart_Cb_Description_Array *a, const char *name)
- {
- if (!a->array) return NULL;
- return bsearch(name, a->array, a->size, sizeof(Evas_Smart_Cb_Description *),
- _evas_smart_cb_description_cmp_search);
- }