aboutsummaryrefslogtreecommitdiffstats
path: root/egraph
diff options
context:
space:
mode:
authorLaurent Ghigonis <laurent@p1sec.com>2013-02-27 19:44:58 +0100
committerLaurent Ghigonis <laurent@p1sec.com>2013-02-27 19:44:58 +0100
commitd21bb7f6b5df682c2b41ad47a63c1dc6da0bcce2 (patch)
treebd0a2c7597f909b813e0d5ce011b59644edb4c99 /egraph
parentadd authors and license (diff)
parentlockup ++ (diff)
downloadglouglou-d21bb7f6b5df682c2b41ad47a63c1dc6da0bcce2.tar.xz
glouglou-d21bb7f6b5df682c2b41ad47a63c1dc6da0bcce2.zip
Merge egraph repository in glouglou repository
Diffstat (limited to 'egraph')
-rw-r--r--egraph/AUTHORS1
-rw-r--r--egraph/COPYING15
-rw-r--r--egraph/Egraph.h233
-rw-r--r--egraph/Makefile38
-rw-r--r--egraph/README47
-rw-r--r--egraph/data/blob.pngbin0 -> 3649 bytes
-rw-r--r--egraph/data/edge.pngbin0 -> 372 bytes
-rw-r--r--egraph/data/edge.xcfbin0 -> 8278 bytes
-rw-r--r--egraph/data/vertice.pngbin0 -> 4488 bytes
-rw-r--r--egraph/doc/TODO.txt118
-rw-r--r--egraph/doc/bug_lockup_evas.txt646
-rw-r--r--egraph/doc/egraph.xojbin0 -> 105411 bytes
-rw-r--r--egraph/doc/internals.txt89
-rw-r--r--egraph/egraph.c1275
-rw-r--r--egraph/egraph.edc250
-rw-r--r--egraph/examples/Makefile12
-rw-r--r--egraph/examples/demoapp.c371
-rw-r--r--egraph/examples/simplegraph.c59
-rwxr-xr-xegraph/retest.sh9
-rw-r--r--egraph/tests/Makefile32
-rw-r--r--egraph/tests/README.txt4
-rw-r--r--egraph/tests/creategraph.c37
22 files changed, 3236 insertions, 0 deletions
diff --git a/egraph/AUTHORS b/egraph/AUTHORS
new file mode 100644
index 0000000..4e42cdc
--- /dev/null
+++ b/egraph/AUTHORS
@@ -0,0 +1 @@
+Laurent Ghigonis <laurent@p1sec.com>
diff --git a/egraph/COPYING b/egraph/COPYING
new file mode 100644
index 0000000..bae178d
--- /dev/null
+++ b/egraph/COPYING
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2012 Laurent Ghigonis <laurent@p1sec.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
diff --git a/egraph/Egraph.h b/egraph/Egraph.h
new file mode 100644
index 0000000..553d5cd
--- /dev/null
+++ b/egraph/Egraph.h
@@ -0,0 +1,233 @@
+#include <Eina.h>
+#include <Evas.h>
+#include <Ecore.h>
+#include <igraph/igraph.h>
+
+#define EGRAPH_VERTICES_MAX 16384 /* cannot be more that u_int32_t */
+#define EGRAPH_VERTICE_NAME_MAXLEN 60
+
+typedef struct Egraph Egraph;
+typedef struct Egraph_Edge Egraph_Edge;
+typedef struct Egraph_Vertice Egraph_Vertice;
+
+typedef enum {
+ EGRAPH_LAYOUT_GRAPHOPT = 0,
+ EGRAPH_LAYOUT_KAMADAKAWAI = 1,
+ EGRAPH_LAYOUT_FRUCHTERMANREINGOLD = 2,
+} Egraph_Layout;
+#define EGRAPH_LAYOUT_DEFAULT EGRAPH_LAYOUT_GRAPHOPT
+#define EGRAPH_LAYOUTING_IMPROVEMENTS 5
+
+struct Egraph {
+ Evas_Object_Smart_Clipped_Data __clipped_data;
+ Evas_Object *obj;
+ Evas_Object *split_vertice_edge;
+ Evas *evas;
+ int graph_directed;
+ int display_vertices;
+ int display_names;
+ int display_edges;
+ int use_animations;
+ int do_improvements;
+ char *theme_path;
+ int theme_edges;
+ Egraph_Layout layout;
+ struct {
+ Ecore_Thread *thread;
+ int running;
+ int todo;
+ int changes_diff;
+ int improvement; /* special pass to improve the graph layout */
+ } layouting;
+ Eina_Hash *vertices;
+ int vertices_count;
+ u_int32_t vertices_freeids[EGRAPH_VERTICES_MAX];
+ int vertice_max_w;
+ int vertice_max_h;
+ Eina_List *edges;
+ igraph_t graph;
+ int graph_vcount;
+ igraph_matrix_t coords;
+ igraph_t graph2; // XXX remove use of graph here, see _repos()
+ int graph2_vcount;
+ igraph_vector_t graph2_wmin, graph2_wmax, graph2_hmin, graph2_hmax;
+ int graph_wmin, graph_wmax, graph_hmin, graph_hmax;
+ igraph_matrix_t coords2;
+};
+
+struct Egraph_Vertice {
+ u_int32_t id;
+ char *name;
+ char *type;
+ u_int status : 1;
+ Evas_Object *o;
+ Eina_List *edges;
+ Eina_List *blobs_incoming;
+ void *data;
+ u_int is_group : 1;
+ Eina_List *group_vertices; /* used if the vertice is a group */
+ u_int new : 1;
+ u_int v2_new : 1;
+ u_int v2_del : 1;
+ u_int v3_new : 1;
+ u_int v3_del : 1;
+};
+
+struct Egraph_Edge {
+ Egraph_Vertice *a;
+ Egraph_Vertice *b;
+ char *type;
+ Evas_Object *o;
+ u_int o_usetheme : 1;
+ void *data;
+ u_int new : 1;
+ u_int v2_new : 1;
+ u_int v2_del : 1;
+ u_int v3_new : 1;
+ u_int v3_del : 1;
+};
+
+/**
+ * Creates Egraph Evas_Object
+ */
+Evas_Object *egraph_new(Evas *evas, int directed);
+
+/**
+ * Remove all nodes and edges
+ */
+void egraph_clear(Evas_Object *obj);
+
+/**
+ * Configure egraph to use an edje theme
+ */
+void egraph_theme_file_set(Evas_Object *obj, char *path);
+
+/**
+ * Sets if egraph should theme the edges
+ */
+void egraph_theme_edges_set(Evas_Object *obj, int set);
+
+/**
+ * Sets the layout of Egraph
+ */
+void egraph_layout_set(Evas_Object *obj, Egraph_Layout layout);
+
+/**
+ * Configure if Egraph should display vertices
+ */
+void egraph_display_vertices_set(Evas_Object *obj, int set);
+
+/**
+ * Configure if Egraph should display vertices names
+ */
+void egraph_display_names_set(Evas_Object *obj, int set);
+
+/**
+ * Configure if Egraph should display edges
+ */
+void egraph_display_edges_set(Evas_Object *obj, int set);
+
+/**
+ * Configure if Egraph should use animations
+ */
+void egraph_use_animations_set(Evas_Object *obj, int set);
+
+/**
+ * Configure if Egraph should do improvements after a graph change
+ */
+void egraph_do_improvements_set(Evas_Object *obj, int set);
+
+/**
+ * Adds an edge between existing vertices
+ *
+ * @param obj The Egraph object
+ * @param a First vertice
+ * @param b Second vertice
+ * @param data The pointer to attach
+ * @return The new Egraph_Egde object
+ */
+Egraph_Edge *egraph_edge_add(Evas_Object *obj,
+ Egraph_Vertice *a, Egraph_Vertice *b, void *data);
+
+/**
+ * Delete an edge
+ *
+ * Hint: This does not delete vertices
+ */
+void egraph_edge_del(Evas_Object *obj, Egraph_Edge *e);
+
+/**
+ * Sets the type of an edge, to make it appear differently in the graph,
+ * depending on theme
+ */
+void egraph_edge_type_set(Evas_Object *obj,
+ Egraph_Edge *e, const char *type);
+/**
+ * Finds if an edge exists between 2 vertices
+ */
+Egraph_Edge *egraph_edge_find(Evas_Object *obj,
+ Egraph_Vertice *a, Egraph_Vertice *b);
+
+/**
+ * Add a vertice to the graph
+ *
+ * @param obj The Egraph object
+ * @param name The name of the vertice to be displayed. If NULL, no name is
+ * displayed
+ * @param data The pointer to attach
+ */
+Egraph_Vertice *egraph_vertice_add(Evas_Object *obj,
+ const char *name, void *data);
+
+/**
+ * Delete a vertice
+ *
+ * Hint: Also deletes all the edges attached to it
+ *
+ * @param obj The Egraph object
+ * @todo add user callback where edges are deleted
+ */
+void egraph_vertice_del(Evas_Object *obj, Egraph_Vertice *v);
+
+/**
+ * Update the name of a vertice
+ */
+void egraph_vertice_rename(Evas_Object *obj, Egraph_Vertice *v,
+ const char *name);
+
+/**
+ * Sets the type of a vertice, to make it appear differently in the graph,
+ * depending on theme
+ */
+void
+egraph_vertice_type_set(Evas_Object *obj, Egraph_Vertice *v, const char *type);
+
+ /**
+ * Send a blob from vertice to vertice
+ *
+ * A blob is a visual object that will move quickly from the first node to the
+ * second node.
+ */
+void egraph_vertice_send_blob(Evas_Object *obj,
+ Egraph_Vertice *a, Egraph_Vertice *b,
+ int size, u_int32_t color);
+
+/**
+ * Add a group of vertices, for later attaching nodes to it.
+ *
+ * The group is represented by an Egraph_Vertice with special properties.
+ */
+Egraph_Vertice *egraph_group_add(Evas_Object *obj,
+ const char *name, void *data);
+
+/**
+ * Attach a vertice to a group
+ */
+int egraph_group_vertice_attach(Evas_Object *obj,
+ Egraph_Vertice *group, Egraph_Vertice *v);
+
+/**
+ * Detach a vertice from a group
+ */
+void egraph_group_vertice_detach(Evas_Object *obj,
+ Egraph_Vertice *group, Egraph_Vertice *v);
diff --git a/egraph/Makefile b/egraph/Makefile
new file mode 100644
index 0000000..3aa6042
--- /dev/null
+++ b/egraph/Makefile
@@ -0,0 +1,38 @@
+# CFLAGS += -Werror -Wall -O2 -fPIC -shared -g
+CFLAGS += -Werror -Wall -fPIC -shared -g
+CFLAGS += $(shell pkg-config --libs --cflags edje)
+CFLAGS += $(shell pkg-config --libs --cflags efx)
+CFLAGS += $(shell pkg-config --libs --cflags igraph)
+
+PREFIX=/usr/local
+INCLUDEDIR=$(PREFIX)/include
+SHAREDIR=$(PREFIX)/share/egraph
+LIBDIR=$(PREFIX)/lib
+
+SOURCES = egraph.c
+HEADERS = Egraph.h
+EDC = egraph.edc
+EDJ = $(EDC:.edc=.edj)
+OBJECTS = $(SOURCES:.c=.o)
+LIBNAME = libegraph
+TARGET = ${LIBNAME}.so
+
+all: $(TARGET) $(EDJ)
+
+$(TARGET): $(OBJECTS)
+ $(CC) $(CFLAGS) -o $(TARGET) $(OBJECTS)
+
+$(EDJ):
+ edje_cc $(EDC) $(EDJ)
+
+install:
+ @echo "installation of $(LIBNAME)"
+ mkdir -p $(LIBDIR)
+ mkdir -p $(INCLUDEDIR)
+ mkdir -p $(SHAREDIR)
+ install -m 0644 $(TARGET) $(LIBDIR)
+ install -m 0644 $(HEADERS) $(INCLUDEDIR)
+ install -m 0644 $(EDJ) $(SHAREDIR)
+
+clean:
+ rm -f $(TARGET) $(OBJECTS) $(EDJ)
diff --git a/egraph/README b/egraph/README
new file mode 100644
index 0000000..dc4be18
--- /dev/null
+++ b/egraph/README
@@ -0,0 +1,47 @@
+egraph - library for rendring dynamic graphs in evas
+
+Requirements
+============
+
+* Enlightenment Foundation Libraries
+http://www.enlightenment.org
+ * eina
+ * evas
+ * ecore
+ * efx
+
+* igraph v0.6
+http://igraph.sourceforge.net/index.html
+ * for Ubuntu: v0.6 is *not* available in ubuntu packages
+You can download it here :
+http://sourceforge.net/projects/igraph/files/C%20library/0.6/igraph-0.6.tar.gz/download
+ * for Archlinux: yaourt -S igraph
+
+Installation
+============
+
+make
+sudo make install
+
+You can run the demoapp in examples :
+make -C examples
+./examples/demoapp
+
+You can use OpenGL rendering :
+ELM_ENGINE=opengl_x11 ./examples/demoapp
+
+Thanks
+======
+
+Thanks to ntamas (http://sixdegrees.hu/) for her advices on igraph.
+Thanks to cedric for tech advices on evas / edje.
+Thanks to vtorri for tech advices on evas / edje.
+Thanks to zmike for tech advices on efx.
+Thanks to raster for tech advices on evas / elementary.
+Thanks to ludivina for graphical advices.
+
+History
+=======
+
+Egraph was developped for the Glouglou Network Map (gg_map), a tool for
+live computer network visualisation based on the Glouglou framework.
diff --git a/egraph/data/blob.png b/egraph/data/blob.png
new file mode 100644
index 0000000..96e4aff
--- /dev/null
+++ b/egraph/data/blob.png
Binary files differ
diff --git a/egraph/data/edge.png b/egraph/data/edge.png
new file mode 100644
index 0000000..f6bbfc4
--- /dev/null
+++ b/egraph/data/edge.png
Binary files differ
diff --git a/egraph/data/edge.xcf b/egraph/data/edge.xcf
new file mode 100644
index 0000000..9481336
--- /dev/null
+++ b/egraph/data/edge.xcf
Binary files differ
diff --git a/egraph/data/vertice.png b/egraph/data/vertice.png
new file mode 100644
index 0000000..54c556b
--- /dev/null
+++ b/egraph/data/vertice.png
Binary files differ
diff --git a/egraph/doc/TODO.txt b/egraph/doc/TODO.txt
new file mode 100644
index 0000000..beed508
--- /dev/null
+++ b/egraph/doc/TODO.txt
@@ -0,0 +1,118 @@
+CURRENT
+=======
+
+vertice / vertice_text visibility will be broken
+need to implement it in the edje object and send signals
+
+* BUG: show nodes labels does not show old nodes labels
+reproduce: do not show labels, add edges, show label, add edges
+
+* BUG: layer stacking is wrong, edges end up on top of nodes, despite
+eg->split_vertice_edge
+
+* BUG: vertices / vertices text fight for being on top. use evas layers ?
+add 500 edges to reproduce, and watch the nodes
+
+TODO
+====
+
+* missing function declaration for static _color_int_to_rgb()
+* reorder static funcs
+
+* BUG: sometimes when you add nodes during layouting, the graph is broken
+a new edge attaches to the wrong new vertice
+it seems to be always the same node numbers that gets this wrong edge
+
+* BUG: EGRAPH_LAYOUT_FRUCHTERMANREINGOLD is broken when adding many edges
+
+* zoom
+10:16 < glouglou> i want to implement zooming with mouse scroll, do you have some ideas about that ?
+10:16 < zmike> that should be trivial
+10:16 < zmike> just hook mouse wheel and use efx_zoom
+10:18 < glouglou> does efx_zoom resize the objects ?
+10:18 < glouglou> all the graph is one evas smart object
+10:18 < zmike> it does not resize, it just maps
+10:18 < glouglou> that clips everything
+10:18 < zmike> it should work, you can see the elm test is working, and that uses smart objects
+10:18 < glouglou> yeah i want to update the coordinates i guess, not really "zoom"
+10:19 < zmike> hm there's no efx_scale yet, but you could use efx_resize I would think
+10:19 < glouglou> i would prefer to resize / update the coords
+10:19 < glouglou> scale yes, that would be it
+10:19 < glouglou> ok
+10:19 < zmike> just calculate the size you want and use efx_resize
+10:20 < zmike> it will animate the resizing
+
+* blobs
+05:17 < glouglou> cedric: t'as vu dans ma demo les packets qui vont d'une node a l'autre quand les nodes bougent et ben les paquets arrivent a l'ancien endroit
+05:17 < glouglou> j'ai regarde un peu dans efx mais j'ai pas trouve de bon moyen
+05:18 < glouglou> il faudrait que les paquets ne puissent pas sortir de l'edge (le trait) entre les 2 nodes
+05:18 < glouglou> si tu as une idee ...
+05:22 -!- Munto [~frugal@2a01:e35:139d:91e0:221:85ff:fee1:5c3c] has quit [Read error: Connection reset by peer]
+05:33 -!- sharinganex [~sharingan@233.208.85.79.rev.sfr.net] has joined #e.fr
+06:22 <@cedric> glouglou: oui, swallow un smart objet
+06:22 <@cedric> qui n'a qu'une seule tache faire bouger des paquets de haut en bas et de bas en haut
+06:22 <@cedric> parcontre ca a un probleme, la taille des objets de tes paquets est limite par la taille de ton objet edje parent
+06:40 < glouglou> cedric: mais un smart object dans un edje object qui est ensuite mappe, juste pour faire un trait, ca va etre un peu lourd non ?
+06:40 < glouglou> et complexe
+06:40 < glouglou> mais c'est vrai que ca resous mon probleme
+06:41 <@cedric> bah, de toute facon, tu vas avoir une surface cree pour mettre ton edje dans ta map
+06:41 <@cedric> dc ca reviendra au meme voir tu fairas l'economie d'une surface
+06:49 < glouglou> cedric: donc quand tu swallow un evas smart object dans un edje object, les coordonnes pour le smart object sont relatifs a la part swallow ?
+06:50 < glouglou> genre si je fais un geometry_get dans mon smart obj, le 0x0 sera en fait en haut a gauche de ma part swallow edje ?
+06:52 <@cedric> oui
+06:52 < glouglou> mais c'est magnifique
+06:52 < glouglou> et splendide a fois
+06:53 < glouglou> merci :D
+
+TODO LATER
+==========
+
+* find a better storage type for vertices
+quick access O(1) -> table
+possibility to foreach and remove at the same time
+
+* possible future API: no edges no vertices for the user
+
+struct Egraph_Vertice {
+ const char *name;
+ int vertice_id;
+ Evas_Object *o;
+ void *data;
+}
+egraph_vertice_add(Egraph *eg, const char *name, void *data);
+egraph_edge_add(Egraph *eg,
+ const char *a, const char *b, void *data);
+
+* speed: draw directly to a surface and map to evas via invisible polygons
+see elementary/src/bin/test_gesture_layer3.c
+04:45 < glouglou> i would like to draw directly in a surface and then give it to evas, but i want in the future to have user interaction with the nodes of my
+ graph, like click click reaction, so i guess i cannot escape from creating one evas object for each node and edge
+04:46 <@raster> trick:
+04:47 <@raster> u can just create invisible rects
+04:47 < glouglou> (i can imagine crazy mapping of the clicks on my surface that triggers evas callbacks, but i'm not that crazy)
+04:47 <@raster> and overlay them on your image
+04:47 <@raster> use them for event stuff
+04:47 < glouglou> lol
+04:47 <@raster> or polygons tyoo
+04:47 <@raster> thats about the only use of polygons
+04:47 <@raster> as u can do exact inside/outside poly checks for events
+04:48 < glouglou> i think you are talking about the crazy things i don't want to do :p
+04:48 <@raster> one of the elm demos does this
+04:48 <@raster> for soming/rotating with little photos
+04:48 <@raster> multitouch test stuff
+
+* speed: from Thanatermesis :
+the Core library (https://github.com/acaudwell/Core)
+renders to OpenGL directly
+used by :
+http://code.google.com/p/logstalgia/
+https://github.com/acaudwell/Gource (http://code.google.com/p/gource/)
+
+OLD
+===
+
+* speed: evas_object_rectangles
+04:40 <@raster> they add clipoouts
+04:41 <@raster> make them just a bit translucent
+04:41 <@raster> and it'll be faster
+
diff --git a/egraph/doc/bug_lockup_evas.txt b/egraph/doc/bug_lockup_evas.txt
new file mode 100644
index 0000000..4f194c5
--- /dev/null
+++ b/egraph/doc/bug_lockup_evas.txt
@@ -0,0 +1,646 @@
+===============================================================================
+This bug is a lockup of evas during rendering in my efl app.
+App freeze and takes 100% CPU. Below are backtraces when gdb was running and
+I interrupt it with Ctrl-C.
+
+At the time of crash, around 300objects total :
+elementary interface + ~100 edje + ~100 evas_object_line
+
+This crash is not predictible from what I see, sometimes it goes fine for a long
+time.
+It seem to crash more when using more edje objects.
+
+svn info
+Revision: 79909
+
+uname -a
+Linux balboa 3.6.7-1-ARCH #1 SMP PREEMPT Sun Nov 18 10:11:22 CET 2012 x86_64 GNU/Linux
+
+===============================================================================
+2012-12-09_18-10
+
+ELM_ENGINE=opengl_x11 gdb ./examples/demoapp
+run
+
+// use the app, and it locks up during an animation (app takes 100% CPU)
+// Ctrl-C
+
+(gdb) bt
+#0 0x00007ffff7233fe6 in _calc_intra_outer_rect_area (outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...) at lib/evas/common/evas_tiler.c:468
+#1 rect_list_add_split_fuzzy (node=0x1967160, rects=0xdf91a8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:652
+#2 rect_list_add_split_fuzzy_and_merge (node=0x1967160, rects=0xdf91a8, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
+ at lib/evas/common/evas_tiler.c:849
+#3 _add_redraw (h=16, w=24, y=200, x=882, rects=0xdf91a8) at lib/evas/common/evas_tiler.c:956
+#4 evas_common_tilebuf_add_redraw (tb=0xdf9170, x=882, y=200, w=24, h=16) at lib/evas/common/evas_tiler.c:986
+#5 0x00007ffff71b2af2 in evas_object_render_pre_effect_updates (rects=0x68ad48, eo_obj=<optimized out>, is_v=1, was_v=<optimized out>)
+ at lib/evas/canvas/evas_object_main.c:343
+#6 0x00007ffff71f1bfc in _evas_render_phase1_direct (render_objects=0x1498d30, active_objects=0x68ab50, e=<optimized out>, restack_objects=<optimized out>,
+ delete_objects=<optimized out>) at lib/evas/canvas/evas_render.c:231
+#7 evas_render_updates_internal (eo_e=0x68aac0, make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001') at lib/evas/canvas/evas_render.c:1357
+#8 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
+#9 0x00007ffff6acba35 in _eo_op_internal (obj=0x68aac0, op_type=EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe1b8) at lib/eo/eo.c:363
+#10 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe1b8, op_type=EO_OP_TYPE_REGULAR, obj=0x68aac0) at lib/eo/eo.c:403
+#11 eo_do_internal (obj=0x68aac0, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
+#12 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
+#13 0x00007fffe73da43a in _ecore_evas_x_render (ee=0x6892f0) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
+#14 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
+#15 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
+#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
+#17 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
+#18 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
+#19 0x00000000004027bf in elm_main (argc=1, argv=0x7fffffffe568) at demoapp.c:248
+#20 0x0000000000402804 in main (argc=1, argv=0x7fffffffe568) at demoapp.c:255
+
+===============================================================================
+
+===============================================================================
+2012-12-10_15-48
+
+ELM_ENGINE=opengl_x11 gdb ./examples/demoapp
+run
+
+// use the app, and it locks up during an animation (app takes 100% CPU)
+// Ctrl-C
+
+^C
+Program received signal SIGINT, Interrupt.
+0x00007ffff7233fd3 in rect_list_add_split_fuzzy (node=0x1ce6300, rects=0x9c49b8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:650
+650 current = ((rect_node_t *)cur_node)->rect;
+(gdb) bt
+#0 0x00007ffff7233fd3 in rect_list_add_split_fuzzy (node=0x1ce6300, rects=0x9c49b8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:650
+#1 rect_list_add_split_fuzzy_and_merge (node=0x1ce6300, rects=0x9c49b8, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
+ at lib/evas/common/evas_tiler.c:849
+#2 _add_redraw (h=7, w=34, y=254, x=698, rects=0x9c49b8) at lib/evas/common/evas_tiler.c:956
+#3 evas_common_tilebuf_add_redraw (tb=0x9c4980, x=698, y=254, w=34, h=7) at lib/evas/common/evas_tiler.c:986
+#4 0x00007ffff71b2af2 in evas_object_render_pre_effect_updates (rects=0x68bed8, eo_obj=<optimized out>, is_v=1, was_v=<optimized out>)
+ at lib/evas/canvas/evas_object_main.c:343
+#5 0x00007ffff71f1bfc in _evas_render_phase1_direct (render_objects=0x139e3a0, active_objects=0x68bce0, e=<optimized out>, restack_objects=<optimized out>,
+ delete_objects=<optimized out>) at lib/evas/canvas/evas_render.c:231
+#6 evas_render_updates_internal (eo_e=0x68bc50, make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001') at lib/evas/canvas/evas_render.c:1357
+#7 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
+#8 0x00007ffff6acba35 in _eo_op_internal (obj=0x68bc50, op_type=EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe158) at lib/eo/eo.c:363
+#9 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe158, op_type=EO_OP_TYPE_REGULAR, obj=0x68bc50) at lib/eo/eo.c:403
+#10 eo_do_internal (obj=0x68bc50, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
+#11 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
+#12 0x00007fffe73d943a in _ecore_evas_x_render (ee=0x68a480) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
+#13 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
+#14 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
+#15 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
+#16 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
+#17 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
+#18 0x00000000004028de in elm_main (argc=1, argv=0x7fffffffe508) at demoapp.c:284
+#19 0x0000000000402923 in main (argc=1, argv=0x7fffffffe508) at demoapp.c:291
+
+===============================================================================
+2012-12-10_23-49
+
+Lockup without opengl !
+I was using software rendering.
+
+gdb ./examples/demoapp
+run
+
+// use the app, and it locks up during an animation (app takes 100% CPU)
+// Ctrl-C
+
+^C
+Program received signal SIGINT, Interrupt.
+_calc_intra_outer_rect_area (outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...) at lib/evas/common/evas_tiler.c:524
+524 intra->area = intra->width * intra->height;
+(gdb) bt
+#0 _calc_intra_outer_rect_area (outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...) at lib/evas/common/evas_tiler.c:524
+#1 rect_list_add_split_fuzzy (node=0xb54050, rects=0x6927f8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:652
+#2 rect_list_add_split_fuzzy_and_merge (node=0xb54050, rects=0x6927f8, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
+ at lib/evas/common/evas_tiler.c:849
+#3 _add_redraw (h=72, w=348, y=429, x=296, rects=0x6927f8) at lib/evas/common/evas_tiler.c:956
+#4 evas_common_tilebuf_add_redraw (tb=0x6927c0, x=296, y=429, w=348, h=72) at lib/evas/common/evas_tiler.c:986
+#5 0x00007ffff71b2af2 in evas_object_render_pre_effect_updates (rects=rects@entry=0x689ac8, eo_obj=eo_obj@entry=0x8d2360, is_v=is_v@entry=1, was_v=was_v@entry=
+ 1) at lib/evas/canvas/evas_object_main.c:343
+#6 0x00007ffff71ab60d in evas_object_image_render_pre (eo_obj=0x8d2360, obj=0x8d23f0) at lib/evas/canvas/evas_object_image.c:3768
+#7 0x00007ffff71f1668 in evas_render_updates_internal (eo_e=0x689840, make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
+ at lib/evas/canvas/evas_render.c:1365
+#8 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
+#9 0x00007ffff6acba35 in _eo_op_internal (obj=0x689840, op_type=EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe168) at lib/eo/eo.c:363
+#10 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe168, op_type=EO_OP_TYPE_REGULAR, obj=0x689840) at lib/eo/eo.c:403
+#11 eo_do_internal (obj=0x689840, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
+#12 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
+#13 0x00007fffe73d943a in _ecore_evas_x_render (ee=0x6880c0) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
+#14 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
+#15 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
+#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
+#17 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
+#18 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
+#19 0x00000000004028de in elm_main (argc=1, argv=0x7fffffffe518) at demoapp.c:284
+#20 0x0000000000402923 in main (argc=1, argv=0x7fffffffe518) at demoapp.c:291
+
+===============================================================================
+2012-12-10_23-58
+
+// Same scenario
+
+^C
+Program received signal SIGINT, Interrupt.
+rect_list_add_split_fuzzy (node=0xfe0150, rects=0x6927f8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:653
+653 area = current.area + r.area - intra.area;
+(gdb) bt
+#0 rect_list_add_split_fuzzy (node=0xfe0150, rects=0x6927f8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:653
+#1 rect_list_add_split_fuzzy_and_merge (node=0xfe0150, rects=0x6927f8, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
+ at lib/evas/common/evas_tiler.c:849
+#2 _add_redraw (h=63, w=85, y=314, x=493, rects=0x6927f8) at lib/evas/common/evas_tiler.c:956
+#3 evas_common_tilebuf_add_redraw (tb=0x6927c0, x=493, y=314, w=85, h=63) at lib/evas/common/evas_tiler.c:986
+#4 0x00007ffff71b2b9d in evas_object_render_pre_effect_updates (rects=0x689ac8, eo_obj=<optimized out>, is_v=1, was_v=<optimized out>)
+ at lib/evas/canvas/evas_object_main.c:356
+#5 0x00007ffff71f1bfc in _evas_render_phase1_direct (render_objects=0x1b79f50, active_objects=0x6898d0, e=<optimized out>, restack_objects=<optimized out>,
+ delete_objects=<optimized out>) at lib/evas/canvas/evas_render.c:231
+#6 evas_render_updates_internal (eo_e=0x689840, make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001') at lib/evas/canvas/evas_render.c:1357
+#7 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
+#8 0x00007ffff6acba35 in _eo_op_internal (obj=0x689840, op_type=EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe168) at lib/eo/eo.c:363
+#9 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe168, op_type=EO_OP_TYPE_REGULAR, obj=0x689840) at lib/eo/eo.c:403
+#10 eo_do_internal (obj=0x689840, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
+#11 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
+#12 0x00007fffe73d943a in _ecore_evas_x_render (ee=0x6880c0) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
+#13 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
+#14 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
+#15 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
+#16 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
+#17 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
+#18 0x00000000004028de in elm_main (argc=1, argv=0x7fffffffe518) at demoapp.c:284
+#19 0x0000000000402923 in main (argc=1, argv=0x7fffffffe518) at demoapp.c:291
+
+===============================================================================
+2012-12-11_00-34
+
+// Same scenario
+
+^C
+Program received signal SIGINT, Interrupt.
+rect_list_add_split_fuzzy (node=0xb54370, rects=0x6927f8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:702
+702 else if (intra.area <= accepted_error)
+(gdb) bt
+#0 rect_list_add_split_fuzzy (node=0xb54370, rects=0x6927f8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:702
+#1 rect_list_add_split_fuzzy_and_merge (node=0xb54370, rects=0x6927f8, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
+ at lib/evas/common/evas_tiler.c:849
+#2 _add_redraw (h=39, w=49, y=156, x=486, rects=0x6927f8) at lib/evas/common/evas_tiler.c:956
+#3 evas_common_tilebuf_add_redraw (tb=0x6927c0, x=486, y=156, w=49, h=39) at lib/evas/common/evas_tiler.c:986
+#4 0x00007ffff71b2af2 in evas_object_render_pre_effect_updates (rects=0x689ac8, eo_obj=<optimized out>, is_v=1, was_v=<optimized out>)
+ at lib/evas/canvas/evas_object_main.c:343
+#5 0x00007ffff71f1bfc in _evas_render_phase1_direct (render_objects=0x1671880, active_objects=0x6898d0, e=<optimized out>, restack_objects=<optimized out>,
+ delete_objects=<optimized out>) at lib/evas/canvas/evas_render.c:231
+#6 evas_render_updates_internal (eo_e=0x689840, make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001') at lib/evas/canvas/evas_render.c:1357
+#7 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
+#8 0x00007ffff6acba35 in _eo_op_internal (obj=0x689840, op_type=EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe168) at lib/eo/eo.c:363
+#9 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe168, op_type=EO_OP_TYPE_REGULAR, obj=0x689840) at lib/eo/eo.c:403
+#10 eo_do_internal (obj=0x689840, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
+#11 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
+#12 0x00007fffe73d943a in _ecore_evas_x_render (ee=0x6880c0) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
+#13 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
+#14 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
+#15 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
+#16 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
+#17 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
+#18 0x00000000004028de in elm_main (argc=1, argv=0x7fffffffe518) at demoapp.c:284
+#19 0x0000000000402923 in main (argc=1, argv=0x7fffffffe518) at demoapp.c:291
+
+===============================================================================
+2012-12-11_05-39
+
+Without any evas_object_line
+
+^C
+Program received signal SIGINT, Interrupt.
+rect_list_add_split_fuzzy (node=0xcf4c20, rects=0x692788, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:650
+650 current = ((rect_node_t *)cur_node)->rect;
+(gdb) bt
+#0 rect_list_add_split_fuzzy (node=0xcf4c20, rects=0x692788, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:650
+#1 rect_list_add_split_fuzzy_and_merge (node=0xcf4c20, rects=0x692788, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
+ at lib/evas/common/evas_tiler.c:849
+#2 _add_redraw (h=16, w=1047, y=240, x=263, rects=0x692788) at lib/evas/common/evas_tiler.c:956
+#3 evas_common_tilebuf_add_redraw (tb=0x692750, x=263, y=240, w=1047, h=16) at lib/evas/common/evas_tiler.c:986
+#4 0x00007ffff71b2af2 in evas_object_render_pre_effect_updates (rects=rects@entry=0x689a58, eo_obj=eo_obj@entry=0x1100690, is_v=is_v@entry=1,
+ was_v=was_v@entry=1) at lib/evas/canvas/evas_object_main.c:343
+#5 0x00007ffff71ab60d in evas_object_image_render_pre (eo_obj=0x1100690, obj=0x1100720) at lib/evas/canvas/evas_object_image.c:3768
+#6 0x00007ffff71f1bfc in _evas_render_phase1_direct (render_objects=0x1100690, active_objects=0x689860, e=<optimized out>, restack_objects=<optimized out>,
+ delete_objects=<optimized out>) at lib/evas/canvas/evas_render.c:231
+#7 evas_render_updates_internal (eo_e=0x6897d0, make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001') at lib/evas/canvas/evas_render.c:1357
+#8 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
+#9 0x00007ffff6acba35 in _eo_op_internal (obj=0x6897d0, op_type=EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe1d8) at lib/eo/eo.c:363
+#10 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe1d8, op_type=EO_OP_TYPE_REGULAR, obj=0x6897d0) at lib/eo/eo.c:403
+#11 eo_do_internal (obj=0x6897d0, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
+#12 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
+#13 0x00007fffe73d743a in _ecore_evas_x_render (ee=0x688050) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
+#14 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
+#15 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
+#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
+#17 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
+#18 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
+#19 0x00000000004028ce in elm_main (argc=1, argv=0x7fffffffe588) at demoapp.c:284
+#20 0x0000000000402913 in main (argc=1, argv=0x7fffffffe588) at demoapp.c:291
+
+===============================================================================
+2012-12-11_05-42
+
+with 500 nodes = 1500 objects, no evas_object_line, but 500 evas_map
+
+^C
+Program received signal SIGINT, Interrupt.
+_calc_intra_outer_rect_area (outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...) at lib/evas/common/evas_tiler.c:498
+498 if (a.top < b.top)
+(gdb) bt
+#0 _calc_intra_outer_rect_area (outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...) at lib/evas/common/evas_tiler.c:498
+#1 rect_list_add_split_fuzzy (node=0x1acbb00, rects=0x93f238, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:652
+#2 rect_list_add_split_fuzzy_and_merge (node=0x1acbb00, rects=0x93f238, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
+ at lib/evas/common/evas_tiler.c:849
+#3 _add_redraw (h=52, w=371, y=437, x=826, rects=0x93f238) at lib/evas/common/evas_tiler.c:956
+#4 evas_common_tilebuf_add_redraw (tb=0x93f200, x=826, y=437, w=371, h=52) at lib/evas/common/evas_tiler.c:986
+#5 0x00007ffff71ed67f in _evas_render_prev_cur_clip_cache_add (obj=obj@entry=0x1c752b0, e=0x68bc90, e=0x68bc90) at lib/evas/canvas/evas_render.c:158
+#6 0x00007ffff71ee940 in _evas_render_phase1_object_process (e=e@entry=0x68bc90, eo_obj=0x1c75220, active_objects=active_objects@entry=0x68bda8,
+ restack_objects=restack_objects@entry=0x68bdc8, delete_objects=delete_objects@entry=0x68bd88, render_objects=render_objects@entry=0x68bde8, restack=0,
+ redraw_all=redraw_all@entry=0x7fffffffe0ec, mapped_parent=mapped_parent@entry=0 '\000') at lib/evas/canvas/evas_render.c:355
+#7 0x00007ffff71eeaf6 in _evas_render_phase1_object_process (e=e@entry=0x68bc90, eo_obj=<optimized out>, active_objects=active_objects@entry=0x68bda8,
+ restack_objects=restack_objects@entry=0x68bdc8, delete_objects=delete_objects@entry=0x68bd88, render_objects=render_objects@entry=0x68bde8, restack=0,
+ redraw_all=redraw_all@entry=0x7fffffffe0ec, mapped_parent=mapped_parent@entry=0 '\000') at lib/evas/canvas/evas_render.c:413
+#8 0x00007ffff71eeaf6 in _evas_render_phase1_object_process (e=e@entry=0x68bc90, eo_obj=<optimized out>, active_objects=active_objects@entry=0x68bda8,
+ restack_objects=restack_objects@entry=0x68bdc8, delete_objects=delete_objects@entry=0x68bd88, render_objects=render_objects@entry=0x68bde8, restack=0,
+ redraw_all=redraw_all@entry=0x7fffffffe0ec, mapped_parent=mapped_parent@entry=0 '\000') at lib/evas/canvas/evas_render.c:413
+#9 0x00007ffff71eeaf6 in _evas_render_phase1_object_process (e=e@entry=0x68bc90, eo_obj=<optimized out>, active_objects=active_objects@entry=0x68bda8,
+ restack_objects=restack_objects@entry=0x68bdc8, delete_objects=delete_objects@entry=0x68bd88, render_objects=render_objects@entry=0x68bde8, restack=0,
+ redraw_all=redraw_all@entry=0x7fffffffe0ec, mapped_parent=mapped_parent@entry=0 '\000') at lib/evas/canvas/evas_render.c:413
+#10 0x00007ffff71eeaf6 in _evas_render_phase1_object_process (e=e@entry=0x68bc90, eo_obj=<optimized out>, active_objects=active_objects@entry=0x68bda8,
+ restack_objects=restack_objects@entry=0x68bdc8, delete_objects=delete_objects@entry=0x68bd88, render_objects=render_objects@entry=0x68bde8, restack=0,
+ redraw_all=redraw_all@entry=0x7fffffffe0ec, mapped_parent=mapped_parent@entry=0 '\000') at lib/evas/canvas/evas_render.c:413
+#11 0x00007ffff71eeaf6 in _evas_render_phase1_object_process (e=e@entry=0x68bc90, eo_obj=<optimized out>, active_objects=active_objects@entry=0x68bda8,
+ restack_objects=restack_objects@entry=0x68bdc8, delete_objects=delete_objects@entry=0x68bd88, render_objects=render_objects@entry=0x68bde8,
+ restack=restack@entry=0, redraw_all=redraw_all@entry=0x7fffffffe0ec, mapped_parent=mapped_parent@entry=0 '\000') at lib/evas/canvas/evas_render.c:413
+#12 0x00007ffff71f0f29 in _evas_render_phase1_process (redraw_all=0x7fffffffe0dc, render_objects=0x68bde8, delete_objects=0x68bd88, restack_objects=0x68bdc8,
+ active_objects=0x68bda8, e=0x68bc90) at lib/evas/canvas/evas_render.c:557
+#13 evas_render_updates_internal (eo_e=0x68bc00, make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001') at lib/evas/canvas/evas_render.c:1337
+#14 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
+#15 0x00007ffff6acba35 in _eo_op_internal (obj=0x68bc00, op_type=EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe1b8) at lib/eo/eo.c:363
+#16 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe1b8, op_type=EO_OP_TYPE_REGULAR, obj=0x68bc00) at lib/eo/eo.c:403
+#17 eo_do_internal (obj=0x68bc00, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
+#18 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
+#19 0x00007fffe73d743a in _ecore_evas_x_render (ee=0x68a430) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
+#20 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
+#21 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
+#22 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
+#23 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
+#24 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
+#25 0x00000000004028ce in elm_main (argc=1, argv=0x7fffffffe568) at demoapp.c:284
+#26 0x0000000000402913 in main (argc=1, argv=0x7fffffffe568) at demoapp.c:291
+
+
+===============================================================================
+2012-12-13_06-32
+
+
+(gdb) bt
+#0 0x00007ffff53ddff7 in _calc_intra_outer_rect_area (
+ outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...)
+ at lib/evas/common/evas_tiler.c:479
+#1 rect_list_add_split_fuzzy (node=0x8ed9c0, rects=0x691668,
+ accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:652
+#2 rect_list_add_split_fuzzy_and_merge (node=0x8ed9c0, rects=0x691668,
+ split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
+ at lib/evas/common/evas_tiler.c:849
+#3 _add_redraw (h=115, w=327, y=203, x=504, rects=0x691668)
+ at lib/evas/common/evas_tiler.c:956
+#4 evas_common_tilebuf_add_redraw (tb=0x691630, x=504, y=203, w=327, h=115)
+ at lib/evas/common/evas_tiler.c:986
+#5 0x00007ffff535cb9d in evas_object_render_pre_effect_updates (rects=
+ 0x688938, eo_obj=<optimized out>, is_v=1, was_v=<optimized out>)
+ at lib/evas/canvas/evas_object_main.c:356
+#6 0x00007ffff539bbfc in _evas_render_phase1_direct (render_objects=0x9baa60,
+ active_objects=0x688740, e=<optimized out>,
+ restack_objects=<optimized out>, delete_objects=<optimized out>)
+ at lib/evas/canvas/evas_render.c:231
+#7 evas_render_updates_internal (eo_e=0x6886b0,
+ make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
+ at lib/evas/canvas/evas_render.c:1357
+#8 0x00007ffff539dcd7 in _canvas_render_updates (eo_e=<optimized out>,
+ _pd=<optimized out>, list=<optimized out>)
+ at lib/evas/canvas/evas_render.c:1795
+#9 0x00007ffff706fa35 in _eo_op_internal (obj=0x6886b0, op_type=
+ EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe228) at lib/eo/eo.c:363
+#10 0x00007ffff70716cd in _eo_dov_internal (p_list=0x7fffffffe228, op_type=
+ EO_OP_TYPE_REGULAR, obj=0x6886b0) at lib/eo/eo.c:403
+#11 eo_do_internal (obj=0x6886b0, op_type=op_type@entry=EO_OP_TYPE_REGULAR)
+ at lib/eo/eo.c:434
+#12 0x00007ffff539dc5f in evas_render_updates (eo_e=<optimized out>)
+ at lib/evas/canvas/evas_render.c:1779
+#13 0x00007fffe6f7a43a in _ecore_evas_x_render (ee=0x686f30)
+ at modules/ecore_evas/engines/x/ecore_evas_x.c:447
+#14 0x00007ffff6e5e7f1 in _ecore_evas_idle_enter (data=<optimized out>)
+ at lib/ecore_evas/ecore_evas.c:59
+#15 0x00007ffff50e6019 in _ecore_call_task_cb (data=<optimized out>,
+ func=<optimized out>) at lib/ecore/ecore_private.h:300
+#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
+#17 0x00007ffff50e862d in _ecore_main_loop_iterate_internal (
+ once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1841
+#18 0x00007ffff50e8b27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
+#19 0x000000000040230e in elm_main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:269
+#20 0x0000000000402359 in main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:276
+
+
+===============================================================================
+2012-12-13_06-42
+
+^C
+Program received signal SIGINT, Interrupt.
+rect_list_add_split_fuzzy (node=0x884d70, rects=0x691668,
+ accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:653
+653 area = current.area + r.area - intra.area;
+
+(gdb) bt
+#0 rect_list_add_split_fuzzy (node=0x884d70, rects=0x691668,
+ accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:653
+#1 rect_list_add_split_fuzzy_and_merge (node=0x884d70, rects=0x691668,
+ split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
+ at lib/evas/common/evas_tiler.c:849
+#2 _add_redraw (h=12, w=542, y=356, x=118, rects=0x691668)
+ at lib/evas/common/evas_tiler.c:956
+#3 evas_common_tilebuf_add_redraw (tb=tb@entry=0x691630, x=118, y=356, w=542,
+ h=12) at lib/evas/common/evas_tiler.c:986
+#4 0x00007fffe6d672ac in _merge_rects (tb=0x691630, r1=<optimized out>, r2=
+ 0x0, r3=0x0) at modules/evas/engines/software_x11/evas_engine.c:713
+#5 0x00007fffe6d6759b in eng_output_redraws_next_update_get (data=0x691c00, x=
+ 0x7fffffffe13c, y=0x7fffffffe140, w=0x7fffffffe144, h=0x7fffffffe148,
+ cx=<optimized out>, cy=0x7fffffffe150, cw=0x7fffffffe154, ch=
+ 0x7fffffffe158) at modules/evas/engines/software_x11/evas_engine.c:821
+#6 0x00007ffff539bf4f in evas_render_updates_internal (eo_e=0x6886b0,
+ make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
+ at lib/evas/canvas/evas_render.c:1533
+#7 0x00007ffff539dcd7 in _canvas_render_updates (eo_e=<optimized out>,
+ _pd=<optimized out>, list=<optimized out>)
+ at lib/evas/canvas/evas_render.c:1795
+#8 0x00007ffff706fa35 in _eo_op_internal (obj=0x6886b0, op_type=
+ EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe228) at lib/eo/eo.c:363
+#9 0x00007ffff70716cd in _eo_dov_internal (p_list=0x7fffffffe228, op_type=
+ EO_OP_TYPE_REGULAR, obj=0x6886b0) at lib/eo/eo.c:403
+#10 eo_do_internal (obj=0x6886b0, op_type=op_type@entry=EO_OP_TYPE_REGULAR)
+ at lib/eo/eo.c:434
+#11 0x00007ffff539dc5f in evas_render_updates (eo_e=<optimized out>)
+ at lib/evas/canvas/evas_render.c:1779
+#12 0x00007fffe6f7a43a in _ecore_evas_x_render (ee=0x686f30)
+ at modules/ecore_evas/engines/x/ecore_evas_x.c:447
+#13 0x00007ffff6e5e7f1 in _ecore_evas_idle_enter (data=<optimized out>)
+ at lib/ecore_evas/ecore_evas.c:59
+#14 0x00007ffff50e6019 in _ecore_call_task_cb (data=<optimized out>,
+ func=<optimized out>) at lib/ecore/ecore_private.h:300
+#15 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
+#16 0x00007ffff50e847b in _ecore_main_loop_iterate_internal (
+ once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
+#17 0x00007ffff50e8b27 in ecore_main_loop_begin ()
+ at lib/ecore/ecore_main.c:964
+#18 0x000000000040230e in elm_main (argc=1, argv=0x7fffffffe5b8)
+ at gg_map.c:269
+#19 0x0000000000402359 in main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:276
+
+===============================================================================
+2012-12-13_15-32
+
+^C 0x7fffe6d61700 (LWP 21696)]
+[Thread 0x7fffe6d61700 (LWP 21696) exited]
+[New Thread 0x7fffe6d61700 (LWP 21697)]
+[Thread 0x7fffe6d61700 (LWP 21697) exited]
+[New Thread 0x7fffe6d61700 (LWP 21711)]
+[Thread 0x7fffe6d61700 (LWP 21711) exited]
+[New Thread 0x7fffe6d61700 (LWP 21712)]
+[Thread 0x7fffe6d61700 (LWP 21712) exited]
+
+Program received signal SIGINT, Interrupt.
+rect_list_add_split_fuzzy (node=0xa977b0, rects=0x691668,
+ accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:680
+680 else if ((outer.area - area) <= accepted_error)
+
+
+(gdb) bt
+#0 rect_list_add_split_fuzzy (node=0xa977b0, rects=0x691668,
+ accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:680
+#1 rect_list_add_split_fuzzy_and_merge (node=0xa977b0, rects=0x691668,
+ split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
+ at lib/evas/common/evas_tiler.c:849
+#2 _add_redraw (h=6, w=126, y=110, x=463, rects=0x691668)
+ at lib/evas/common/evas_tiler.c:956
+#3 evas_common_tilebuf_add_redraw (tb=0x691630, x=463, y=110, w=126, h=6)
+ at lib/evas/common/evas_tiler.c:986
+#4 0x00007ffff535cb9d in evas_object_render_pre_effect_updates (
+ rects=rects@entry=0x688938, eo_obj=eo_obj@entry=0xa83500, is_v=is_v@entry=
+ 1, was_v=was_v@entry=1) at lib/evas/canvas/evas_object_main.c:356
+#5 0x00007ffff535560d in evas_object_image_render_pre (eo_obj=0xa83500, obj=
+ 0xa83590) at lib/evas/canvas/evas_object_image.c:3768
+#6 0x00007ffff539bbfc in _evas_render_phase1_direct (render_objects=0xa83500,
+ active_objects=0x688740, e=<optimized out>,
+ restack_objects=<optimized out>, delete_objects=<optimized out>)
+ at lib/evas/canvas/evas_render.c:231
+#7 evas_render_updates_internal (eo_e=0x6886b0,
+ make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
+ at lib/evas/canvas/evas_render.c:1357
+#8 0x00007ffff539dcd7 in _canvas_render_updates (eo_e=<optimized out>,
+ _pd=<optimized out>, list=<optimized out>)
+ at lib/evas/canvas/evas_render.c:1795
+#9 0x00007ffff706fa35 in _eo_op_internal (obj=0x6886b0, op_type=
+ EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe228) at lib/eo/eo.c:363
+#10 0x00007ffff70716cd in _eo_dov_internal (p_list=0x7fffffffe228, op_type=
+ EO_OP_TYPE_REGULAR, obj=0x6886b0) at lib/eo/eo.c:403
+#11 eo_do_internal (obj=0x6886b0, op_type=op_type@entry=EO_OP_TYPE_REGULAR)
+ at lib/eo/eo.c:434
+#12 0x00007ffff539dc5f in evas_render_updates (eo_e=<optimized out>)
+ at lib/evas/canvas/evas_render.c:1779
+#13 0x00007fffe6f7943a in _ecore_evas_x_render (ee=0x686f30)
+ at modules/ecore_evas/engines/x/ecore_evas_x.c:447
+#14 0x00007ffff6e5e7f1 in _ecore_evas_idle_enter (data=<optimized out>)
+ at lib/ecore_evas/ecore_evas.c:59
+#15 0x00007ffff50e6019 in _ecore_call_task_cb (data=<optimized out>,
+ func=<optimized out>) at lib/ecore/ecore_private.h:300
+#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
+#17 0x00007ffff50e847b in _ecore_main_loop_iterate_internal (
+ once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
+#18 0x00007ffff50e8b27 in ecore_main_loop_begin ()
+ at lib/ecore/ecore_main.c:964
+#19 0x00000000004022f1 in elm_main (argc=1, argv=0x7fffffffe5b8)
+ at gg_map.c:273
+#20 0x000000000040233c in main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:280
+(gdb)
+
+
+===============================================================================
+2012-12-13_17-19
+
+
+rect_list_add_split_fuzzy (node=0xb07d60, rects=0x692668, [0/1873]
+ accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:653
+653 area = current.area + r.area - intra.area;
+(gdb) bt
+#0 rect_list_add_split_fuzzy (node=0xb07d60, rects=0x692668,
+ accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:653
+#1 rect_list_add_split_fuzzy_and_merge (node=0xb07d60, rects=0x692668,
+ split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
+ at lib/evas/common/evas_tiler.c:849
+#2 _add_redraw (h=30, w=79, y=539, x=665, rects=0x692668)
+ at lib/evas/common/evas_tiler.c:956
+#3 evas_common_tilebuf_add_redraw (tb=0x692630, x=665, y=539, w=79, h=30)
+ at lib/evas/common/evas_tiler.c:986
+#4 0x00007ffff539bd1c in _evas_render_phase1_direct (render_objects=0xb61c40,
+ active_objects=0x689740, e=<optimized out>,
+ restack_objects=<optimized out>, delete_objects=<optimized out>)
+ at lib/evas/canvas/evas_render.c:257
+#5 evas_render_updates_internal (eo_e=0x6896b0,
+ make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
+ at lib/evas/canvas/evas_render.c:1357
+#6 0x00007ffff539dcd7 in _canvas_render_updates (eo_e=<optimized out>,
+ _pd=<optimized out>, list=<optimized out>)
+ at lib/evas/canvas/evas_render.c:1795
+#7 0x00007ffff706fa35 in _eo_op_internal (obj=0x6896b0, op_type=
+ EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe228) at lib/eo/eo.c:363
+#8 0x00007ffff70716cd in _eo_dov_internal (p_list=0x7fffffffe228, op_type=
+ EO_OP_TYPE_REGULAR, obj=0x6896b0) at lib/eo/eo.c:403
+#9 eo_do_internal (obj=0x6896b0, op_type=op_type@entry=EO_OP_TYPE_REGULAR)
+ at lib/eo/eo.c:434
+#10 0x00007ffff539dc5f in evas_render_updates (eo_e=<optimized out>)
+ at lib/evas/canvas/evas_render.c:1779
+#11 0x00007fffe6f7943a in _ecore_evas_x_render (ee=0x687f30)
+ at modules/ecore_evas/engines/x/ecore_evas_x.c:447
+#12 0x00007ffff6e5e7f1 in _ecore_evas_idle_enter (data=<optimized out>)
+ at lib/ecore_evas/ecore_evas.c:59
+#13 0x00007ffff50e6019 in _ecore_call_task_cb (data=<optimized out>,
+ func=<optimized out>) at lib/ecore/ecore_private.h:300
+#14 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
+#15 0x00007ffff50e847b in _ecore_main_loop_iterate_internal (
+ once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
+#16 0x00007ffff50e8b27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
+#17 0x00000000004025d9 in elm_main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:324
+#18 0x0000000000402624 in main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:331
+
+===============================================================================
+2012-12-16_04-22
+
+This bug is a lockup of evas during rendering in my efl app.
+App freeze and takes 100% CPU. Below are backtraces when gdb was running and
+I interrupt it with Ctrl-C.
+
+At the time of crash, around 300objects total :
+elementary interface + ~100 edje + 100 edje mapped with evas_map + ~100 evas_object_text
+
+This crash is not predictible from what I see, sometimes it goes fine for a long
+time.
+It seem to crash more when using more edje objects.
+
+happened AFTER raster's fix
+------------------------------------------------------------------------
+r81039 | raster | 2012-12-16 03:01:11 +0100 (Sun, 16 Dec 2012) | 5 lines
+small change - dont let update rect list for image object become a
+runaway endless list if evas doenst come around and render (pick it
+up) any time soon - limit to 512 update rects.
+
+
+^C
+Program received signal SIGINT, Interrupt.
+0x00007ffff53ddc54 in _calc_intra_outer_rect_area (outer=<synthetic pointer>,
+ intra=<synthetic pointer>, a=..., b=...) at lib/evas/common/evas_tiler.c:530
+530 outer->height = max_bottom - min_top;
+(gdb) bt
+#0 0x00007ffff53ddc54 in _calc_intra_outer_rect_area (
+ outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...)
+ at lib/evas/common/evas_tiler.c:530
+#1 rect_list_add_split_fuzzy (node=0x9d27c0, rects=0x6942b8,
+ accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:652
+#2 rect_list_add_split_fuzzy_and_merge (node=0x9d27c0, rects=0x6942b8,
+ split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
+ at lib/evas/common/evas_tiler.c:849
+#3 _add_redraw (h=76, w=276, y=453, x=990, rects=0x6942b8)
+ at lib/evas/common/evas_tiler.c:956
+#4 evas_common_tilebuf_add_redraw (tb=0x694280, x=990, y=453, w=276, h=76)
+ at lib/evas/common/evas_tiler.c:986
+#5 0x00007ffff539736f in _evas_render_prev_cur_clip_cache_add (obj=obj@entry=
+ 0xbee890, e=0x68b390, e=0x68b390) at lib/evas/canvas/evas_render.c:158
+#6 0x00007ffff539ba0c in _evas_render_phase1_direct (render_objects=0xbee800,
+ active_objects=0x68b390, e=<optimized out>,
+ restack_objects=<optimized out>, delete_objects=<optimized out>)
+ at lib/evas/canvas/evas_render.c:257
+#7 evas_render_updates_internal (eo_e=0x68b300,
+ make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
+ at lib/evas/canvas/evas_render.c:1357
+#8 0x00007ffff539d9c7 in _canvas_render_updates (eo_e=<optimized out>,
+ _pd=<optimized out>, list=<optimized out>)
+ at lib/evas/canvas/evas_render.c:1795
+#9 0x00007ffff706fa45 in _eo_op_internal (obj=0x68b300, op_type=
+ EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe1f8) at lib/eo/eo.c:363
+#10 0x00007ffff70716dd in _eo_dov_internal (p_list=0x7fffffffe1f8, op_type=
+ EO_OP_TYPE_REGULAR, obj=0x68b300) at lib/eo/eo.c:403
+#11 eo_do_internal (obj=0x68b300, op_type=op_type@entry=EO_OP_TYPE_REGULAR)
+ at lib/eo/eo.c:434
+#12 0x00007ffff539d94f in evas_render_updates (eo_e=<optimized out>)
+ at lib/evas/canvas/evas_render.c:1779
+#13 0x00007fffe6f7743a in _ecore_evas_x_render (ee=0x689b80)
+ at modules/ecore_evas/engines/x/ecore_evas_x.c:447
+#14 0x00007ffff6e5e841 in _ecore_evas_idle_enter (data=<optimized out>)
+ at lib/ecore_evas/ecore_evas.c:59
+#15 0x00007ffff50e5059 in _ecore_call_task_cb (data=<optimized out>,
+ func=<optimized out>) at lib/ecore/ecore_private.h:300
+#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
+#17 0x00007ffff50e74bb in _ecore_main_loop_iterate_internal (
+ once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
+#18 0x00007ffff50e7b67 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
+#19 0x00000000004035b0 in elm_main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:461
+---Type <return> to continue, or q <return> to quit---
+#20 0x00000000004035fb in main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:468
+
+===============================================================================
+2012-12-16_18-16
+
+
+^C
+Program received signal SIGINT, Interrupt.
+0x00007ffff53ddd20 in _calc_intra_outer_rect_area (outer=<synthetic pointer>,
+ intra=<synthetic pointer>, a=..., b=...)
+ at lib/evas/common/evas_tiler.c:509
+509 if (a.bottom < b.bottom)
+(gdb) bt
+#0 0x00007ffff53ddd20 in _calc_intra_outer_rect_area (
+ outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...)
+ at lib/evas/common/evas_tiler.c:509
+#1 rect_list_add_split_fuzzy (node=0x16b03d0, rects=0x692668,
+ accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:652
+#2 rect_list_add_split_fuzzy_and_merge (node=0x16b03d0, rects=0x692668,
+ split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
+ at lib/evas/common/evas_tiler.c:849
+#3 _add_redraw (h=31, w=323, y=264, x=696, rects=0x692668)
+ at lib/evas/common/evas_tiler.c:956
+#4 evas_common_tilebuf_add_redraw (tb=0x692630, x=696, y=264, w=323, h=31)
+ at lib/evas/common/evas_tiler.c:986
+#5 0x00007ffff539736f in _evas_render_prev_cur_clip_cache_add (obj=obj@entry=
+ 0x36cef40, e=0x689740, e=0x689740) at lib/evas/canvas/evas_render.c:158
+#6 0x00007ffff539ba0c in _evas_render_phase1_direct (render_objects=
+ 0x36ceeb0, active_objects=0x689740, e=<optimized out>,
+ restack_objects=<optimized out>, delete_objects=<optimized out>)
+ at lib/evas/canvas/evas_render.c:257
+#7 evas_render_updates_internal (eo_e=0x6896b0,
+ make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
+ at lib/evas/canvas/evas_render.c:1357
+#8 0x00007ffff539d9c7 in _canvas_render_updates (eo_e=<optimized out>,
+ _pd=<optimized out>, list=<optimized out>)
+ at lib/evas/canvas/evas_render.c:1795
+#9 0x00007ffff706fa45 in _eo_op_internal (obj=0x6896b0, op_type=
+ EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe1f8) at lib/eo/eo.c:363
+#10 0x00007ffff70716dd in _eo_dov_internal (p_list=0x7fffffffe1f8, op_type=
+ EO_OP_TYPE_REGULAR, obj=0x6896b0) at lib/eo/eo.c:403
+#11 eo_do_internal (obj=0x6896b0, op_type=op_type@entry=EO_OP_TYPE_REGULAR)
+ at lib/eo/eo.c:434
+#12 0x00007ffff539d94f in evas_render_updates (eo_e=<optimized out>)
+ at lib/evas/canvas/evas_render.c:1779
+#13 0x00007fffe6f7743a in _ecore_evas_x_render (ee=0x687f30)
+ at modules/ecore_evas/engines/x/ecore_evas_x.c:447
+#14 0x00007ffff6e5e841 in _ecore_evas_idle_enter (data=<optimized out>)
+ at lib/ecore_evas/ecore_evas.c:59
+#15 0x00007ffff50e5059 in _ecore_call_task_cb (data=<optimized out>,
+ func=<optimized out>) at lib/ecore/ecore_private.h:300
+#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
+#17 0x00007ffff50e766d in _ecore_main_loop_iterate_internal (
+ once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1841
+#18 0x00007ffff50e7b67 in ecore_main_loop_begin ()
+ at lib/ecore/ecore_main.c:964
+#19 0x00000000004031c1 in elm_main (argc=1, argv=0x7fffffffe5b8)
+ at gg_map.c:447
+#20 0x000000000040320c in main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:454
+
+
diff --git a/egraph/doc/egraph.xoj b/egraph/doc/egraph.xoj
new file mode 100644
index 0000000..59ca038
--- /dev/null
+++ b/egraph/doc/egraph.xoj
Binary files differ
diff --git a/egraph/doc/internals.txt b/egraph/doc/internals.txt
new file mode 100644
index 0000000..7a8b34d
--- /dev/null
+++ b/egraph/doc/internals.txt
@@ -0,0 +1,89 @@
+Internals
+=========
+
+=== algo to handle threaded graph layouting correctly ===
+
+###### GENERAL ALGO
+_layouting_start(graph-2, coords-2);
+
+_add/del(structs-3);
+_repositionning(graph, structs, coords);
+
+_layouting_end(coords-2);
+
+_v2_updtate(structs-2, graph-2, coords-2);
+ _v2_structs/graph_update(structs-2, graph);
+ -> structs, graph // real add/del
+ _coords_copy(coords-2);
+ -> coords
+
+_repositionning(graph, structs, coords);
+
+_v3_update(structs-3);
+ _v3_structs/graph_update(structs-3, graph-2);
+ -> structs-2, graph-2
+
+###### TIMELINE VERTICE ADD
+egraph_vertice_add();
+ id = freeids[vertices_count];
+ v = vertices[id];
+ v->id = id;
+ vertices_count++;
+ v->v3-new = 1;
+
+_v3_update();
+ v->v2-new = v->v3-new;
+ v->v3-new = 0;
+ _v2_add()
+ v->graph2_vid = graph2_vcount;
+ graph2_vcount++;
+ igraph_add_vertices(graph2);
+
+_layouting_start();
+ // end up in coords2
+
+_layouting_end();
+_coords_copy();
+ // end up in coords
+
+_v2_update();
+ _add()
+ v->v2-new = 0;
+ v->graph_vid = graph_vcount;
+ graph_vcount++;
+ igraph_add_vertices(graph);
+ evas_object
+
+// in structs, graph, coords
+
+###### TIMELINE VERTICE DEL
+egraph_vertice_del();
+ v->v3-del = 1;
+
+_v3_update();
+ v->v2-del = v->v3-del;
+ v->v3-del = 0;
+ _v2_del()
+ igraph_delete_vertices(v->graph2_vid);
+ graph2_vcount--;
+
+_layouting_start();
+ // not in coords2
+
+_layouting_end();
+_coords_copy();
+ // not in coords
+
+_v2_update();
+ _del();
+ igraph_delete_vertices(v->graph_vid);
+ graph_vcount--;
+ freeids[vertices_count] = v->id;
+ vertices_count--;
+ free(v);
+
+// removed from structs, graph, coords
+
+###### TIMELINE VERTICE DEL
+
+
diff --git a/egraph/egraph.c b/egraph/egraph.c
new file mode 100644
index 0000000..bffcebf
--- /dev/null
+++ b/egraph/egraph.c
@@ -0,0 +1,1275 @@
+#include <err.h>
+#include <Efx.h>
+#include <Edje.h>
+
+#include "Egraph.h"
+
+#define DEBUG 0
+
+#define TYPE_MAXLEN 30
+
+static void _smart_add(Evas_Object *obj);
+static void _smart_del(Evas_Object *obj);
+static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static void _edge_v2_add(Egraph *eg, Egraph_Edge *e);
+static void _edge_add(Egraph *eg, Egraph_Edge *e);
+static void _edge_signal(Egraph *eg, Egraph_Edge *e, const char *signal);
+static void _edge_v2_del(Egraph *eg, Egraph_Edge *e);
+static void _edge_del(Egraph *eg, Egraph_Edge *e);
+static void _vertice_v2_add(Egraph *eg, Egraph_Vertice *v);
+static void _vertice_add(Egraph *eg, Egraph_Vertice *v);
+static void _vertice_v2_del(Egraph *eg, Egraph_Vertice *v);
+static void _vertice_del(Egraph *eg, Egraph_Vertice *v);
+static void _vertice_update_status(Egraph *eg, Egraph_Vertice *v);
+static void _vertice_signal(Egraph *eg, Egraph_Vertice *v, const char *signal);
+static void _vertice_geometry_update(Egraph *eg, Egraph_Vertice *v);
+static void _v2_update(Egraph *eg);
+static void _v3_update(Egraph *eg);
+static void _coords2_copy(Egraph *eg);
+static void _cb_blob_arrived(void *data, Efx_Map_Data *e, Evas_Object *obj);
+static void _blob_send(Evas_Object *blob,
+ Egraph_Vertice *v, Evas_Coord x, Evas_Coord y);
+static void _layouting_schedule(Egraph *eg);
+static Eina_Bool _cb_layouting_start(void *data);
+static void _cb_layouting_run(void *data, Ecore_Thread *thread);
+static void _cb_layouting_end(void *data, Ecore_Thread *thread);
+static void _cb_layouting_cancel(void *data, Ecore_Thread *thread);
+static int _igraph_query_vid(igraph_t *g, int g_len, int id);
+static void _cb_vertice_move(void *data,
+ Evas *evas, Evas_Object *obj, void *event_info);
+static void _reposition(Egraph *eg, int no_animation);
+static void _matrix_minmax_2v(const igraph_matrix_t *m, int row_count,
+ float *c1min, float *c1max,
+ float *c2min, float *c2max);
+static Evas_Object *_edje_obj_new(Egraph *eg, const char *group);
+static Evas_Object *_edje_obj_set(Egraph *eg, Evas_Object *o, const char *group);
+
+static const Evas_Smart_Cb_Description _smart_callbacks[] = {{NULL, NULL}};
+#define EGRAPH_DATA_GET(o, ptr) \
+ Egraph * ptr = evas_object_smart_data_get(o)
+/* defines _egraph_parent_sc and _egraph_smart_class_new */
+EVAS_SMART_SUBCLASS_NEW("Egraph", _egraph,
+ Evas_Smart_Class, Evas_Smart_Class,
+ evas_object_smart_clipped_class_get, _smart_callbacks);
+
+static void
+_egraph_smart_set_user(Evas_Smart_Class *sc)
+{
+ /* specializing these two */
+ sc->add = _smart_add;
+ sc->del = _smart_del;
+ sc->move = _smart_move;
+ /* clipped smart object has no hook on resizes or calculations */
+ sc->resize = _smart_resize;
+}
+
+static void
+_smart_add(Evas_Object *obj)
+{
+ EVAS_SMART_DATA_ALLOC(obj, Egraph);
+
+ priv->evas = evas_object_evas_get(obj);
+
+ _egraph_parent_sc->add(obj);
+}
+
+static void
+_smart_del(Evas_Object *obj)
+{
+ EGRAPH_DATA_GET(obj, eg);
+
+ igraph_destroy(&eg->graph);
+ if (eg->layouting.running == 2)
+ ecore_thread_cancel(eg->layouting.thread);
+
+ _egraph_parent_sc->del(obj);
+}
+
+static void
+_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+ EGRAPH_DATA_GET(obj, eg);
+
+ _reposition(eg, 1);
+
+ _egraph_parent_sc->move(obj, x, y);
+}
+
+static void
+_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+ EGRAPH_DATA_GET(obj, eg);
+
+ _reposition(eg, 1);
+}
+
+Evas_Object *
+egraph_new(Evas *evas, int directed)
+{
+ Evas_Object *obj = NULL;
+ Evas_Object *rect;
+ Egraph *eg;
+ int i;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(evas, NULL);
+
+ efx_init();
+ eina_log_domain_level_set("efx", EINA_LOG_LEVEL_WARN);
+
+ obj = evas_object_smart_add(evas, _egraph_smart_class_new());
+ eg = evas_object_smart_data_get(obj);
+ if (!eg) goto err;
+ eg->obj = obj;
+ rect = evas_object_rectangle_add(eg->evas);
+ evas_object_color_set(rect, 0, 0, 0, 0);
+ evas_object_smart_member_add(rect, obj);
+ eg->split_vertice_edge = rect;
+
+ eg->graph_directed = directed;
+ eg->display_vertices = 1;
+ eg->display_names = 1;
+ eg->display_edges = 1;
+ eg->use_animations = 1;
+ eg->do_improvements = 1;
+ egraph_theme_file_set(obj, NULL);
+ eg->theme_edges = 1;
+ eg->layout = EGRAPH_LAYOUT_DEFAULT;
+
+ /* needed for igraph attribute handling */
+ igraph_i_set_attribute_table(&igraph_cattribute_table);
+
+ eg->vertices = eina_hash_int32_new(NULL);
+ for (i=0; i<EGRAPH_VERTICES_MAX-1; i++)
+ eg->vertices_freeids[i] = i;
+ if (igraph_empty(&eg->graph, 0, directed))
+ goto err;
+ if (igraph_empty(&eg->graph2, 0, directed))
+ goto err;
+ igraph_matrix_init(&eg->coords, 0, 2);
+ igraph_matrix_init(&eg->coords2, 0, 2);
+ eg->graph_wmin = 0;
+ eg->graph_wmax = 200;
+ eg->graph_hmin = 0;
+ eg->graph_hmax = 200;
+ eg->vertice_max_w = 0;
+ eg->vertice_max_h = 0;
+
+ return obj;
+
+err:
+ if (obj)
+ evas_object_del(obj);
+ return NULL;
+}
+
+void
+egraph_clear(Evas_Object *obj)
+{
+ EGRAPH_DATA_GET(obj, eg);
+ Eina_Iterator *it;
+ Egraph_Vertice *v;
+ void *data;
+
+ it = eina_hash_iterator_tuple_new(eg->vertices);
+ while (eina_iterator_next(it, &data)) {
+ Eina_Hash_Tuple *t = data;
+ v = t->data;
+ egraph_vertice_del(obj, v);
+ }
+}
+
+void
+egraph_theme_file_set(Evas_Object *obj, char *path)
+{
+ EGRAPH_DATA_GET(obj, eg);
+
+ if (eg->theme_path)
+ free(eg->theme_path);
+
+ if (!path) {
+ char buf[256];
+
+ snprintf(buf, sizeof(buf),
+ "%s/egraph.edj",
+ "/usr/local/share/egraph"); /* XXX use eina_prefix */
+ path = buf;
+ }
+ eg->theme_path = strndup(path, 256);
+}
+
+void
+egraph_theme_edges_set(Evas_Object *obj, int set)
+{
+ EGRAPH_DATA_GET(obj, eg);
+
+ eg->theme_edges = set;
+}
+
+void
+egraph_layout_set(Evas_Object *obj, Egraph_Layout layout)
+{
+ EGRAPH_DATA_GET(obj, eg);
+
+ eg->layout = layout;
+ _layouting_schedule(eg);
+}
+
+void
+egraph_display_vertices_set(Evas_Object *obj, int set)
+{
+ EGRAPH_DATA_GET(obj, eg);
+ Eina_Iterator *it;
+ Egraph_Vertice *v;
+ void *data;
+
+ eg->display_vertices = set;
+
+ it = eina_hash_iterator_tuple_new(eg->vertices);
+ while (eina_iterator_next(it, &data)) {
+ Eina_Hash_Tuple *t = data;
+ v = t->data;
+ if (v->o) {
+ if (set == 0)
+ evas_object_hide(v->o);
+ else
+ evas_object_show(v->o);
+ }
+ }
+
+ _reposition(eg, 0);
+}
+
+void
+egraph_display_names_set(Evas_Object *obj, int set)
+{
+ EGRAPH_DATA_GET(obj, eg);
+ Eina_Iterator *it;
+ Egraph_Vertice *v;
+ void *data;
+
+ eg->display_names = set;
+
+ it = eina_hash_iterator_tuple_new(eg->vertices);
+ while (eina_iterator_next(it, &data)) {
+ Eina_Hash_Tuple *t = data;
+ v = t->data;
+ egraph_vertice_rename(obj, v, set ? v->name : NULL);
+ }
+}
+
+void
+egraph_display_edges_set(Evas_Object *obj, int set)
+{
+ EGRAPH_DATA_GET(obj, eg);
+ Eina_List *l;
+ Egraph_Edge *e;
+
+ eg->display_edges = set;
+
+ EINA_LIST_FOREACH(eg->edges, l, e) {
+ if (e->o) {
+ if (set == 0)
+ evas_object_hide(e->o);
+ else
+ evas_object_show(e->o);
+ }
+ }
+}
+
+void
+egraph_use_animations_set(Evas_Object *obj, int set)
+{
+ EGRAPH_DATA_GET(obj, eg);
+
+ eg->use_animations = set;
+}
+
+void
+egraph_do_improvements_set(Evas_Object *obj, int set)
+{
+ EGRAPH_DATA_GET(obj, eg);
+
+ eg->do_improvements = set;
+}
+
+Egraph_Edge *
+egraph_edge_add(Evas_Object *obj, Egraph_Vertice *a, Egraph_Vertice *b,
+ void *data)
+{
+ EGRAPH_DATA_GET(obj, eg);
+ Egraph_Edge *e;
+
+ e = calloc(1, sizeof(Egraph_Edge));
+ if (!e)
+ err(1, "egraph_edge_add: cannot calloc");
+ e->v3_new = 1;
+ e->a = a;
+ e->b = b;
+ e->data = data;
+ eg->edges = eina_list_append(eg->edges, e);
+ if (DEBUG)
+ printf("egraph_edge_add %d %d\n", e->a->id, e->b->id);
+
+ egraph_edge_type_set(obj, e, "edge_normal");
+
+ _layouting_schedule(eg);
+ return e;
+}
+
+static void
+_edge_v2_add(Egraph *eg, Egraph_Edge *e)
+{
+ int a_pos, b_pos;
+
+ if (DEBUG)
+ printf("_edge_v2_add %d %d\n", e->a->id, e->b->id);
+
+ e->v2_new = 1;
+ e->v3_new = 0;
+
+ a_pos = _igraph_query_vid(&eg->graph2, eg->graph2_vcount, e->a->id);
+ b_pos = _igraph_query_vid(&eg->graph2, eg->graph2_vcount, e->b->id);
+ igraph_add_edge(&eg->graph2, a_pos, b_pos);
+}
+
+static void
+_edge_add(Egraph *eg, Egraph_Edge *e)
+{
+ Evas_Object *eobj = NULL;
+ int a_pos, b_pos;
+
+ e->new = 1;
+ e->v2_new = 0;
+
+ a_pos = _igraph_query_vid(&eg->graph, eg->graph_vcount, e->a->id);
+ b_pos = _igraph_query_vid(&eg->graph, eg->graph_vcount, e->b->id);
+ igraph_add_edge(&eg->graph, a_pos, b_pos);
+
+ if (eg->theme_edges) {
+ eobj = _edje_obj_new(eg, e->type);
+ if (eobj) {
+ e->o_usetheme = 1;
+ evas_object_resize(eobj, eg->vertice_max_w, eg->vertice_max_h); // XXX rm
+ }
+ }
+ if (!eobj) {
+ eobj = evas_object_line_add(eg->evas);
+ evas_object_color_set(eobj, 255, 0, 0, 255);
+ }
+ evas_object_smart_member_add(eobj, eg->obj);
+ evas_object_stack_below(eobj, eg->split_vertice_edge);
+ e->o = eobj;
+ _edge_signal(eg, e, "become_active");
+
+ e->a->edges = eina_list_append(e->a->edges, e);
+ e->b->edges = eina_list_append(e->b->edges, e);
+ _vertice_update_status(eg, e->a);
+ _vertice_update_status(eg, e->b);
+}
+
+void
+egraph_edge_type_set(Evas_Object *obj, Egraph_Edge *e, const char *type)
+{
+ EGRAPH_DATA_GET(obj, eg);
+
+ if (e->type)
+ free(e->type);
+
+ e->type = strndup(type, TYPE_MAXLEN);
+ if (eg->theme_edges && e->o) {
+ _edje_obj_set(eg, e->o, type);
+ }
+}
+
+static void
+_edge_signal(Egraph *eg, Egraph_Edge *e, const char *signal)
+{
+ if (eg->theme_edges && e->o);
+ edje_object_signal_emit(e->o, signal, "");
+}
+
+void
+egraph_edge_del(Evas_Object *obj, Egraph_Edge *e)
+{
+ EGRAPH_DATA_GET(obj, eg);
+
+ // XXX DEBUG find mem corrupt, del already del edge
+ if (!egraph_edge_find(obj, e->a, e->b))
+ printf("XXX DEBUG: egraph_edge_del on unknown edge !!!\n");
+ if (DEBUG)
+ printf("egraph_edge_del: %d %d\n", e->a->id, e->b->id);
+
+ e->v3_del = 1;
+ _layouting_schedule(eg);
+}
+
+static void
+_edge_v2_del(Egraph *eg, Egraph_Edge *e)
+{
+ igraph_es_t es;
+ int a_pos, b_pos;
+
+ if (e->v2_del == 1)
+ return;
+
+ if (DEBUG)
+ printf("_edge_v2_del %d %d\n", e->a->id, e->b->id);
+
+ e->v2_del = 1;
+ e->v3_del = 0;
+
+ if (!e->v3_new) {
+ a_pos = _igraph_query_vid(&eg->graph2, eg->graph2_vcount, e->a->id);
+ b_pos = _igraph_query_vid(&eg->graph2, eg->graph2_vcount, e->b->id);
+ igraph_es_pairs_small(&es, eg->graph_directed, a_pos, b_pos, -1);
+ igraph_delete_edges(&eg->graph2, es);
+ }
+}
+
+static void
+_edge_del(Egraph *eg, Egraph_Edge *e)
+{
+ igraph_es_t es;
+ int a_pos, b_pos;
+
+ if (!e->v3_new && !e->v2_new) {
+ a_pos = _igraph_query_vid(&eg->graph, eg->graph_vcount, e->a->id);
+ b_pos = _igraph_query_vid(&eg->graph, eg->graph_vcount, e->b->id);
+ igraph_es_pairs_small(&es, eg->graph_directed, a_pos, b_pos, -1);
+ igraph_delete_edges(&eg->graph, es);
+
+ e->a->edges = eina_list_remove(e->a->edges, e);
+ e->b->edges = eina_list_remove(e->b->edges, e);
+ _vertice_update_status(eg, e->a);
+ _vertice_update_status(eg, e->b);
+
+ evas_object_del(e->o);
+ }
+ eg->edges = eina_list_remove(eg->edges, e);
+ free(e);
+}
+
+Egraph_Edge *
+egraph_edge_find(Evas_Object *obj, Egraph_Vertice *a, Egraph_Vertice *b)
+{
+ EGRAPH_DATA_GET(obj, eg);
+ Egraph_Edge *e;
+ Eina_List *l;
+
+ EINA_LIST_FOREACH(eg->edges, l, e)
+ if (!(e->v3_del || e->v2_del) &&
+ ((e->a == a && e->b == b) ||
+ (e->a == b && e->b == a)))
+ return e;
+ return NULL;
+}
+
+Egraph_Vertice *
+egraph_vertice_add(Evas_Object *obj, const char *name, void *data)
+{
+ EGRAPH_DATA_GET(obj, eg);
+ Egraph_Vertice *v;
+ u_int32_t id;
+
+ if (eg->vertices_count == EGRAPH_VERTICES_MAX) {
+ printf("egraph error: maximum number of vertices reached !\n");
+ return NULL;
+ }
+ v = calloc(1, sizeof(Egraph_Vertice));
+ if (!v)
+ err(1, "egraph_vertice_add: cannot calloc");
+ id = eg->vertices_freeids[eg->vertices_count];
+ v->id = id;
+ eina_hash_add(eg->vertices, &id, v);
+ eg->vertices_count++;
+ v->v3_new = 1;
+ if (DEBUG)
+ printf("egraph_vertice_add %d\n", id);
+
+ if (name)
+ v->name = strndup(name, EGRAPH_VERTICE_NAME_MAXLEN);
+ egraph_vertice_type_set(obj, v, "vertice_normal");
+
+ v->data = data;
+
+ _layouting_schedule(eg);
+ return v;
+}
+
+static void
+_vertice_v2_add(Egraph *eg, Egraph_Vertice *v)
+{
+ v->v2_new = 1;
+ v->v3_new = 0;
+
+ igraph_add_vertices(&eg->graph2, 1, 0);
+ SETVAN(&eg->graph2, "id", eg->graph2_vcount, v->id);
+ eg->graph2_vcount++;
+}
+
+static void
+_vertice_add(Egraph *eg, Egraph_Vertice *v)
+{
+ Evas_Object *vobj = NULL;
+
+ v->new = 1;
+ v->v2_new = 0;
+
+ vobj = _edje_obj_new(eg, v->type);
+ if (!vobj) {
+ printf("egraph: could not load theme for vertice !");
+ v->v2_new = 1;
+ v->new = 0;
+ _vertice_v2_del(eg, v);
+ return;
+ }
+ evas_object_smart_member_add(vobj, eg->obj);
+ evas_object_stack_above(vobj, eg->split_vertice_edge);
+ evas_object_event_callback_add(vobj, EVAS_CALLBACK_MOVE, _cb_vertice_move, v);
+ v->o = vobj;
+ _vertice_geometry_update(eg, v);
+
+ igraph_add_vertices(&eg->graph, 1, 0);
+ SETVAN(&eg->graph, "id", eg->graph_vcount, v->id);
+ eg->graph_vcount++;
+
+ if (v->name)
+ egraph_vertice_rename(eg->obj, v, v->name);
+}
+
+void
+egraph_vertice_del(Evas_Object *obj, Egraph_Vertice *v)
+{
+ EGRAPH_DATA_GET(obj, eg);
+ Egraph_Edge *e;
+ Eina_List *l;
+
+ v->v3_del = 1;
+
+ EINA_LIST_FOREACH(eg->edges, l, e)
+ if (e->a == v || e->b == v)
+ egraph_edge_del(obj, e);
+
+ _layouting_schedule(eg);
+}
+
+static void
+_vertice_v2_del(Egraph *eg, Egraph_Vertice *v)
+{
+ Egraph_Edge *e;
+ Eina_List *l;
+ int pos;
+
+ if (v->v2_del == 1)
+ return;
+
+ v->v2_del = 1;
+ v->v3_del = 0;
+
+ if (DEBUG)
+ printf("_vertice_v2_del %d\n", v->id);
+ EINA_LIST_FOREACH(eg->edges, l, e)
+ if (e->a == v || e->b == v)
+ _edge_v2_del(eg, e);
+
+ if (!v->v3_new) {
+ pos = _igraph_query_vid(&eg->graph2, eg->graph2_vcount, v->id);
+ igraph_delete_vertices(&eg->graph2, igraph_vss_1(pos));
+ eg->graph2_vcount--;
+ }
+}
+
+static void
+_vertice_del(Egraph *eg, Egraph_Vertice *v)
+{
+ Egraph_Edge *e;
+ Eina_List *l, *lprev;
+ Evas_Object *blob;
+ int pos;
+
+ if (!v->v3_new && !v->v2_new) {
+ EINA_LIST_FOREACH_SAFE(eg->edges, l, lprev, e)
+ if (e->a == v || e->b == v)
+ _edge_del(eg, e);
+ eina_list_free(v->edges);
+
+ pos = _igraph_query_vid(&eg->graph, eg->graph_vcount, v->id);
+ igraph_delete_vertices(&eg->graph, igraph_vss_1(pos));
+ eg->graph_vcount--;
+
+ EINA_LIST_FOREACH(v->blobs_incoming, l, blob)
+ evas_object_del(blob);
+ eina_list_free(v->blobs_incoming);
+
+ evas_object_del(v->o);
+ }
+
+ eina_hash_del(eg->vertices, &v->id, NULL);
+ eg->vertices_count--;
+ eg->vertices_freeids[eg->vertices_count] = v->id;
+
+ free(v);
+}
+
+void
+egraph_vertice_type_set(Evas_Object *obj, Egraph_Vertice *v, const char *type)
+{
+ EGRAPH_DATA_GET(obj, eg);
+
+ if (v->type)
+ free(v->type);
+
+ v->type = strndup(type, TYPE_MAXLEN);
+ if (v->o)
+ _edje_obj_set(eg, v->o, type);
+}
+
+static void
+_vertice_update_status(Egraph *eg, Egraph_Vertice *v)
+{
+ Eina_List *l;
+ Egraph_Edge *e;
+ int status = 0;
+
+ if (v->is_group && (eina_list_count(v->edges) >= 1)) {
+ status = 1; /* we are a group with childs */
+ } else {
+ EINA_LIST_FOREACH(v->edges, l, e) {
+ if ((v == e->a && !e->b->is_group) ||
+ (v == e->b && !e->a->is_group)) {
+ status = 1; /* we are connected to at least on other non group node */
+ break;
+ }
+ }
+ }
+
+ if (status != v->status) {
+ if (status)
+ _vertice_signal(eg, v, "become_active");
+ else
+ _vertice_signal(eg, v, "become_inactive");
+ v->status = status;
+ }
+}
+
+static void
+_vertice_signal(Egraph *eg, Egraph_Vertice *v, const char *signal)
+{
+ if (v->o)
+ edje_object_signal_emit(v->o, signal, "");
+}
+
+void
+egraph_vertice_rename(Evas_Object *obj, Egraph_Vertice *v, const char *name)
+{
+ EGRAPH_DATA_GET(obj, eg);
+
+ if (eg->display_names == 0)
+ return;
+
+ if (name) {
+ if (v->name != name) {
+ if (v->name)
+ free(v->name);
+ v->name = strndup(name, EGRAPH_VERTICE_NAME_MAXLEN);
+ }
+ }
+ if (v->o) {
+ if (v->name)
+ edje_object_part_text_set(v->o, "label", v->name);
+ else
+ edje_object_part_text_set(v->o, "label", "");
+ _vertice_geometry_update(eg, v);
+ }
+}
+
+static void
+_vertice_geometry_update(Egraph *eg, Egraph_Vertice *v)
+{
+ int w, h;
+
+ edje_object_size_min_calc(v->o, &w, &h);
+ if (DEBUG)
+ printf("_vertice_geometry_update: %d %d\n", w, h);
+ evas_object_resize(v->o, w, h);
+ if (w > eg->vertice_max_w)
+ eg->vertice_max_w = w;
+ if (h > eg->vertice_max_h)
+ eg->vertice_max_h = h;
+ if (DEBUG)
+ printf("_vertice_geometry_update: end %d %d\n",
+ eg->vertice_max_w, eg->vertice_max_h);
+}
+
+void
+_color_int_to_rgb(u_int32_t color, int *r, int *g , int *b)
+{
+ *r = (color & 0xFF000000) >> 24;
+ *g = (color & 0x00FF0000) >> 16;
+ *b = (color & 0x0000FF00) >> 8;
+}
+
+void
+egraph_vertice_send_blob(Evas_Object *obj,
+ Egraph_Vertice *a, Egraph_Vertice *b,
+ int size, u_int32_t color)
+{
+ EGRAPH_DATA_GET(obj, eg);
+ Evas_Object *blob;
+ int ax, ay, aw, ah, bx, by, bw, bh;
+ int cr, cg, cb;
+
+ if (!a->o || !b->o)
+ return;
+ evas_object_geometry_get(a->o, &ax, &ay, &aw, &ah);
+ evas_object_geometry_get(b->o, &bx, &by, &bw, &bh);
+ _color_int_to_rgb(color, &cr, &cg, &cb);
+
+ blob = _edje_obj_new(eg, "blob");
+ if (!blob)
+ blob = evas_object_rectangle_add(eg->evas);
+ evas_object_color_set(blob, cr, cg, cb, 255);
+ evas_object_smart_member_add(blob, eg->obj);
+ evas_object_stack_above(blob, eg->split_vertice_edge);
+ evas_object_move(blob, ax, ay);
+ evas_object_resize(blob, size, size);
+ evas_object_show(blob);
+ b->blobs_incoming = eina_list_append(b->blobs_incoming, blob);
+ _blob_send(blob, b, bx, by);
+}
+
+static void
+_cb_blob_arrived(void *data, Efx_Map_Data *e, Evas_Object *obj)
+{
+ Egraph_Vertice *v;
+
+ v = data;
+ v->blobs_incoming = eina_list_remove(v->blobs_incoming, obj);
+ evas_object_del(obj);
+}
+
+static void
+_blob_send(Evas_Object *blob, Egraph_Vertice *v, Evas_Coord x, Evas_Coord y)
+{
+ if (DEBUG)
+ printf("blob_send %d %d\n", x, y);
+ efx_move(blob, EFX_EFFECT_SPEED_SINUSOIDAL,
+ &(Evas_Point){ x, y }, 0.6, _cb_blob_arrived, v);
+}
+
+static void
+_layouting_schedule(Egraph *eg)
+{
+ if (eg->layouting.running > 0) {
+ eg->layouting.todo = 1;
+ return;
+ }
+
+ eg->layouting.running = 1;
+ ecore_timer_add(0.0, _cb_layouting_start, eg); /* delayed start */
+}
+
+static void
+_v2_update(Egraph *eg)
+{
+ Eina_List *l, *lprev, *todel, *toadd;
+ Eina_Iterator *it;
+ Egraph_Vertice *v;
+ Egraph_Edge *e;
+ void *data;
+
+ /* update graph and structs based on v2_add / v2_del */
+ it = eina_hash_iterator_tuple_new(eg->vertices);
+ todel = NULL; toadd = NULL;
+ while (eina_iterator_next(it, &data)) {
+ Eina_Hash_Tuple *t = data;
+ v = t->data;
+ if (v->v2_del)
+ todel = eina_list_append(todel, v);
+ else if (v->v2_new)
+ toadd = eina_list_append(toadd, v);
+ }
+ eina_iterator_free(it);
+ EINA_LIST_FOREACH(todel, l, v)
+ _vertice_del(eg, v);
+ EINA_LIST_FOREACH(toadd, l, v)
+ _vertice_add(eg, v);
+ todel = eina_list_free(todel);
+ toadd = eina_list_free(toadd);
+ EINA_LIST_FOREACH_SAFE(eg->edges, l, lprev, e) {
+ if (e->v2_del)
+ _edge_del(eg, e);
+ else if (e->v2_new)
+ _edge_add(eg, e);
+ }
+}
+
+static void
+_v3_update(Egraph *eg)
+{
+ Eina_List *l, *lprev;
+ Eina_Iterator *it;
+ Egraph_Vertice *v;
+ Egraph_Edge *e;
+ void *data;
+ float ranx, rany;
+ int changes_count = 0;
+ int changes_diff = 0;
+ int i, id;
+
+ if (DEBUG)
+ printf("_v3_update\n");
+ /* update graph2 and structs based on v3_add / v3_del */
+ it = eina_hash_iterator_tuple_new(eg->vertices);
+ while (eina_iterator_next(it, &data)) {
+ Eina_Hash_Tuple *t = data;
+ v = t->data;
+ if (v->v3_del) {
+ _vertice_v2_del(eg, v); changes_diff--; changes_count++;
+ } else if (v->v3_new) {
+ _vertice_v2_add(eg, v); changes_diff++; changes_count++;
+ }
+ }
+ eina_iterator_free(it);
+ if (DEBUG)
+ printf("_v3_update edges\n");
+ EINA_LIST_FOREACH_SAFE(eg->edges, l, lprev, e) {
+ if (e->v3_del) {
+ _edge_v2_del(eg, e); changes_count++;
+ } else if (e->v3_new) {
+ _edge_v2_add(eg, e); changes_count++;
+ }
+ }
+
+ /* set correct coords2 size */
+ if (changes_diff > 0) {
+ for (i=0; i<changes_diff; i++) {
+ id = (eg->graph2_vcount - changes_diff) + i;
+ igraph_matrix_add_rows(&eg->coords2, 1);
+ ranx = eg->graph_wmin + fmod((float)random() / 1000, (float)((eg->graph_wmax + 1) - eg->graph_wmin));
+ rany = eg->graph_hmin + fmod((float)random() / 1000, (float)((eg->graph_hmax + 1) - eg->graph_hmin));
+ if (DEBUG)
+ printf("ranx %6.3f rany %6.3f\n", ranx, rany);
+ igraph_matrix_set(&eg->coords2, id, 0, ranx);
+ igraph_matrix_set(&eg->coords2, id, 1, rany);
+ }
+ } else if (changes_diff < 0) {
+ changes_diff = -changes_diff;
+ for (i=0; i<changes_diff; i++) {
+ id = (eg->graph2_vcount + changes_diff) - i;
+ igraph_matrix_remove_row(&eg->coords2, 0);
+ }
+ }
+
+ if (eg->layout == EGRAPH_LAYOUT_FRUCHTERMANREINGOLD) {
+ /* set minimum and maximum for each node */
+ /* XXX do that in layouting thread ? */
+ if (DEBUG)
+ printf("g wmin %d wmax %d hmin %d hmax %d\n",
+ eg->graph_wmin, eg->graph_wmax, eg->graph_hmin, eg->graph_hmax);
+ igraph_vector_init(&eg->graph2_wmin, eg->graph2_vcount);
+ igraph_vector_init(&eg->graph2_wmax, eg->graph2_vcount);
+ igraph_vector_init(&eg->graph2_hmin, eg->graph2_vcount);
+ igraph_vector_init(&eg->graph2_hmax, eg->graph2_vcount);
+ igraph_vector_fill(&eg->graph2_wmin, eg->graph_wmin);
+ igraph_vector_fill(&eg->graph2_wmax, eg->graph_wmax);
+ igraph_vector_fill(&eg->graph2_hmin, eg->graph_hmin);
+ igraph_vector_fill(&eg->graph2_hmax, eg->graph_hmax);
+ }
+
+ eg->layouting.changes_diff = changes_diff;
+}
+
+static Eina_Bool
+_cb_layouting_start(void *data)
+{
+ Egraph *eg;
+
+ eg = data;
+
+ eg->layouting.todo = 0;
+
+ _v3_update(eg);
+
+ eg->layouting.running = 2;
+ eg->layouting.thread = ecore_thread_run(_cb_layouting_run, _cb_layouting_end,
+ _cb_layouting_cancel, eg);
+
+ return EINA_FALSE; /* no repeat */
+}
+
+void
+_cb_layouting_run(void *data, Ecore_Thread *thread)
+{
+ Egraph *eg;
+ int niter;
+
+ eg = data;
+
+ if (DEBUG)
+ printf("[-] _cb_layouting_run begin (%d)\n", eg->layout);
+
+ switch(eg->layout) {
+ case EGRAPH_LAYOUT_KAMADAKAWAI:
+ if (eg->layouting.improvement) {
+ niter = 300;
+ } else {
+ if (eg->layouting.changes_diff == 0)
+ niter = 1000;
+ else
+ niter = 1000 * eg->layouting.changes_diff;
+ if (niter > 2000)
+ niter = 2000;
+ }
+ /* http://igraph.sourceforge.net/doc/html/ch18s01.html#igraph_layout_kamada_kawai
+ * int igraph_layout_kamada_kawai(const igraph_t *g, igraph_matrix_t *res,
+ * igraph_integer_t niter, igraph_real_t sigma,
+ * igraph_real_t initemp, igraph_real_t coolexp,
+ * igraph_real_t kkconst, igraph_bool_t use_seed,
+ * const igraph_vector_t *minx,
+ * const igraph_vector_t *maxx,
+ * const igraph_vector_t *miny,
+ * const igraph_vector_t *maxy);
+ * Defaults :
+ * igraph_layout_kamada_kawai(&eg->graph2, &eg->coords2,
+ * 1000, eg->vertices_count / 4, 10, 0.99,
+ * eg->vertices_count ^ 2, 1,
+ * NULL, NULL, NULL, NULL);
+ */
+ igraph_layout_kamada_kawai(&eg->graph2, &eg->coords2,
+ niter, eg->graph2_vcount, 10, 0.99,
+ eg->vertices_count ^ 2, 1,
+ NULL, NULL, NULL, NULL);
+ break;
+
+ case EGRAPH_LAYOUT_GRAPHOPT:
+ if (eg->layouting.improvement) {
+ niter = 300;
+ } else {
+ if (eg->layouting.changes_diff == 0)
+ niter = 100;
+ else
+ niter = 50 * eg->layouting.changes_diff;
+ if (niter > 500)
+ niter = 500;
+ }
+ /* http://igraph.sourceforge.net/doc/html/ch18s01.html#igraph_layout_graphopt
+ * int igraph_layout_graphopt(const igraph_t *g, igraph_matrix_t *res,
+ * igraph_integer_t niter,
+ * igraph_real_t node_charge, igraph_real_t node_mass,
+ * igraph_real_t spring_length,
+ * igraph_real_t spring_constant,
+ * igraph_real_t max_sa_movement,
+ * igraph_bool_t use_seed);
+ * Defaults :
+ * igraph_layout_graphopt(&eg->graph2, &eg->coords2,
+ * 1000, 0.001, 30, 0, 1, 5, 0);
+ */
+ igraph_layout_graphopt(&eg->graph2, &eg->coords2,
+ niter, 0.003, 10, 10, 1, 5, 1);
+ break;
+
+ case EGRAPH_LAYOUT_FRUCHTERMANREINGOLD:
+ niter = 1000;
+ /* http://igraph.sourceforge.net/doc/html/ch18s01.html#igraph_layout_fruchterman_reingold
+ * int igraph_layout_fruchterman_reingold(const igraph_t *graph, igraph_matrix_t *res,
+ * igraph_integer_t niter, igraph_real_t maxdelta,
+ * igraph_real_t area, igraph_real_t coolexp,
+ * igraph_real_t repulserad, igraph_bool_t use_seed,
+ * const igraph_vector_t *weight,
+ * const igraph_vector_t *minx,
+ * const igraph_vector_t *maxx,
+ * const igraph_vector_t *miny,
+ * const igraph_vector_t *maxy);
+ * Defaults:
+ * igraph_layout_fruchterman_reingold(&eg->graph2, &eg->coords2,
+ * 500, eg->graph2_vcount,
+ * sqrt(eg->graph2_vcount) * sqrt(eg->graph2_vcount), 1.5,
+ * eg->graph2_vcount, 0,
+ * NULL, NULL, NULL, NULL, NULL);
+ */
+ igraph_layout_fruchterman_reingold(&eg->graph2, &eg->coords2,
+ niter, 0.05,
+ sqrt(eg->graph2_vcount), 1.5,
+ sqrt(eg->graph2_vcount) * eg->graph2_vcount, 1,
+ NULL, NULL, NULL, NULL, NULL);
+ //&eg->graph2_wmin, &eg->graph2_wmax,
+ //&eg->graph2_hmin, &eg->graph2_hmax);
+ break;
+ }
+ if (DEBUG)
+ printf("[-] _cb_layouting_run end\n");
+}
+
+static void
+_coords2_copy(Egraph *eg)
+{
+ igraph_matrix_copy(&eg->coords, &eg->coords2);
+}
+
+void
+_cb_layouting_end(void *data, Ecore_Thread *thread)
+{
+ Egraph *eg;
+
+ eg = data;
+ _v2_update(eg);
+ _coords2_copy(eg);
+ _reposition(eg, 0);
+ eg->layouting.running = 0;
+ if (eg->layouting.todo) {
+ eg->layouting.todo = 0;
+ eg->layouting.improvement = 0;
+ _layouting_schedule(eg);
+ } else {
+ if (eg->do_improvements) {
+ if (eg->layouting.improvement < EGRAPH_LAYOUTING_IMPROVEMENTS) {
+ eg->layouting.improvement++;
+ _layouting_schedule(eg);
+ } else {
+ eg->layouting.improvement = 0;
+ }
+ }
+ }
+}
+
+void
+_cb_layouting_cancel(void *data, Ecore_Thread *thread)
+{
+ Egraph *eg;
+
+ eg = data;
+ eg->layouting.running = 0;
+ eg->layouting.todo = 0;
+ /* we are not in a clean state now, but it happends on exit only */
+}
+
+/* XXX slow ! possible to do edge/vertice delete on repositionning ? */
+static int
+_igraph_query_vid(igraph_t *g, int g_len, int id)
+{
+ int i;
+
+ for (i=0; i<g_len; i++) {
+ if (VAN(g, "id", i) == id)
+ return i;
+ }
+ printf("egraph: WARNING: _igraph_query_id %d not found !\n", id);
+ return -1;
+}
+
+/* Apply vertice move to it's edges */
+static void
+_cb_vertice_move(void *data, Evas *evas, Evas_Object *obj, void *event_info)
+{
+ EGRAPH_DATA_GET(evas_object_smart_parent_get(obj), eg);
+ Egraph_Vertice *v;
+ Egraph_Edge *e;
+ Evas_Map *m;
+ Eina_List *l;
+ int x, y, w, h;
+ int ax, ay, bx, by, aw, ah, bw, bh;
+ int p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y;
+ float a;
+
+ v = data;
+ evas_object_geometry_get(v->o, &x, &y, &w, &h);
+
+ EINA_LIST_FOREACH(v->edges, l, e) {
+ if (e->new) {
+ if (eg->display_edges)
+ evas_object_show(e->o);
+ e->new = 0;
+ }
+ if (e->o_usetheme) {
+ /* XXX we map the edges once per node = 2 times ... */
+ evas_object_move(e->o, x, y);
+ m = evas_map_new(4);
+ evas_map_smooth_set(m, 1);
+ evas_map_util_points_populate_from_object(m, e->o);
+ evas_object_geometry_get(e->a->o, &ax, &ay, &aw, &ah);
+ evas_object_geometry_get(e->b->o, &bx, &by, &bw, &bh);
+ ax = ax + aw / 2; ay = ay + ah / 2;
+ bx = bx + bw / 2; by = by + bh / 2;
+ aw = aw / 2; ah = ah / 2;
+ bw = bw / 2; bh = bh / 2;
+ /* rotate edge endpoints */
+ a = atan2(by - ay, bx - ax);
+#define ROTX(x, h, a) (-sin(a)*h + x)
+#define ROTY(y, h, a) (cos(a)*h + y)
+ p0x = ROTX(ax, ah, a); p0y = ROTY(ay, ah, a);
+ p1x = ROTX(ax, -ah, a); p1y = ROTY(ay, -ah, a);
+ p2x = ROTX(bx, bh, a); p2y = ROTY(by, bh, a);
+ p3x = ROTX(bx, -bh, a); p3y = ROTY(by, -bh, a);
+ /* set edge endpoints */
+ evas_map_point_coord_set(m, 0, p2x, p2y, 0);
+ evas_map_point_coord_set(m, 1, p0x, p0y, 0);
+ evas_map_point_coord_set(m, 2, p1x, p1y, 0);
+ evas_map_point_coord_set(m, 3, p3x, p3y, 0);
+ evas_object_map_set(e->o, m);
+ evas_object_map_enable_set(e->o, EINA_TRUE); // XXX do at init
+ evas_map_free(m);
+ } else {
+ evas_object_line_xy_get(e->o, &ax, &ay, &bx, &by);
+ if (e->a == v) {
+ ax = x + w/2;
+ ay = y + h/2;
+ } else {
+ bx = x + w/2;
+ by = y + h/2;
+ }
+ evas_object_line_xy_set(e->o, ax, ay, bx, by);
+ }
+ }
+}
+
+static void
+_reposition(Egraph *eg, int no_animation)
+{
+ Egraph_Vertice *v;
+ u_int32_t id;
+ float gw_min, gw_max, gh_min, gh_max, factor_w, factor_h;
+ float x, y;
+ int obj_x, obj_y, obj_w, obj_h;
+ int vcur;
+
+ if (DEBUG)
+ printf("[-] _reposition\n");
+ if (eg->graph_vcount == 0)
+ return;
+
+ evas_object_geometry_get(eg->obj, &obj_x, &obj_y, &obj_w, &obj_h);
+ _matrix_minmax_2v(&eg->coords, eg->graph_vcount,
+ &gw_min, &gw_max, &gh_min, &gh_max);
+ eg->graph_wmin = gw_min;
+ eg->graph_wmax = gw_max;
+ eg->graph_hmin = gh_min;
+ eg->graph_hmax = gh_max;
+
+ if (DEBUG)
+ printf("gw_min %6.3f gw_max %6.3f gh_min %6.3f gh_max %6.3f\n",
+ gw_min, gw_max, gh_min, gh_max);
+ if (gw_max == gw_min)
+ factor_w = 1;
+ else
+ factor_w = (obj_w - eg->vertice_max_w) / (gw_max - gw_min);
+ if (gh_max == gh_min)
+ factor_h = 1;
+ else
+ factor_h = (obj_h - eg->vertice_max_h) / (gh_max - gh_min);
+ if (DEBUG)
+ printf("factor_w %6.3f factor_h %6.3f\n", factor_w, factor_h);
+
+ for (vcur=0; vcur<eg->graph_vcount; vcur++) {
+ id = VAN(&eg->graph, "id", vcur);
+
+ x = MATRIX(eg->coords, vcur, 0);
+ y = MATRIX(eg->coords, vcur, 1);
+ if (DEBUG)
+ printf("%d: %6.3f %6.3f id %d\n", vcur, x, y, id);
+ x = obj_x + ((x - gw_min) * factor_w);
+ y = obj_y + ((y - gh_min) * factor_h);
+ if (DEBUG)
+ printf(" inobj: %6.3f %6.3f\n", x, y);
+
+ v = eina_hash_find(eg->vertices, &id);
+ if (eg->use_animations && !no_animation) {
+ efx_move(v->o, EFX_EFFECT_SPEED_DECELERATE,
+ &(Evas_Point){ x, y }, 0.5, NULL, NULL);
+ }
+ else
+ evas_object_move(v->o, x, y);
+ /* XXX fix blob repositionning
+ Evas_Object *blob;
+ Eina_List *l;
+ EINA_LIST_FOREACH(v->blobs_incoming, l, blob)
+ _blob_send(blob, v, x, y);
+ */
+ if (v->new) {
+ evas_object_show(v->o);
+ v->new = 0;
+ }
+ }
+}
+
+/**
+ * Compute minimum and maximum of a matrices of 2 colum vectors
+ *
+ * @note igraph is crazy in the coconut
+ */
+static void
+_matrix_minmax_2v(const igraph_matrix_t *m, int row_count,
+ float *c1min, float *c1max, float *c2min, float *c2max)
+{
+ float val;
+ int row;
+
+ *c1min=MATRIX(*m, 0, 0); *c1max=MATRIX(*m, 0, 0);
+ *c2min=MATRIX(*m, 0, 1); *c2max=MATRIX(*m, 0, 1);
+
+ for (row=1; row<row_count; row++) {
+ val = MATRIX(*m, row, 0);
+ if (val < *c1min) *c1min = val;
+ else if (val > *c1max) *c1max = val;
+ val = MATRIX(*m, row, 1);
+ if (val < *c2min) *c2min = val;
+ else if (val > *c2max) *c2max = val;
+ }
+}
+
+static Evas_Object *
+_edje_obj_new(Egraph *eg, const char *group)
+{
+ Evas_Object *obj;
+
+ obj = edje_object_add(eg->evas);
+ return _edje_obj_set(eg, obj, group);
+}
+
+static Evas_Object *
+_edje_obj_set(Egraph *eg, Evas_Object *obj, const char *group)
+{
+ if (!obj || !edje_object_file_set(obj, eg->theme_path, group)) {
+ int err = edje_object_load_error_get(obj);
+ const char *errmsg = edje_load_error_str(err);
+ if (DEBUG)
+ fprintf(stderr, "Could not load the edje file - reason:%s\n", errmsg);
+ return NULL;
+ }
+ return obj;
+}
+
+Egraph_Vertice *
+egraph_group_add(Evas_Object *obj, const char *name, void *data)
+{
+ Egraph_Vertice *g;
+
+ g = egraph_vertice_add(obj, name, data);
+ g->is_group = 1;
+ egraph_vertice_type_set(obj, g, "vertice_group");
+ return g;
+}
+
+int
+egraph_group_vertice_attach(Evas_Object *obj,
+ Egraph_Vertice *group, Egraph_Vertice *v)
+{
+ Egraph_Edge *e;
+
+ group->group_vertices = eina_list_append(group->group_vertices, v);
+ e = egraph_edge_add(obj, group, v, NULL);
+ egraph_edge_type_set(obj, e, "edge_group");
+ return 1;
+}
+
+void
+egraph_group_vertice_detach(Evas_Object *obj,
+ Egraph_Vertice *group, Egraph_Vertice *v)
+{
+ Egraph_Edge *e;
+
+ group->group_vertices = eina_list_remove(group->group_vertices, v);
+ e = egraph_edge_find(obj, group, v);
+ egraph_edge_del(obj, e);
+}
diff --git a/egraph/egraph.edc b/egraph/egraph.edc
new file mode 100644
index 0000000..399442a
--- /dev/null
+++ b/egraph/egraph.edc
@@ -0,0 +1,250 @@
+collections {
+ group {
+ name: "vertice_normal";
+ max: 700 700;
+ min: 700 700;
+ images {
+ image: "data/vertice.png" COMP;
+ }
+ parts {
+ part {
+ name: "image";
+ type: IMAGE;
+ description {
+ state: "default" 0.0;
+ max: 15 15;
+ min: 15 15;
+ image{
+ normal: "data/vertice.png";
+ }
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 1.0;
+ color: 255 255 255 100;
+ }
+ description {
+ state: "active" 1.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "label";
+ type: TEXT;
+ description {
+ state: "default" 0.0;
+ max: 50 8;
+ fixed: 1 1;
+ color: 200 255 0 50; /* yellow low */
+ text {
+ font: "vera";
+ size: 10;
+ min: 1 1;
+ }
+ rel1.to: "image";
+ rel1.relative: 0.5 1.0;
+ rel2.to: "image";
+ rel2.relative: 0.5 1.0;
+ rel2.offset: 0 8;
+ }
+ description {
+ state: "active" 1.0;
+ inherit: "default" 0.0;
+ color: 200 255 0 255; /* yellow visible */
+ }
+ }
+ }
+ programs {
+ program {
+ name: "state_active";
+ signal: "become_active";
+ source: "";
+ action: STATE_SET "active" 0.0;
+ target: "image";
+ target: "label";
+ transition: DECELERATE 0.5;
+ }
+ program {
+ name: "state_inactive";
+ signal: "become_inactive";
+ source: "";
+ action: STATE_SET "default" 0.0;
+ target: "image";
+ target: "label";
+ transition: DECELERATE 0.5;
+ }
+ }
+ }
+ group {
+ name: "vertice_group";
+ max: 700 700;
+ min: 700 700;
+ images {
+ image: "data/vertice.png" COMP;
+ }
+ parts {
+ part {
+ name: "image";
+ type: IMAGE;
+ description {
+ state: "default" 0.0;
+ max: 15 15;
+ min: 15 15;
+ image{
+ normal: "data/vertice.png";
+ }
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 1.0;
+ color: 160 120 40 70;
+ }
+ description {
+ state: "active" 1.0;
+ inherit: "default" 0.0;
+ color: 160 120 40 170;
+ }
+ }
+ part {
+ name: "label";
+ type: TEXT;
+ description {
+ state: "default" 0.0;
+ max: 50 8;
+ fixed: 1 1;
+ color: 160 120 40 70; /* yellow low */
+ text {
+ font: "vera";
+ size: 10;
+ min: 1 1;
+ }
+ rel1.to: "image";
+ rel1.relative: 0.5 1.0;
+ rel2.to: "image";
+ rel2.relative: 0.5 1.0;
+ rel2.offset: 0 8;
+ }
+ description {
+ state: "active" 1.0;
+ inherit: "default" 0.0;
+ color: 160 120 40 170; /* yellow visible */
+ }
+ }
+ }
+ programs {
+ program {
+ name: "state_active";
+ signal: "become_active";
+ action: STATE_SET "active" 0.0;
+ target: "image";
+ transition: DECELERATE 0.5;
+ }
+ program {
+ name: "state_inactive";
+ signal: "become_inactive";
+ action: STATE_SET "default" 0.0;
+ target: "image";
+ transition: DECELERATE 0.5;
+ }
+ }
+ }
+ group {
+ name: "edge_normal";
+ max: 700 700;
+ min: 700 700;
+ images {
+ image: "data/edge.png" COMP;
+ }
+ parts {
+ part {
+ name: "image";
+ type: IMAGE;
+ description {
+ state: "default" 0.0;
+ max: 50 10;
+ min: 50 10;
+ image{
+ normal: "data/edge.png";
+ }
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 1.0;
+ color: 255 255 255 50;
+ }
+ description {
+ state: "active" 1.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "state_active";
+ signal: "become_active";
+ action: STATE_SET "active" 0.0;
+ target: "image";
+ transition: DECELERATE 0.5;
+ }
+ }
+ }
+ group {
+ name: "edge_group";
+ max: 700 700;
+ min: 700 700;
+ images {
+ image: "data/edge.png" COMP;
+ }
+ parts {
+ part {
+ name: "image";
+ type: IMAGE;
+ description {
+ state: "default" 0.0;
+ max: 50 10;
+ min: 50 10;
+ image{
+ normal: "data/edge.png";
+ }
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 1.0;
+ color: 255 120 40 70;
+ }
+ description {
+ state: "active" 1.0;
+ inherit: "default" 0.0;
+ color: 255 120 40 170;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "state_active";
+ signal: "become_active";
+ action: STATE_SET "active" 0.0;
+ target: "image";
+ transition: DECELERATE 0.5;
+ }
+ }
+ }
+ group {
+ name: "blob";
+ max: 700 700;
+ min: 700 700;
+ images {
+ image: "data/blob.png" COMP;
+ }
+ parts {
+ part {
+ name: "image";
+ type: IMAGE;
+ description {
+ state: "default" 0.0;
+ max: 50 50;
+ min: 3 3;
+ image{
+ normal: "data/blob.png";
+ }
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 1.0;
+ }
+ }
+ }
+ }
+}
diff --git a/egraph/examples/Makefile b/egraph/examples/Makefile
new file mode 100644
index 0000000..9ac573e
--- /dev/null
+++ b/egraph/examples/Makefile
@@ -0,0 +1,12 @@
+CFLAGS += -Wall -g
+CFLAGS += $(shell pkg-config --libs --cflags elementary)
+CFLAGS += -L../ -legraph -lecore_evas
+
+SOURCES = $(shell echo *.c)
+OBJECTS = $(SOURCES:.c=.o)
+TARGETS = $(SOURCES:.c=)
+
+all: $(TARGETS)
+
+clean:
+ rm -f $(TARGETS) $(OBJECTS)
diff --git a/egraph/examples/demoapp.c b/egraph/examples/demoapp.c
new file mode 100644
index 0000000..4e64363
--- /dev/null
+++ b/egraph/examples/demoapp.c
@@ -0,0 +1,371 @@
+#include <err.h>
+
+#include <Elementary.h>
+#include <Egraph.h>
+
+Evas_Object *_mainwin;
+Evas_Object *_egraph;
+Eina_List *_vertice_list = NULL;
+Eina_List *_group_list = NULL;
+
+static void
+_cb_add_edge(void *data, Evas_Object *obj, void *event_info)
+{
+ Egraph_Vertice *a, *b;
+ int ran, count;
+ char buf[64];
+
+ if (!_egraph)
+ return;
+
+ count = eina_list_count(_vertice_list);
+ if (count == 0) {
+ a = egraph_vertice_add(_egraph, "first", NULL);
+ _vertice_list = eina_list_append(_vertice_list, a);
+ } else {
+ ran = random() % count;
+ a = eina_list_nth(_vertice_list, ran);
+ }
+ b = egraph_vertice_add(_egraph, NULL, NULL);
+ snprintf(buf, sizeof(buf), "%d", b->id);
+ egraph_vertice_rename(_egraph, b, buf);
+ _vertice_list = eina_list_append(_vertice_list, b);
+
+ egraph_edge_add(_egraph, a, b, NULL);
+}
+
+static void
+_cb_add_50edges(void *data, Evas_Object *obj, void *event_info)
+{
+ int i;
+
+ if (!_egraph)
+ return;
+
+ for (i=0; i<50; i++)
+ _cb_add_edge(data, obj, event_info);
+}
+
+static void
+_cb_add_500edges(void *data, Evas_Object *obj, void *event_info)
+{
+ int i;
+
+ if (!_egraph)
+ return;
+
+ for (i=0; i<500; i++)
+ _cb_add_edge(data, obj, event_info);
+}
+
+static void
+_cb_del_edges(void *data, Evas_Object *obj, void *event_info)
+{
+ Eina_List *l;
+ Egraph_Vertice *v;
+
+ if (!_egraph)
+ return;
+
+ egraph_clear(_egraph);
+ _vertice_list = eina_list_free(_vertice_list);
+ _group_list = eina_list_free(_group_list);
+}
+
+static void
+_cb_add_node(void *data, Evas_Object *obj, void *event_info)
+{
+ Egraph_Vertice *v;
+ char buf[64];
+
+ if (!_egraph)
+ return;
+
+ v = egraph_vertice_add(_egraph, NULL, NULL);
+ snprintf(buf, sizeof(buf), "%d", v->id);
+ egraph_vertice_rename(_egraph, v, buf);
+ _vertice_list = eina_list_append(_vertice_list, v);
+}
+
+static void
+_cb_send_100blobs(void *data, Evas_Object *obj, void *event_info)
+{
+ Egraph_Vertice *a, *b;
+ int count, ran, i;
+
+ count = eina_list_count(_vertice_list);
+ if (!count)
+ return;
+
+ for (i=0; i<100; i++) {
+ ran = random() % count;
+ a = eina_list_nth(_vertice_list, ran);
+ ran = random() % count;
+ b = eina_list_nth(_vertice_list, ran);
+ egraph_vertice_send_blob(_egraph, a, b, 5, 0xFF000000);
+ }
+}
+
+static void
+_cb_add_10n_group(void *data, Evas_Object *obj, void *event_info)
+{
+ Egraph_Vertice *group, *v;
+ char buf[64];
+ int i;
+
+ if (!_egraph)
+ return;
+
+ group = egraph_group_add(_egraph, NULL, NULL);
+ snprintf(buf, sizeof(buf), "%d-group", group->id);
+ egraph_vertice_rename(_egraph, group, buf);
+ _group_list = eina_list_append(_group_list, group);
+ for (i=0; i<10; i++) {
+ v = egraph_vertice_add(_egraph, NULL, NULL);
+ snprintf(buf, sizeof(buf), "%d-child(%d)", v->id, group->id);
+ egraph_vertice_rename(_egraph, v, buf);
+ egraph_group_vertice_attach(_egraph, group, v);
+ _vertice_list = eina_list_append(_vertice_list, v);
+ }
+}
+
+
+static void
+_cb_show_nodes(void *data, Evas_Object *obj, void *event_info)
+{
+ egraph_display_vertices_set(_egraph, elm_check_state_get(obj));
+}
+
+static void
+_cb_show_labels(void *data, Evas_Object *obj, void *event_info)
+{
+ if (!_egraph)
+ return;
+
+ egraph_display_names_set(_egraph, elm_check_state_get(obj));
+}
+
+static void
+_cb_show_edges(void *data, Evas_Object *obj, void *event_info)
+{
+ if (!_egraph)
+ return;
+
+ egraph_display_edges_set(_egraph, elm_check_state_get(obj));
+}
+
+static void
+_cb_use_animations(void *data, Evas_Object *obj, void *event_info)
+{
+ if (!_egraph)
+ return;
+
+ egraph_use_animations_set(_egraph, elm_check_state_get(obj));
+}
+
+static void
+_cb_do_improvements(void *data, Evas_Object *obj, void *event_info)
+{
+ if (!_egraph)
+ return;
+
+ egraph_do_improvements_set(_egraph, elm_check_state_get(obj));
+}
+
+static void
+_cb_use_theme_e(void *data, Evas_Object *obj, void *event_info)
+{
+ if (!_egraph)
+ return;
+
+ egraph_theme_edges_set(_egraph, elm_check_state_get(obj));
+}
+
+static void
+_cb_layout_changed(void *data, Evas_Object *obj, void *event_info)
+{
+ Elm_Object_Item *it;
+ char *selected;
+ int layout;
+
+ if (!_egraph)
+ return;
+
+ it = event_info;
+ selected = elm_object_item_text_get(it);
+ layout = EGRAPH_LAYOUT_DEFAULT;
+ if (!strcmp(selected, "Kamada K."))
+ layout = EGRAPH_LAYOUT_KAMADAKAWAI;
+ else if (!strcmp(selected, "GraphOpt"))
+ layout = EGRAPH_LAYOUT_GRAPHOPT;
+ else if (!strcmp(selected, "Fruchterman R."))
+ layout = EGRAPH_LAYOUT_FRUCHTERMANREINGOLD;
+
+ egraph_layout_set(_egraph, layout);
+}
+
+static void
+_cb_on_done(void *data, Evas_Object *obj, void *event_info)
+{
+ elm_exit();
+}
+
+EAPI_MAIN int
+elm_main(int argc, char **argv)
+{
+ Evas_Object *win, *bg, *egraph, *panes;
+ Evas_Object *bx, *tb, *tb_it, *ck, *sc, *seg_it, *lb;
+ Evas *evas;
+ int retval = -1;
+
+ win = elm_win_add(NULL, "panes", ELM_WIN_BASIC);
+ evas = evas_object_evas_get(win);
+ elm_win_title_set(win, "Egraph demo app");
+ evas_object_smart_callback_add(win, "delete,request", _cb_on_done, NULL);
+
+ bg = elm_bg_add(win);
+ elm_win_resize_object_add(win, bg);
+ evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_color_set(bg, 0, 0, 0, 255);
+ evas_object_show(bg);
+
+ bx = elm_box_add(win);
+ elm_box_horizontal_set(bx, EINA_TRUE);
+ evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_win_resize_object_add(win, bx);
+ evas_object_show(bx);
+
+ tb = elm_toolbar_add(win);
+ elm_toolbar_homogeneous_set(tb, EINA_FALSE);
+ elm_toolbar_horizontal_set(tb, EINA_FALSE);
+ elm_toolbar_shrink_mode_set(tb, ELM_TOOLBAR_SHRINK_EXPAND);
+ elm_toolbar_select_mode_set(tb, ELM_OBJECT_SELECT_MODE_ALWAYS);
+ elm_toolbar_transverse_expanded_set(tb, EINA_TRUE);
+ elm_object_style_set(tb, "item_centered");
+ evas_object_size_hint_weight_set(tb, 0.0, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ elm_box_pack_end(bx, tb);
+ evas_object_show(tb);
+ elm_toolbar_item_append(tb, "object-rotate-right", "Add 1 edge",
+ _cb_add_edge, NULL);
+ elm_toolbar_item_append(tb, "object-rotate-right", "Add 50 edges",
+ _cb_add_50edges, NULL);
+ elm_toolbar_item_append(tb, "object-rotate-right", "Add 500 edges",
+ _cb_add_500edges, NULL);
+ elm_toolbar_item_append(tb, "object-rotate-right", "Add 1 node alone",
+ _cb_add_node, NULL);
+ elm_toolbar_item_append(tb, "edit-delete", "Delete all",
+ _cb_del_edges, NULL);
+ elm_toolbar_item_append(tb, "object-rotate-right", "Send 100 blobs",
+ _cb_send_100blobs, NULL);
+ elm_toolbar_item_append(tb, "object-rotate-right", "Add a 10n group",
+ _cb_add_10n_group, NULL);
+ elm_toolbar_item_separator_set(elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL), EINA_FALSE);
+ lb = elm_label_add(win);
+ elm_object_text_set(lb, "<b>Layout</b>");
+ evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(lb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
+ elm_object_item_part_content_set(tb_it, "object", lb);
+ sc = elm_segment_control_add(win);
+ //evas_object_size_hint_weight_set(sc, em->weight.w, em->weight.h);
+ //evas_object_size_hint_align_set(sc, em->align.x, em->align.y);
+ seg_it = elm_segment_control_item_add(sc, NULL, "GraphOpt");
+ elm_segment_control_item_selected_set(seg_it, EINA_TRUE);
+ seg_it = elm_segment_control_item_add(sc, NULL, "Kamada K.");
+ elm_segment_control_item_selected_set(seg_it, EINA_FALSE);
+ seg_it = elm_segment_control_item_add(sc, NULL, "Fruchterman R.");
+ elm_segment_control_item_selected_set(seg_it, EINA_FALSE);
+ evas_object_smart_callback_add(sc, "changed", _cb_layout_changed, NULL);
+ evas_object_show(sc);
+ tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
+ elm_object_item_part_content_set(tb_it, "object", sc);
+ //elm_toolbar_item_separator_set(elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL), EINA_FALSE);
+ ck = elm_check_add(win);
+ elm_object_text_set(ck, "Show Node");
+ elm_check_state_set(ck, EINA_TRUE);
+ evas_object_show(ck);
+ evas_object_smart_callback_add(ck, "changed", _cb_show_nodes, NULL);
+ tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
+ elm_object_item_part_content_set(tb_it, "object", ck);
+ ck = elm_check_add(win);
+ elm_object_text_set(ck, "Show Label");
+ elm_check_state_set(ck, EINA_TRUE);
+ evas_object_show(ck);
+ evas_object_smart_callback_add(ck, "changed", _cb_show_labels, NULL);
+ tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
+ elm_object_item_part_content_set(tb_it, "object", ck);
+ ck = elm_check_add(win);
+ elm_object_text_set(ck, "Show Edges");
+ elm_check_state_set(ck, EINA_TRUE);
+ evas_object_show(ck);
+ evas_object_smart_callback_add(ck, "changed", _cb_show_edges, NULL);
+ tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
+ elm_object_item_part_content_set(tb_it, "object", ck);
+ ck = elm_check_add(win);
+ elm_object_text_set(ck, "Use animations");
+ elm_check_state_set(ck, EINA_TRUE);
+ evas_object_show(ck);
+ evas_object_smart_callback_add(ck, "changed", _cb_use_animations, NULL);
+ tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
+ elm_object_item_part_content_set(tb_it, "object", ck);
+ ck = elm_check_add(win);
+ elm_object_text_set(ck, "Do improvements");
+ elm_check_state_set(ck, EINA_TRUE);
+ evas_object_show(ck);
+ evas_object_smart_callback_add(ck, "changed", _cb_do_improvements, NULL);
+ tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
+ elm_object_item_part_content_set(tb_it, "object", ck);
+ ck = elm_check_add(win);
+ elm_object_text_set(ck, "Use theme for edges");
+ elm_check_state_set(ck, EINA_TRUE);
+ evas_object_show(ck);
+ evas_object_smart_callback_add(ck, "changed", _cb_use_theme_e, NULL);
+ tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
+ elm_object_item_part_content_set(tb_it, "object", ck);
+ //elm_toolbar_item_separator_set(elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL), EINA_FALSE);
+ elm_toolbar_item_append(tb, "exit", "Quit",
+ _cb_on_done, NULL);
+
+ panes = elm_panes_add(win);
+ evas_object_size_hint_weight_set(panes, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(panes, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ elm_panes_content_right_size_set(panes, 0.0);
+ elm_box_pack_end(bx, panes);
+ evas_object_show(panes);
+
+ egraph = egraph_new(evas, 1);
+ if (!egraph)
+ goto quit;
+ evas_object_size_hint_weight_set(egraph, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(egraph, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_show(egraph);
+ elm_object_part_content_set(panes, "left", egraph);
+
+ lb = elm_label_add(win);
+ elm_object_style_set(lb, "marker");
+ evas_object_color_set(lb, 255, 255, 255, 255);
+ elm_object_text_set(lb,
+ "Demo application for Egraph<br/>"
+ "<br/>"
+ "Enjoy !<br/>");
+ evas_object_show(lb);
+ elm_object_part_content_set(panes, "right", lb);
+
+ evas_object_resize(win, 150, 150); // XXX workaround elm sizing issue
+ evas_object_show(win);
+ evas_object_resize(win, 950, 715);
+ evas_object_show(win);
+ _egraph = egraph;
+ _mainwin = win;
+
+ _cb_add_50edges(NULL, NULL, NULL);
+
+ elm_run();
+ retval = 0;
+
+quit:
+ elm_shutdown();
+ return retval;
+}
+ELM_MAIN()
diff --git a/egraph/examples/simplegraph.c b/egraph/examples/simplegraph.c
new file mode 100644
index 0000000..43e6d59
--- /dev/null
+++ b/egraph/examples/simplegraph.c
@@ -0,0 +1,59 @@
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "../Egraph.h"
+
+Evas_Object *_egraph_obj = NULL;
+
+static void
+_on_destroy(Ecore_Evas *ee)
+{
+ ecore_main_loop_quit();
+}
+
+static void
+_canvas_resize_cb(Ecore_Evas *ee)
+{
+ int w, h;
+
+ printf("_canvas_resize_cb\n");
+ ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+ evas_object_resize(_egraph_obj, w, h);
+}
+
+int
+main(void)
+{
+ Ecore_Evas *ee;
+ Evas *evas;
+ Egraph_Vertice *a, *b;
+ Egraph_Edge *e;
+
+ if (!ecore_evas_init())
+ return EXIT_FAILURE;
+ ee = ecore_evas_new(NULL, 10, 10, 100, 100, NULL);
+ if (!ee)
+ return -1;
+ ecore_evas_callback_destroy_set(ee, _on_destroy);
+ ecore_evas_callback_resize_set(ee, _canvas_resize_cb);
+ ecore_evas_show(ee);
+ evas = ecore_evas_get(ee);
+
+ _egraph_obj = egraph_new(evas, 1);
+ evas_object_resize(_egraph_obj, 100, 100);
+ evas_object_show(_egraph_obj);
+
+ a = egraph_vertice_add(_egraph_obj, "a", NULL);
+ b = egraph_vertice_add(_egraph_obj, "b", NULL);
+ e = egraph_edge_add(_egraph_obj, a, b, NULL);
+
+ ecore_main_loop_begin();
+
+ evas_object_del(_egraph_obj);
+ ecore_evas_free(ee);
+ ecore_evas_shutdown();
+
+ return (!_egraph_obj);
+}
diff --git a/egraph/retest.sh b/egraph/retest.sh
new file mode 100755
index 0000000..c778fa1
--- /dev/null
+++ b/egraph/retest.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+make clean && \
+ make && \
+ sudo make install && \
+ make -C tests/ clean && \
+ make -C tests/ run && \
+ make -C examples clean && \
+ make -C examples
diff --git a/egraph/tests/Makefile b/egraph/tests/Makefile
new file mode 100644
index 0000000..8b70170
--- /dev/null
+++ b/egraph/tests/Makefile
@@ -0,0 +1,32 @@
+CFLAGS += -Wall -g
+CFLAGS += $(shell pkg-config --libs --cflags igraph)
+CFLAGS += $(shell pkg-config --libs --cflags efx)
+CFLAGS += -L../ -legraph -lecore_evas
+
+SOURCES = $(shell echo *.c)
+OBJECTS = $(SOURCES:.c=.o)
+TARGETS = $(SOURCES:.c=)
+
+all: $(TARGETS)
+
+run: $(TARGETS)
+ @count=0 ;\
+ errors=0 ;\
+ for test in $(TARGETS); do \
+ echo =============================================================================== ;\
+ echo $$test ;\
+ LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:../ ./$$test ;\
+ if [ $$? -eq 0 ]; then \
+ echo OK ;\
+ else \
+ echo FAILED ;\
+ errors=$$(($$errors + 1)) ;\
+ fi ;\
+ count=$$(($$count + 1)) ;\
+ done ;\
+ echo =============================================================================== ;\
+ echo "$$count tests executed, $$errors errors" ;\
+ exit $$errors
+
+clean:
+ rm -f $(TARGETS) $(OBJECTS)
diff --git a/egraph/tests/README.txt b/egraph/tests/README.txt
new file mode 100644
index 0000000..9a25111
--- /dev/null
+++ b/egraph/tests/README.txt
@@ -0,0 +1,4 @@
+egraph library unit tests
+
+do "make run" to execute them
+returns the number of tests that failed
diff --git a/egraph/tests/creategraph.c b/egraph/tests/creategraph.c
new file mode 100644
index 0000000..d27e3d5
--- /dev/null
+++ b/egraph/tests/creategraph.c
@@ -0,0 +1,37 @@
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "../Egraph.h"
+
+int
+main(void)
+{
+ Ecore_Evas *ee;
+ Evas *evas;
+ Evas_Object *obj = NULL;
+ Egraph_Vertice *a, *b;
+ Egraph_Edge *e;
+
+ if (!ecore_evas_init())
+ return EXIT_FAILURE;
+ ee = ecore_evas_new(NULL, 10, 10, 100, 100, NULL);
+ if (!ee)
+ return -1;
+ ecore_evas_show(ee);
+ evas = ecore_evas_get(ee);
+
+ obj = egraph_new(evas, 1);
+
+ a = egraph_vertice_add(obj, "a", NULL);
+ b = egraph_vertice_add(obj, NULL, NULL);
+ e = egraph_edge_add(obj, a, b, NULL);
+ egraph_vertice_del(obj, a);
+
+ evas_object_del(obj);
+ ecore_evas_free(ee);
+ ecore_evas_shutdown();
+
+ return (!obj);
+}