summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Ghigonis <laurent@p1sec.com>2013-03-19 13:14:13 +0100
committerLaurent Ghigonis <laurent@p1sec.com>2013-03-19 13:14:13 +0100
commitd20f8e455bd447ffdc9d938cdf448ec6cef0af26 (patch)
tree15825096badec56a1f3113c3fc92759c3f29fead
initial import for egraph
egraph - library for rendering dynamic graphs in evas take a look at examples/demoapp.c for a demo app using Elementary (make -C examples) see README
-rw-r--r--AUTHORS1
-rw-r--r--COPYING15
-rw-r--r--Egraph.h233
-rw-r--r--Makefile36
-rw-r--r--README47
-rw-r--r--data/blob.pngbin0 -> 3649 bytes
-rw-r--r--data/edge.pngbin0 -> 372 bytes
-rw-r--r--data/edge.xcfbin0 -> 8278 bytes
-rw-r--r--data/vertice.pngbin0 -> 4488 bytes
-rw-r--r--doc/TODO.txt118
-rw-r--r--doc/bug_lockup_evas.txt646
-rw-r--r--doc/egraph.xojbin0 -> 105411 bytes
-rw-r--r--doc/internals.txt89
-rw-r--r--egraph.c1275
-rw-r--r--egraph.edc250
-rw-r--r--examples/Makefile12
-rw-r--r--examples/demoapp.c371
-rw-r--r--examples/simplegraph.c59
-rwxr-xr-xretest.sh9
-rw-r--r--tests/Makefile32
-rw-r--r--tests/README.txt4
-rw-r--r--tests/creategraph.c37
22 files changed, 3234 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..4e42cdc
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
Laurent Ghigonis <laurent@p1sec.com>
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..bae178d
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,15 @@
1/*
2 * Copyright (c) 2012 Laurent Ghigonis <laurent@p1sec.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
diff --git a/Egraph.h b/Egraph.h
new file mode 100644
index 0000000..553d5cd
--- /dev/null
+++ b/Egraph.h
@@ -0,0 +1,233 @@
1#include <Eina.h>
2#include <Evas.h>
3#include <Ecore.h>
4#include <igraph/igraph.h>
5
6#define EGRAPH_VERTICES_MAX 16384 /* cannot be more that u_int32_t */
7#define EGRAPH_VERTICE_NAME_MAXLEN 60
8
9typedef struct Egraph Egraph;
10typedef struct Egraph_Edge Egraph_Edge;
11typedef struct Egraph_Vertice Egraph_Vertice;
12
13typedef enum {
14 EGRAPH_LAYOUT_GRAPHOPT = 0,
15 EGRAPH_LAYOUT_KAMADAKAWAI = 1,
16 EGRAPH_LAYOUT_FRUCHTERMANREINGOLD = 2,
17} Egraph_Layout;
18#define EGRAPH_LAYOUT_DEFAULT EGRAPH_LAYOUT_GRAPHOPT
19#define EGRAPH_LAYOUTING_IMPROVEMENTS 5
20
21struct Egraph {
22 Evas_Object_Smart_Clipped_Data __clipped_data;
23 Evas_Object *obj;
24 Evas_Object *split_vertice_edge;
25 Evas *evas;
26 int graph_directed;
27 int display_vertices;
28 int display_names;
29 int display_edges;
30 int use_animations;
31 int do_improvements;
32 char *theme_path;
33 int theme_edges;
34 Egraph_Layout layout;
35 struct {
36 Ecore_Thread *thread;
37 int running;
38 int todo;
39 int changes_diff;
40 int improvement; /* special pass to improve the graph layout */
41 } layouting;
42 Eina_Hash *vertices;
43 int vertices_count;
44 u_int32_t vertices_freeids[EGRAPH_VERTICES_MAX];
45 int vertice_max_w;
46 int vertice_max_h;
47 Eina_List *edges;
48 igraph_t graph;
49 int graph_vcount;
50 igraph_matrix_t coords;
51 igraph_t graph2; // XXX remove use of graph here, see _repos()
52 int graph2_vcount;
53 igraph_vector_t graph2_wmin, graph2_wmax, graph2_hmin, graph2_hmax;
54 int graph_wmin, graph_wmax, graph_hmin, graph_hmax;
55 igraph_matrix_t coords2;
56};
57
58struct Egraph_Vertice {
59 u_int32_t id;
60 char *name;
61 char *type;
62 u_int status : 1;
63 Evas_Object *o;
64 Eina_List *edges;
65 Eina_List *blobs_incoming;
66 void *data;
67 u_int is_group : 1;
68 Eina_List *group_vertices; /* used if the vertice is a group */
69 u_int new : 1;
70 u_int v2_new : 1;
71 u_int v2_del : 1;
72 u_int v3_new : 1;
73 u_int v3_del : 1;
74};
75
76struct Egraph_Edge {
77 Egraph_Vertice *a;
78 Egraph_Vertice *b;
79 char *type;
80 Evas_Object *o;
81 u_int o_usetheme : 1;
82 void *data;
83 u_int new : 1;
84 u_int v2_new : 1;
85 u_int v2_del : 1;
86 u_int v3_new : 1;
87 u_int v3_del : 1;
88};
89
90/**
91 * Creates Egraph Evas_Object
92 */
93Evas_Object *egraph_new(Evas *evas, int directed);
94
95/**
96 * Remove all nodes and edges
97 */
98void egraph_clear(Evas_Object *obj);
99
100/**
101 * Configure egraph to use an edje theme
102 */
103void egraph_theme_file_set(Evas_Object *obj, char *path);
104
105/**
106 * Sets if egraph should theme the edges
107 */
108void egraph_theme_edges_set(Evas_Object *obj, int set);
109
110/**
111 * Sets the layout of Egraph
112 */
113void egraph_layout_set(Evas_Object *obj, Egraph_Layout layout);
114
115/**
116 * Configure if Egraph should display vertices
117 */
118void egraph_display_vertices_set(Evas_Object *obj, int set);
119
120/**
121 * Configure if Egraph should display vertices names
122 */
123void egraph_display_names_set(Evas_Object *obj, int set);
124
125/**
126 * Configure if Egraph should display edges
127 */
128void egraph_display_edges_set(Evas_Object *obj, int set);
129
130/**
131 * Configure if Egraph should use animations
132 */
133void egraph_use_animations_set(Evas_Object *obj, int set);
134
135/**
136 * Configure if Egraph should do improvements after a graph change
137 */
138void egraph_do_improvements_set(Evas_Object *obj, int set);
139
140/**
141 * Adds an edge between existing vertices
142 *
143 * @param obj The Egraph object
144 * @param a First vertice
145 * @param b Second vertice
146 * @param data The pointer to attach
147 * @return The new Egraph_Egde object
148 */
149Egraph_Edge *egraph_edge_add(Evas_Object *obj,
150 Egraph_Vertice *a, Egraph_Vertice *b, void *data);
151
152/**
153 * Delete an edge
154 *
155 * Hint: This does not delete vertices
156 */
157void egraph_edge_del(Evas_Object *obj, Egraph_Edge *e);
158
159/**
160 * Sets the type of an edge, to make it appear differently in the graph,
161 * depending on theme
162 */
163void egraph_edge_type_set(Evas_Object *obj,
164 Egraph_Edge *e, const char *type);
165/**
166 * Finds if an edge exists between 2 vertices
167 */
168Egraph_Edge *egraph_edge_find(Evas_Object *obj,
169 Egraph_Vertice *a, Egraph_Vertice *b);
170
171/**
172 * Add a vertice to the graph
173 *
174 * @param obj The Egraph object
175 * @param name The name of the vertice to be displayed. If NULL, no name is
176 * displayed
177 * @param data The pointer to attach
178 */
179Egraph_Vertice *egraph_vertice_add(Evas_Object *obj,
180 const char *name, void *data);
181
182/**
183 * Delete a vertice
184 *
185 * Hint: Also deletes all the edges attached to it
186 *
187 * @param obj The Egraph object
188 * @todo add user callback where edges are deleted
189 */
190void egraph_vertice_del(Evas_Object *obj, Egraph_Vertice *v);
191
192/**
193 * Update the name of a vertice
194 */
195void egraph_vertice_rename(Evas_Object *obj, Egraph_Vertice *v,
196 const char *name);
197
198/**
199 * Sets the type of a vertice, to make it appear differently in the graph,
200 * depending on theme
201 */
202void
203egraph_vertice_type_set(Evas_Object *obj, Egraph_Vertice *v, const char *type);
204
205 /**
206 * Send a blob from vertice to vertice
207 *
208 * A blob is a visual object that will move quickly from the first node to the
209 * second node.
210 */
211void egraph_vertice_send_blob(Evas_Object *obj,
212 Egraph_Vertice *a, Egraph_Vertice *b,
213 int size, u_int32_t color);
214
215/**
216 * Add a group of vertices, for later attaching nodes to it.
217 *
218 * The group is represented by an Egraph_Vertice with special properties.
219 */
220Egraph_Vertice *egraph_group_add(Evas_Object *obj,
221 const char *name, void *data);
222
223/**
224 * Attach a vertice to a group
225 */
226int egraph_group_vertice_attach(Evas_Object *obj,
227 Egraph_Vertice *group, Egraph_Vertice *v);
228
229/**
230 * Detach a vertice from a group
231 */
232void egraph_group_vertice_detach(Evas_Object *obj,
233 Egraph_Vertice *group, Egraph_Vertice *v);
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..99e8310
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,36 @@
1# CFLAGS += -Werror -Wall -O2 -fPIC -shared -g
2CFLAGS += -Werror -Wall -fPIC -shared -g
3CFLAGS += $(shell pkg-config --libs --cflags edje efx igraph)
4
5PREFIX=/usr/local
6INCLUDEDIR=$(PREFIX)/include
7SHAREDIR=$(PREFIX)/share/egraph
8LIBDIR=$(PREFIX)/lib
9
10SOURCES = egraph.c
11HEADERS = Egraph.h
12EDC = egraph.edc
13EDJ = $(EDC:.edc=.edj)
14OBJECTS = $(SOURCES:.c=.o)
15LIBNAME = libegraph
16TARGET = ${LIBNAME}.so
17
18all: $(TARGET) $(EDJ)
19
20$(TARGET): $(OBJECTS)
21 $(CC) $(CFLAGS) -o $(TARGET) $(OBJECTS)
22
23$(EDJ):
24 edje_cc $(EDC) $(EDJ)
25
26install:
27 @echo "installation of $(LIBNAME)"
28 mkdir -p $(LIBDIR)
29 mkdir -p $(INCLUDEDIR)
30 mkdir -p $(SHAREDIR)
31 install -m 0644 $(TARGET) $(LIBDIR)
32 install -m 0644 $(HEADERS) $(INCLUDEDIR)
33 install -m 0644 $(EDJ) $(SHAREDIR)
34
35clean:
36 rm -f $(TARGET) $(OBJECTS) $(EDJ)
diff --git a/README b/README
new file mode 100644
index 0000000..4f15401
--- /dev/null
+++ b/README
@@ -0,0 +1,47 @@
1egraph - library for rendering dynamic graphs in evas
2
3Requirements
4============
5
6* Enlightenment Foundation Libraries
7http://www.enlightenment.org
8 * eina
9 * evas
10 * ecore
11 * efx
12
13* igraph v0.6
14http://igraph.sourceforge.net/index.html
15 * for Ubuntu: v0.6 is *not* available in ubuntu packages
16You can download it here :
17http://sourceforge.net/projects/igraph/files/C%20library/0.6/igraph-0.6.tar.gz/download
18 * for Archlinux: yaourt -S igraph
19
20Installation
21============
22
23make
24sudo make install
25
26You can run the demoapp in examples :
27make -C examples
28./examples/demoapp
29
30You can use OpenGL rendering :
31ELM_ENGINE=opengl_x11 ./examples/demoapp
32
33Thanks
34======
35
36Thanks to ntamas (http://sixdegrees.hu/) for her advices on igraph.
37Thanks to cedric for tech advices on evas / edje.
38Thanks to vtorri for tech advices on evas / edje.
39Thanks to zmike for tech advices on efx.
40Thanks to raster for tech advices on evas / elementary.
41Thanks to ludivina for graphical advices.
42
43History
44=======
45
46Egraph was developped for the Glouglou Network Map (gg_map), a tool for
47live computer network visualisation based on the Glouglou framework.
diff --git a/data/blob.png b/data/blob.png
new file mode 100644
index 0000000..96e4aff
--- /dev/null
+++ b/data/blob.png
Binary files differ
diff --git a/data/edge.png b/data/edge.png
new file mode 100644
index 0000000..f6bbfc4
--- /dev/null
+++ b/data/edge.png
Binary files differ
diff --git a/data/edge.xcf b/data/edge.xcf
new file mode 100644
index 0000000..9481336
--- /dev/null
+++ b/data/edge.xcf
Binary files differ
diff --git a/data/vertice.png b/data/vertice.png
new file mode 100644
index 0000000..54c556b
--- /dev/null
+++ b/data/vertice.png
Binary files differ
diff --git a/doc/TODO.txt b/doc/TODO.txt
new file mode 100644
index 0000000..beed508
--- /dev/null
+++ b/doc/TODO.txt
@@ -0,0 +1,118 @@
1CURRENT
2=======
3
4vertice / vertice_text visibility will be broken
5need to implement it in the edje object and send signals
6
7* BUG: show nodes labels does not show old nodes labels
8reproduce: do not show labels, add edges, show label, add edges
9
10* BUG: layer stacking is wrong, edges end up on top of nodes, despite
11eg->split_vertice_edge
12
13* BUG: vertices / vertices text fight for being on top. use evas layers ?
14add 500 edges to reproduce, and watch the nodes
15
16TODO
17====
18
19* missing function declaration for static _color_int_to_rgb()
20* reorder static funcs
21
22* BUG: sometimes when you add nodes during layouting, the graph is broken
23a new edge attaches to the wrong new vertice
24it seems to be always the same node numbers that gets this wrong edge
25
26* BUG: EGRAPH_LAYOUT_FRUCHTERMANREINGOLD is broken when adding many edges
27
28* zoom
2910:16 < glouglou> i want to implement zooming with mouse scroll, do you have some ideas about that ?
3010:16 < zmike> that should be trivial
3110:16 < zmike> just hook mouse wheel and use efx_zoom
3210:18 < glouglou> does efx_zoom resize the objects ?
3310:18 < glouglou> all the graph is one evas smart object
3410:18 < zmike> it does not resize, it just maps
3510:18 < glouglou> that clips everything
3610:18 < zmike> it should work, you can see the elm test is working, and that uses smart objects
3710:18 < glouglou> yeah i want to update the coordinates i guess, not really "zoom"
3810:19 < zmike> hm there's no efx_scale yet, but you could use efx_resize I would think
3910:19 < glouglou> i would prefer to resize / update the coords
4010:19 < glouglou> scale yes, that would be it
4110:19 < glouglou> ok
4210:19 < zmike> just calculate the size you want and use efx_resize
4310:20 < zmike> it will animate the resizing
44
45* blobs
4605: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
4705:17 < glouglou> j'ai regarde un peu dans efx mais j'ai pas trouve de bon moyen
4805:18 < glouglou> il faudrait que les paquets ne puissent pas sortir de l'edge (le trait) entre les 2 nodes
4905:18 < glouglou> si tu as une idee ...
5005:22 -!- Munto [~frugal@2a01:e35:139d:91e0:221:85ff:fee1:5c3c] has quit [Read error: Connection reset by peer]
5105:33 -!- sharinganex [~sharingan@233.208.85.79.rev.sfr.net] has joined #e.fr
5206:22 <@cedric> glouglou: oui, swallow un smart objet
5306:22 <@cedric> qui n'a qu'une seule tache faire bouger des paquets de haut en bas et de bas en haut
5406:22 <@cedric> parcontre ca a un probleme, la taille des objets de tes paquets est limite par la taille de ton objet edje parent
5506: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 ?
5606:40 < glouglou> et complexe
5706:40 < glouglou> mais c'est vrai que ca resous mon probleme
5806:41 <@cedric> bah, de toute facon, tu vas avoir une surface cree pour mettre ton edje dans ta map
5906:41 <@cedric> dc ca reviendra au meme voir tu fairas l'economie d'une surface
6006: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 ?
6106: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 ?
6206:52 <@cedric> oui
6306:52 < glouglou> mais c'est magnifique
6406:52 < glouglou> et splendide a fois
6506:53 < glouglou> merci :D
66
67TODO LATER
68==========
69
70* find a better storage type for vertices
71quick access O(1) -> table
72possibility to foreach and remove at the same time
73
74* possible future API: no edges no vertices for the user
75
76struct Egraph_Vertice {
77 const char *name;
78 int vertice_id;
79 Evas_Object *o;
80 void *data;
81}
82egraph_vertice_add(Egraph *eg, const char *name, void *data);
83egraph_edge_add(Egraph *eg,
84 const char *a, const char *b, void *data);
85
86* speed: draw directly to a surface and map to evas via invisible polygons
87see elementary/src/bin/test_gesture_layer3.c
8804: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
89 graph, like click click reaction, so i guess i cannot escape from creating one evas object for each node and edge
9004:46 <@raster> trick:
9104:47 <@raster> u can just create invisible rects
9204:47 < glouglou> (i can imagine crazy mapping of the clicks on my surface that triggers evas callbacks, but i'm not that crazy)
9304:47 <@raster> and overlay them on your image
9404:47 <@raster> use them for event stuff
9504:47 < glouglou> lol
9604:47 <@raster> or polygons tyoo
9704:47 <@raster> thats about the only use of polygons
9804:47 <@raster> as u can do exact inside/outside poly checks for events
9904:48 < glouglou> i think you are talking about the crazy things i don't want to do :p
10004:48 <@raster> one of the elm demos does this
10104:48 <@raster> for soming/rotating with little photos
10204:48 <@raster> multitouch test stuff
103
104* speed: from Thanatermesis :
105the Core library (https://github.com/acaudwell/Core)
106renders to OpenGL directly
107used by :
108http://code.google.com/p/logstalgia/
109https://github.com/acaudwell/Gource (http://code.google.com/p/gource/)
110
111OLD
112===
113
114* speed: evas_object_rectangles
11504:40 <@raster> they add clipoouts
11604:41 <@raster> make them just a bit translucent
11704:41 <@raster> and it'll be faster
118
diff --git a/doc/bug_lockup_evas.txt b/doc/bug_lockup_evas.txt
new file mode 100644
index 0000000..4f194c5
--- /dev/null
+++ b/doc/bug_lockup_evas.txt
@@ -0,0 +1,646 @@
1===============================================================================
2This bug is a lockup of evas during rendering in my efl app.
3App freeze and takes 100% CPU. Below are backtraces when gdb was running and
4I interrupt it with Ctrl-C.
5
6At the time of crash, around 300objects total :
7elementary interface + ~100 edje + ~100 evas_object_line
8
9This crash is not predictible from what I see, sometimes it goes fine for a long
10time.
11It seem to crash more when using more edje objects.
12
13svn info
14Revision: 79909
15
16uname -a
17Linux balboa 3.6.7-1-ARCH #1 SMP PREEMPT Sun Nov 18 10:11:22 CET 2012 x86_64 GNU/Linux
18
19===============================================================================
202012-12-09_18-10
21
22ELM_ENGINE=opengl_x11 gdb ./examples/demoapp
23run
24
25// use the app, and it locks up during an animation (app takes 100% CPU)
26// Ctrl-C
27
28(gdb) bt
29#0 0x00007ffff7233fe6 in _calc_intra_outer_rect_area (outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...) at lib/evas/common/evas_tiler.c:468
30#1 rect_list_add_split_fuzzy (node=0x1967160, rects=0xdf91a8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:652
31#2 rect_list_add_split_fuzzy_and_merge (node=0x1967160, rects=0xdf91a8, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
32 at lib/evas/common/evas_tiler.c:849
33#3 _add_redraw (h=16, w=24, y=200, x=882, rects=0xdf91a8) at lib/evas/common/evas_tiler.c:956
34#4 evas_common_tilebuf_add_redraw (tb=0xdf9170, x=882, y=200, w=24, h=16) at lib/evas/common/evas_tiler.c:986
35#5 0x00007ffff71b2af2 in evas_object_render_pre_effect_updates (rects=0x68ad48, eo_obj=<optimized out>, is_v=1, was_v=<optimized out>)
36 at lib/evas/canvas/evas_object_main.c:343
37#6 0x00007ffff71f1bfc in _evas_render_phase1_direct (render_objects=0x1498d30, active_objects=0x68ab50, e=<optimized out>, restack_objects=<optimized out>,
38 delete_objects=<optimized out>) at lib/evas/canvas/evas_render.c:231
39#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
40#8 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
41#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
42#10 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe1b8, op_type=EO_OP_TYPE_REGULAR, obj=0x68aac0) at lib/eo/eo.c:403
43#11 eo_do_internal (obj=0x68aac0, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
44#12 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
45#13 0x00007fffe73da43a in _ecore_evas_x_render (ee=0x6892f0) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
46#14 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
47#15 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
48#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
49#17 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
50#18 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
51#19 0x00000000004027bf in elm_main (argc=1, argv=0x7fffffffe568) at demoapp.c:248
52#20 0x0000000000402804 in main (argc=1, argv=0x7fffffffe568) at demoapp.c:255
53
54===============================================================================
55
56===============================================================================
572012-12-10_15-48
58
59ELM_ENGINE=opengl_x11 gdb ./examples/demoapp
60run
61
62// use the app, and it locks up during an animation (app takes 100% CPU)
63// Ctrl-C
64
65^C
66Program received signal SIGINT, Interrupt.
670x00007ffff7233fd3 in rect_list_add_split_fuzzy (node=0x1ce6300, rects=0x9c49b8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:650
68650 current = ((rect_node_t *)cur_node)->rect;
69(gdb) bt
70#0 0x00007ffff7233fd3 in rect_list_add_split_fuzzy (node=0x1ce6300, rects=0x9c49b8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:650
71#1 rect_list_add_split_fuzzy_and_merge (node=0x1ce6300, rects=0x9c49b8, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
72 at lib/evas/common/evas_tiler.c:849
73#2 _add_redraw (h=7, w=34, y=254, x=698, rects=0x9c49b8) at lib/evas/common/evas_tiler.c:956
74#3 evas_common_tilebuf_add_redraw (tb=0x9c4980, x=698, y=254, w=34, h=7) at lib/evas/common/evas_tiler.c:986
75#4 0x00007ffff71b2af2 in evas_object_render_pre_effect_updates (rects=0x68bed8, eo_obj=<optimized out>, is_v=1, was_v=<optimized out>)
76 at lib/evas/canvas/evas_object_main.c:343
77#5 0x00007ffff71f1bfc in _evas_render_phase1_direct (render_objects=0x139e3a0, active_objects=0x68bce0, e=<optimized out>, restack_objects=<optimized out>,
78 delete_objects=<optimized out>) at lib/evas/canvas/evas_render.c:231
79#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
80#7 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
81#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
82#9 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe158, op_type=EO_OP_TYPE_REGULAR, obj=0x68bc50) at lib/eo/eo.c:403
83#10 eo_do_internal (obj=0x68bc50, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
84#11 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
85#12 0x00007fffe73d943a in _ecore_evas_x_render (ee=0x68a480) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
86#13 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
87#14 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
88#15 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
89#16 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
90#17 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
91#18 0x00000000004028de in elm_main (argc=1, argv=0x7fffffffe508) at demoapp.c:284
92#19 0x0000000000402923 in main (argc=1, argv=0x7fffffffe508) at demoapp.c:291
93
94===============================================================================
952012-12-10_23-49
96
97Lockup without opengl !
98I was using software rendering.
99
100gdb ./examples/demoapp
101run
102
103// use the app, and it locks up during an animation (app takes 100% CPU)
104// Ctrl-C
105
106^C
107Program received signal SIGINT, Interrupt.
108_calc_intra_outer_rect_area (outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...) at lib/evas/common/evas_tiler.c:524
109524 intra->area = intra->width * intra->height;
110(gdb) bt
111#0 _calc_intra_outer_rect_area (outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...) at lib/evas/common/evas_tiler.c:524
112#1 rect_list_add_split_fuzzy (node=0xb54050, rects=0x6927f8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:652
113#2 rect_list_add_split_fuzzy_and_merge (node=0xb54050, rects=0x6927f8, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
114 at lib/evas/common/evas_tiler.c:849
115#3 _add_redraw (h=72, w=348, y=429, x=296, rects=0x6927f8) at lib/evas/common/evas_tiler.c:956
116#4 evas_common_tilebuf_add_redraw (tb=0x6927c0, x=296, y=429, w=348, h=72) at lib/evas/common/evas_tiler.c:986
117#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=
118 1) at lib/evas/canvas/evas_object_main.c:343
119#6 0x00007ffff71ab60d in evas_object_image_render_pre (eo_obj=0x8d2360, obj=0x8d23f0) at lib/evas/canvas/evas_object_image.c:3768
120#7 0x00007ffff71f1668 in evas_render_updates_internal (eo_e=0x689840, make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
121 at lib/evas/canvas/evas_render.c:1365
122#8 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
123#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
124#10 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe168, op_type=EO_OP_TYPE_REGULAR, obj=0x689840) at lib/eo/eo.c:403
125#11 eo_do_internal (obj=0x689840, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
126#12 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
127#13 0x00007fffe73d943a in _ecore_evas_x_render (ee=0x6880c0) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
128#14 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
129#15 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
130#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
131#17 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
132#18 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
133#19 0x00000000004028de in elm_main (argc=1, argv=0x7fffffffe518) at demoapp.c:284
134#20 0x0000000000402923 in main (argc=1, argv=0x7fffffffe518) at demoapp.c:291
135
136===============================================================================
1372012-12-10_23-58
138
139// Same scenario
140
141^C
142Program received signal SIGINT, Interrupt.
143rect_list_add_split_fuzzy (node=0xfe0150, rects=0x6927f8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:653
144653 area = current.area + r.area - intra.area;
145(gdb) bt
146#0 rect_list_add_split_fuzzy (node=0xfe0150, rects=0x6927f8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:653
147#1 rect_list_add_split_fuzzy_and_merge (node=0xfe0150, rects=0x6927f8, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
148 at lib/evas/common/evas_tiler.c:849
149#2 _add_redraw (h=63, w=85, y=314, x=493, rects=0x6927f8) at lib/evas/common/evas_tiler.c:956
150#3 evas_common_tilebuf_add_redraw (tb=0x6927c0, x=493, y=314, w=85, h=63) at lib/evas/common/evas_tiler.c:986
151#4 0x00007ffff71b2b9d in evas_object_render_pre_effect_updates (rects=0x689ac8, eo_obj=<optimized out>, is_v=1, was_v=<optimized out>)
152 at lib/evas/canvas/evas_object_main.c:356
153#5 0x00007ffff71f1bfc in _evas_render_phase1_direct (render_objects=0x1b79f50, active_objects=0x6898d0, e=<optimized out>, restack_objects=<optimized out>,
154 delete_objects=<optimized out>) at lib/evas/canvas/evas_render.c:231
155#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
156#7 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
157#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
158#9 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe168, op_type=EO_OP_TYPE_REGULAR, obj=0x689840) at lib/eo/eo.c:403
159#10 eo_do_internal (obj=0x689840, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
160#11 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
161#12 0x00007fffe73d943a in _ecore_evas_x_render (ee=0x6880c0) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
162#13 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
163#14 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
164#15 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
165#16 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
166#17 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
167#18 0x00000000004028de in elm_main (argc=1, argv=0x7fffffffe518) at demoapp.c:284
168#19 0x0000000000402923 in main (argc=1, argv=0x7fffffffe518) at demoapp.c:291
169
170===============================================================================
1712012-12-11_00-34
172
173// Same scenario
174
175^C
176Program received signal SIGINT, Interrupt.
177rect_list_add_split_fuzzy (node=0xb54370, rects=0x6927f8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:702
178702 else if (intra.area <= accepted_error)
179(gdb) bt
180#0 rect_list_add_split_fuzzy (node=0xb54370, rects=0x6927f8, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:702
181#1 rect_list_add_split_fuzzy_and_merge (node=0xb54370, rects=0x6927f8, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
182 at lib/evas/common/evas_tiler.c:849
183#2 _add_redraw (h=39, w=49, y=156, x=486, rects=0x6927f8) at lib/evas/common/evas_tiler.c:956
184#3 evas_common_tilebuf_add_redraw (tb=0x6927c0, x=486, y=156, w=49, h=39) at lib/evas/common/evas_tiler.c:986
185#4 0x00007ffff71b2af2 in evas_object_render_pre_effect_updates (rects=0x689ac8, eo_obj=<optimized out>, is_v=1, was_v=<optimized out>)
186 at lib/evas/canvas/evas_object_main.c:343
187#5 0x00007ffff71f1bfc in _evas_render_phase1_direct (render_objects=0x1671880, active_objects=0x6898d0, e=<optimized out>, restack_objects=<optimized out>,
188 delete_objects=<optimized out>) at lib/evas/canvas/evas_render.c:231
189#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
190#7 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
191#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
192#9 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe168, op_type=EO_OP_TYPE_REGULAR, obj=0x689840) at lib/eo/eo.c:403
193#10 eo_do_internal (obj=0x689840, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
194#11 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
195#12 0x00007fffe73d943a in _ecore_evas_x_render (ee=0x6880c0) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
196#13 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
197#14 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
198#15 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
199#16 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
200#17 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
201#18 0x00000000004028de in elm_main (argc=1, argv=0x7fffffffe518) at demoapp.c:284
202#19 0x0000000000402923 in main (argc=1, argv=0x7fffffffe518) at demoapp.c:291
203
204===============================================================================
2052012-12-11_05-39
206
207Without any evas_object_line
208
209^C
210Program received signal SIGINT, Interrupt.
211rect_list_add_split_fuzzy (node=0xcf4c20, rects=0x692788, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:650
212650 current = ((rect_node_t *)cur_node)->rect;
213(gdb) bt
214#0 rect_list_add_split_fuzzy (node=0xcf4c20, rects=0x692788, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:650
215#1 rect_list_add_split_fuzzy_and_merge (node=0xcf4c20, rects=0x692788, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
216 at lib/evas/common/evas_tiler.c:849
217#2 _add_redraw (h=16, w=1047, y=240, x=263, rects=0x692788) at lib/evas/common/evas_tiler.c:956
218#3 evas_common_tilebuf_add_redraw (tb=0x692750, x=263, y=240, w=1047, h=16) at lib/evas/common/evas_tiler.c:986
219#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,
220 was_v=was_v@entry=1) at lib/evas/canvas/evas_object_main.c:343
221#5 0x00007ffff71ab60d in evas_object_image_render_pre (eo_obj=0x1100690, obj=0x1100720) at lib/evas/canvas/evas_object_image.c:3768
222#6 0x00007ffff71f1bfc in _evas_render_phase1_direct (render_objects=0x1100690, active_objects=0x689860, e=<optimized out>, restack_objects=<optimized out>,
223 delete_objects=<optimized out>) at lib/evas/canvas/evas_render.c:231
224#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
225#8 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
226#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
227#10 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe1d8, op_type=EO_OP_TYPE_REGULAR, obj=0x6897d0) at lib/eo/eo.c:403
228#11 eo_do_internal (obj=0x6897d0, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
229#12 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
230#13 0x00007fffe73d743a in _ecore_evas_x_render (ee=0x688050) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
231#14 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
232#15 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
233#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
234#17 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
235#18 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
236#19 0x00000000004028ce in elm_main (argc=1, argv=0x7fffffffe588) at demoapp.c:284
237#20 0x0000000000402913 in main (argc=1, argv=0x7fffffffe588) at demoapp.c:291
238
239===============================================================================
2402012-12-11_05-42
241
242with 500 nodes = 1500 objects, no evas_object_line, but 500 evas_map
243
244^C
245Program received signal SIGINT, Interrupt.
246_calc_intra_outer_rect_area (outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...) at lib/evas/common/evas_tiler.c:498
247498 if (a.top < b.top)
248(gdb) bt
249#0 _calc_intra_outer_rect_area (outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...) at lib/evas/common/evas_tiler.c:498
250#1 rect_list_add_split_fuzzy (node=0x1acbb00, rects=0x93f238, accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:652
251#2 rect_list_add_split_fuzzy_and_merge (node=0x1acbb00, rects=0x93f238, split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
252 at lib/evas/common/evas_tiler.c:849
253#3 _add_redraw (h=52, w=371, y=437, x=826, rects=0x93f238) at lib/evas/common/evas_tiler.c:956
254#4 evas_common_tilebuf_add_redraw (tb=0x93f200, x=826, y=437, w=371, h=52) at lib/evas/common/evas_tiler.c:986
255#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
256#6 0x00007ffff71ee940 in _evas_render_phase1_object_process (e=e@entry=0x68bc90, eo_obj=0x1c75220, active_objects=active_objects@entry=0x68bda8,
257 restack_objects=restack_objects@entry=0x68bdc8, delete_objects=delete_objects@entry=0x68bd88, render_objects=render_objects@entry=0x68bde8, restack=0,
258 redraw_all=redraw_all@entry=0x7fffffffe0ec, mapped_parent=mapped_parent@entry=0 '\000') at lib/evas/canvas/evas_render.c:355
259#7 0x00007ffff71eeaf6 in _evas_render_phase1_object_process (e=e@entry=0x68bc90, eo_obj=<optimized out>, active_objects=active_objects@entry=0x68bda8,
260 restack_objects=restack_objects@entry=0x68bdc8, delete_objects=delete_objects@entry=0x68bd88, render_objects=render_objects@entry=0x68bde8, restack=0,
261 redraw_all=redraw_all@entry=0x7fffffffe0ec, mapped_parent=mapped_parent@entry=0 '\000') at lib/evas/canvas/evas_render.c:413
262#8 0x00007ffff71eeaf6 in _evas_render_phase1_object_process (e=e@entry=0x68bc90, eo_obj=<optimized out>, active_objects=active_objects@entry=0x68bda8,
263 restack_objects=restack_objects@entry=0x68bdc8, delete_objects=delete_objects@entry=0x68bd88, render_objects=render_objects@entry=0x68bde8, restack=0,
264 redraw_all=redraw_all@entry=0x7fffffffe0ec, mapped_parent=mapped_parent@entry=0 '\000') at lib/evas/canvas/evas_render.c:413
265#9 0x00007ffff71eeaf6 in _evas_render_phase1_object_process (e=e@entry=0x68bc90, eo_obj=<optimized out>, active_objects=active_objects@entry=0x68bda8,
266 restack_objects=restack_objects@entry=0x68bdc8, delete_objects=delete_objects@entry=0x68bd88, render_objects=render_objects@entry=0x68bde8, restack=0,
267 redraw_all=redraw_all@entry=0x7fffffffe0ec, mapped_parent=mapped_parent@entry=0 '\000') at lib/evas/canvas/evas_render.c:413
268#10 0x00007ffff71eeaf6 in _evas_render_phase1_object_process (e=e@entry=0x68bc90, eo_obj=<optimized out>, active_objects=active_objects@entry=0x68bda8,
269 restack_objects=restack_objects@entry=0x68bdc8, delete_objects=delete_objects@entry=0x68bd88, render_objects=render_objects@entry=0x68bde8, restack=0,
270 redraw_all=redraw_all@entry=0x7fffffffe0ec, mapped_parent=mapped_parent@entry=0 '\000') at lib/evas/canvas/evas_render.c:413
271#11 0x00007ffff71eeaf6 in _evas_render_phase1_object_process (e=e@entry=0x68bc90, eo_obj=<optimized out>, active_objects=active_objects@entry=0x68bda8,
272 restack_objects=restack_objects@entry=0x68bdc8, delete_objects=delete_objects@entry=0x68bd88, render_objects=render_objects@entry=0x68bde8,
273 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
274#12 0x00007ffff71f0f29 in _evas_render_phase1_process (redraw_all=0x7fffffffe0dc, render_objects=0x68bde8, delete_objects=0x68bd88, restack_objects=0x68bdc8,
275 active_objects=0x68bda8, e=0x68bc90) at lib/evas/canvas/evas_render.c:557
276#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
277#14 0x00007ffff71f3cd7 in _canvas_render_updates (eo_e=<optimized out>, _pd=<optimized out>, list=<optimized out>) at lib/evas/canvas/evas_render.c:1795
278#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
279#16 0x00007ffff6acd6cd in _eo_dov_internal (p_list=0x7fffffffe1b8, op_type=EO_OP_TYPE_REGULAR, obj=0x68bc00) at lib/eo/eo.c:403
280#17 eo_do_internal (obj=0x68bc00, op_type=op_type@entry=EO_OP_TYPE_REGULAR) at lib/eo/eo.c:434
281#18 0x00007ffff71f3c5f in evas_render_updates (eo_e=<optimized out>) at lib/evas/canvas/evas_render.c:1779
282#19 0x00007fffe73d743a in _ecore_evas_x_render (ee=0x68a430) at modules/ecore_evas/engines/x/ecore_evas_x.c:447
283#20 0x00007ffff68ba7f1 in _ecore_evas_idle_enter (data=<optimized out>) at lib/ecore_evas/ecore_evas.c:59
284#21 0x00007ffff6f3c019 in _ecore_call_task_cb (data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:300
285#22 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
286#23 0x00007ffff6f3e47b in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
287#24 0x00007ffff6f3eb27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
288#25 0x00000000004028ce in elm_main (argc=1, argv=0x7fffffffe568) at demoapp.c:284
289#26 0x0000000000402913 in main (argc=1, argv=0x7fffffffe568) at demoapp.c:291
290
291
292===============================================================================
2932012-12-13_06-32
294
295
296(gdb) bt
297#0 0x00007ffff53ddff7 in _calc_intra_outer_rect_area (
298 outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...)
299 at lib/evas/common/evas_tiler.c:479
300#1 rect_list_add_split_fuzzy (node=0x8ed9c0, rects=0x691668,
301 accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:652
302#2 rect_list_add_split_fuzzy_and_merge (node=0x8ed9c0, rects=0x691668,
303 split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
304 at lib/evas/common/evas_tiler.c:849
305#3 _add_redraw (h=115, w=327, y=203, x=504, rects=0x691668)
306 at lib/evas/common/evas_tiler.c:956
307#4 evas_common_tilebuf_add_redraw (tb=0x691630, x=504, y=203, w=327, h=115)
308 at lib/evas/common/evas_tiler.c:986
309#5 0x00007ffff535cb9d in evas_object_render_pre_effect_updates (rects=
310 0x688938, eo_obj=<optimized out>, is_v=1, was_v=<optimized out>)
311 at lib/evas/canvas/evas_object_main.c:356
312#6 0x00007ffff539bbfc in _evas_render_phase1_direct (render_objects=0x9baa60,
313 active_objects=0x688740, e=<optimized out>,
314 restack_objects=<optimized out>, delete_objects=<optimized out>)
315 at lib/evas/canvas/evas_render.c:231
316#7 evas_render_updates_internal (eo_e=0x6886b0,
317 make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
318 at lib/evas/canvas/evas_render.c:1357
319#8 0x00007ffff539dcd7 in _canvas_render_updates (eo_e=<optimized out>,
320 _pd=<optimized out>, list=<optimized out>)
321 at lib/evas/canvas/evas_render.c:1795
322#9 0x00007ffff706fa35 in _eo_op_internal (obj=0x6886b0, op_type=
323 EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe228) at lib/eo/eo.c:363
324#10 0x00007ffff70716cd in _eo_dov_internal (p_list=0x7fffffffe228, op_type=
325 EO_OP_TYPE_REGULAR, obj=0x6886b0) at lib/eo/eo.c:403
326#11 eo_do_internal (obj=0x6886b0, op_type=op_type@entry=EO_OP_TYPE_REGULAR)
327 at lib/eo/eo.c:434
328#12 0x00007ffff539dc5f in evas_render_updates (eo_e=<optimized out>)
329 at lib/evas/canvas/evas_render.c:1779
330#13 0x00007fffe6f7a43a in _ecore_evas_x_render (ee=0x686f30)
331 at modules/ecore_evas/engines/x/ecore_evas_x.c:447
332#14 0x00007ffff6e5e7f1 in _ecore_evas_idle_enter (data=<optimized out>)
333 at lib/ecore_evas/ecore_evas.c:59
334#15 0x00007ffff50e6019 in _ecore_call_task_cb (data=<optimized out>,
335 func=<optimized out>) at lib/ecore/ecore_private.h:300
336#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
337#17 0x00007ffff50e862d in _ecore_main_loop_iterate_internal (
338 once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1841
339#18 0x00007ffff50e8b27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
340#19 0x000000000040230e in elm_main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:269
341#20 0x0000000000402359 in main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:276
342
343
344===============================================================================
3452012-12-13_06-42
346
347^C
348Program received signal SIGINT, Interrupt.
349rect_list_add_split_fuzzy (node=0x884d70, rects=0x691668,
350 accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:653
351653 area = current.area + r.area - intra.area;
352
353(gdb) bt
354#0 rect_list_add_split_fuzzy (node=0x884d70, rects=0x691668,
355 accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:653
356#1 rect_list_add_split_fuzzy_and_merge (node=0x884d70, rects=0x691668,
357 split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
358 at lib/evas/common/evas_tiler.c:849
359#2 _add_redraw (h=12, w=542, y=356, x=118, rects=0x691668)
360 at lib/evas/common/evas_tiler.c:956
361#3 evas_common_tilebuf_add_redraw (tb=tb@entry=0x691630, x=118, y=356, w=542,
362 h=12) at lib/evas/common/evas_tiler.c:986
363#4 0x00007fffe6d672ac in _merge_rects (tb=0x691630, r1=<optimized out>, r2=
364 0x0, r3=0x0) at modules/evas/engines/software_x11/evas_engine.c:713
365#5 0x00007fffe6d6759b in eng_output_redraws_next_update_get (data=0x691c00, x=
366 0x7fffffffe13c, y=0x7fffffffe140, w=0x7fffffffe144, h=0x7fffffffe148,
367 cx=<optimized out>, cy=0x7fffffffe150, cw=0x7fffffffe154, ch=
368 0x7fffffffe158) at modules/evas/engines/software_x11/evas_engine.c:821
369#6 0x00007ffff539bf4f in evas_render_updates_internal (eo_e=0x6886b0,
370 make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
371 at lib/evas/canvas/evas_render.c:1533
372#7 0x00007ffff539dcd7 in _canvas_render_updates (eo_e=<optimized out>,
373 _pd=<optimized out>, list=<optimized out>)
374 at lib/evas/canvas/evas_render.c:1795
375#8 0x00007ffff706fa35 in _eo_op_internal (obj=0x6886b0, op_type=
376 EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe228) at lib/eo/eo.c:363
377#9 0x00007ffff70716cd in _eo_dov_internal (p_list=0x7fffffffe228, op_type=
378 EO_OP_TYPE_REGULAR, obj=0x6886b0) at lib/eo/eo.c:403
379#10 eo_do_internal (obj=0x6886b0, op_type=op_type@entry=EO_OP_TYPE_REGULAR)
380 at lib/eo/eo.c:434
381#11 0x00007ffff539dc5f in evas_render_updates (eo_e=<optimized out>)
382 at lib/evas/canvas/evas_render.c:1779
383#12 0x00007fffe6f7a43a in _ecore_evas_x_render (ee=0x686f30)
384 at modules/ecore_evas/engines/x/ecore_evas_x.c:447
385#13 0x00007ffff6e5e7f1 in _ecore_evas_idle_enter (data=<optimized out>)
386 at lib/ecore_evas/ecore_evas.c:59
387#14 0x00007ffff50e6019 in _ecore_call_task_cb (data=<optimized out>,
388 func=<optimized out>) at lib/ecore/ecore_private.h:300
389#15 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
390#16 0x00007ffff50e847b in _ecore_main_loop_iterate_internal (
391 once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
392#17 0x00007ffff50e8b27 in ecore_main_loop_begin ()
393 at lib/ecore/ecore_main.c:964
394#18 0x000000000040230e in elm_main (argc=1, argv=0x7fffffffe5b8)
395 at gg_map.c:269
396#19 0x0000000000402359 in main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:276
397
398===============================================================================
3992012-12-13_15-32
400
401^C 0x7fffe6d61700 (LWP 21696)]
402[Thread 0x7fffe6d61700 (LWP 21696) exited]
403[New Thread 0x7fffe6d61700 (LWP 21697)]
404[Thread 0x7fffe6d61700 (LWP 21697) exited]
405[New Thread 0x7fffe6d61700 (LWP 21711)]
406[Thread 0x7fffe6d61700 (LWP 21711) exited]
407[New Thread 0x7fffe6d61700 (LWP 21712)]
408[Thread 0x7fffe6d61700 (LWP 21712) exited]
409
410Program received signal SIGINT, Interrupt.
411rect_list_add_split_fuzzy (node=0xa977b0, rects=0x691668,
412 accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:680
413680 else if ((outer.area - area) <= accepted_error)
414
415
416(gdb) bt
417#0 rect_list_add_split_fuzzy (node=0xa977b0, rects=0x691668,
418 accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:680
419#1 rect_list_add_split_fuzzy_and_merge (node=0xa977b0, rects=0x691668,
420 split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
421 at lib/evas/common/evas_tiler.c:849
422#2 _add_redraw (h=6, w=126, y=110, x=463, rects=0x691668)
423 at lib/evas/common/evas_tiler.c:956
424#3 evas_common_tilebuf_add_redraw (tb=0x691630, x=463, y=110, w=126, h=6)
425 at lib/evas/common/evas_tiler.c:986
426#4 0x00007ffff535cb9d in evas_object_render_pre_effect_updates (
427 rects=rects@entry=0x688938, eo_obj=eo_obj@entry=0xa83500, is_v=is_v@entry=
428 1, was_v=was_v@entry=1) at lib/evas/canvas/evas_object_main.c:356
429#5 0x00007ffff535560d in evas_object_image_render_pre (eo_obj=0xa83500, obj=
430 0xa83590) at lib/evas/canvas/evas_object_image.c:3768
431#6 0x00007ffff539bbfc in _evas_render_phase1_direct (render_objects=0xa83500,
432 active_objects=0x688740, e=<optimized out>,
433 restack_objects=<optimized out>, delete_objects=<optimized out>)
434 at lib/evas/canvas/evas_render.c:231
435#7 evas_render_updates_internal (eo_e=0x6886b0,
436 make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
437 at lib/evas/canvas/evas_render.c:1357
438#8 0x00007ffff539dcd7 in _canvas_render_updates (eo_e=<optimized out>,
439 _pd=<optimized out>, list=<optimized out>)
440 at lib/evas/canvas/evas_render.c:1795
441#9 0x00007ffff706fa35 in _eo_op_internal (obj=0x6886b0, op_type=
442 EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe228) at lib/eo/eo.c:363
443#10 0x00007ffff70716cd in _eo_dov_internal (p_list=0x7fffffffe228, op_type=
444 EO_OP_TYPE_REGULAR, obj=0x6886b0) at lib/eo/eo.c:403
445#11 eo_do_internal (obj=0x6886b0, op_type=op_type@entry=EO_OP_TYPE_REGULAR)
446 at lib/eo/eo.c:434
447#12 0x00007ffff539dc5f in evas_render_updates (eo_e=<optimized out>)
448 at lib/evas/canvas/evas_render.c:1779
449#13 0x00007fffe6f7943a in _ecore_evas_x_render (ee=0x686f30)
450 at modules/ecore_evas/engines/x/ecore_evas_x.c:447
451#14 0x00007ffff6e5e7f1 in _ecore_evas_idle_enter (data=<optimized out>)
452 at lib/ecore_evas/ecore_evas.c:59
453#15 0x00007ffff50e6019 in _ecore_call_task_cb (data=<optimized out>,
454 func=<optimized out>) at lib/ecore/ecore_private.h:300
455#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
456#17 0x00007ffff50e847b in _ecore_main_loop_iterate_internal (
457 once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
458#18 0x00007ffff50e8b27 in ecore_main_loop_begin ()
459 at lib/ecore/ecore_main.c:964
460#19 0x00000000004022f1 in elm_main (argc=1, argv=0x7fffffffe5b8)
461 at gg_map.c:273
462#20 0x000000000040233c in main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:280
463(gdb)
464
465
466===============================================================================
4672012-12-13_17-19
468
469
470rect_list_add_split_fuzzy (node=0xb07d60, rects=0x692668, [0/1873]
471 accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:653
472653 area = current.area + r.area - intra.area;
473(gdb) bt
474#0 rect_list_add_split_fuzzy (node=0xb07d60, rects=0x692668,
475 accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:653
476#1 rect_list_add_split_fuzzy_and_merge (node=0xb07d60, rects=0x692668,
477 split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
478 at lib/evas/common/evas_tiler.c:849
479#2 _add_redraw (h=30, w=79, y=539, x=665, rects=0x692668)
480 at lib/evas/common/evas_tiler.c:956
481#3 evas_common_tilebuf_add_redraw (tb=0x692630, x=665, y=539, w=79, h=30)
482 at lib/evas/common/evas_tiler.c:986
483#4 0x00007ffff539bd1c in _evas_render_phase1_direct (render_objects=0xb61c40,
484 active_objects=0x689740, e=<optimized out>,
485 restack_objects=<optimized out>, delete_objects=<optimized out>)
486 at lib/evas/canvas/evas_render.c:257
487#5 evas_render_updates_internal (eo_e=0x6896b0,
488 make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
489 at lib/evas/canvas/evas_render.c:1357
490#6 0x00007ffff539dcd7 in _canvas_render_updates (eo_e=<optimized out>,
491 _pd=<optimized out>, list=<optimized out>)
492 at lib/evas/canvas/evas_render.c:1795
493#7 0x00007ffff706fa35 in _eo_op_internal (obj=0x6896b0, op_type=
494 EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe228) at lib/eo/eo.c:363
495#8 0x00007ffff70716cd in _eo_dov_internal (p_list=0x7fffffffe228, op_type=
496 EO_OP_TYPE_REGULAR, obj=0x6896b0) at lib/eo/eo.c:403
497#9 eo_do_internal (obj=0x6896b0, op_type=op_type@entry=EO_OP_TYPE_REGULAR)
498 at lib/eo/eo.c:434
499#10 0x00007ffff539dc5f in evas_render_updates (eo_e=<optimized out>)
500 at lib/evas/canvas/evas_render.c:1779
501#11 0x00007fffe6f7943a in _ecore_evas_x_render (ee=0x687f30)
502 at modules/ecore_evas/engines/x/ecore_evas_x.c:447
503#12 0x00007ffff6e5e7f1 in _ecore_evas_idle_enter (data=<optimized out>)
504 at lib/ecore_evas/ecore_evas.c:59
505#13 0x00007ffff50e6019 in _ecore_call_task_cb (data=<optimized out>,
506 func=<optimized out>) at lib/ecore/ecore_private.h:300
507#14 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
508#15 0x00007ffff50e847b in _ecore_main_loop_iterate_internal (
509 once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
510#16 0x00007ffff50e8b27 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
511#17 0x00000000004025d9 in elm_main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:324
512#18 0x0000000000402624 in main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:331
513
514===============================================================================
5152012-12-16_04-22
516
517This bug is a lockup of evas during rendering in my efl app.
518App freeze and takes 100% CPU. Below are backtraces when gdb was running and
519I interrupt it with Ctrl-C.
520
521At the time of crash, around 300objects total :
522elementary interface + ~100 edje + 100 edje mapped with evas_map + ~100 evas_object_text
523
524This crash is not predictible from what I see, sometimes it goes fine for a long
525time.
526It seem to crash more when using more edje objects.
527
528happened AFTER raster's fix
529------------------------------------------------------------------------
530r81039 | raster | 2012-12-16 03:01:11 +0100 (Sun, 16 Dec 2012) | 5 lines
531small change - dont let update rect list for image object become a
532runaway endless list if evas doenst come around and render (pick it
533up) any time soon - limit to 512 update rects.
534
535
536^C
537Program received signal SIGINT, Interrupt.
5380x00007ffff53ddc54 in _calc_intra_outer_rect_area (outer=<synthetic pointer>,
539 intra=<synthetic pointer>, a=..., b=...) at lib/evas/common/evas_tiler.c:530
540530 outer->height = max_bottom - min_top;
541(gdb) bt
542#0 0x00007ffff53ddc54 in _calc_intra_outer_rect_area (
543 outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...)
544 at lib/evas/common/evas_tiler.c:530
545#1 rect_list_add_split_fuzzy (node=0x9d27c0, rects=0x6942b8,
546 accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:652
547#2 rect_list_add_split_fuzzy_and_merge (node=0x9d27c0, rects=0x6942b8,
548 split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
549 at lib/evas/common/evas_tiler.c:849
550#3 _add_redraw (h=76, w=276, y=453, x=990, rects=0x6942b8)
551 at lib/evas/common/evas_tiler.c:956
552#4 evas_common_tilebuf_add_redraw (tb=0x694280, x=990, y=453, w=276, h=76)
553 at lib/evas/common/evas_tiler.c:986
554#5 0x00007ffff539736f in _evas_render_prev_cur_clip_cache_add (obj=obj@entry=
555 0xbee890, e=0x68b390, e=0x68b390) at lib/evas/canvas/evas_render.c:158
556#6 0x00007ffff539ba0c in _evas_render_phase1_direct (render_objects=0xbee800,
557 active_objects=0x68b390, e=<optimized out>,
558 restack_objects=<optimized out>, delete_objects=<optimized out>)
559 at lib/evas/canvas/evas_render.c:257
560#7 evas_render_updates_internal (eo_e=0x68b300,
561 make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
562 at lib/evas/canvas/evas_render.c:1357
563#8 0x00007ffff539d9c7 in _canvas_render_updates (eo_e=<optimized out>,
564 _pd=<optimized out>, list=<optimized out>)
565 at lib/evas/canvas/evas_render.c:1795
566#9 0x00007ffff706fa45 in _eo_op_internal (obj=0x68b300, op_type=
567 EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe1f8) at lib/eo/eo.c:363
568#10 0x00007ffff70716dd in _eo_dov_internal (p_list=0x7fffffffe1f8, op_type=
569 EO_OP_TYPE_REGULAR, obj=0x68b300) at lib/eo/eo.c:403
570#11 eo_do_internal (obj=0x68b300, op_type=op_type@entry=EO_OP_TYPE_REGULAR)
571 at lib/eo/eo.c:434
572#12 0x00007ffff539d94f in evas_render_updates (eo_e=<optimized out>)
573 at lib/evas/canvas/evas_render.c:1779
574#13 0x00007fffe6f7743a in _ecore_evas_x_render (ee=0x689b80)
575 at modules/ecore_evas/engines/x/ecore_evas_x.c:447
576#14 0x00007ffff6e5e841 in _ecore_evas_idle_enter (data=<optimized out>)
577 at lib/ecore_evas/ecore_evas.c:59
578#15 0x00007ffff50e5059 in _ecore_call_task_cb (data=<optimized out>,
579 func=<optimized out>) at lib/ecore/ecore_private.h:300
580#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
581#17 0x00007ffff50e74bb in _ecore_main_loop_iterate_internal (
582 once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1866
583#18 0x00007ffff50e7b67 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:964
584#19 0x00000000004035b0 in elm_main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:461
585---Type <return> to continue, or q <return> to quit---
586#20 0x00000000004035fb in main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:468
587
588===============================================================================
5892012-12-16_18-16
590
591
592^C
593Program received signal SIGINT, Interrupt.
5940x00007ffff53ddd20 in _calc_intra_outer_rect_area (outer=<synthetic pointer>,
595 intra=<synthetic pointer>, a=..., b=...)
596 at lib/evas/common/evas_tiler.c:509
597509 if (a.bottom < b.bottom)
598(gdb) bt
599#0 0x00007ffff53ddd20 in _calc_intra_outer_rect_area (
600 outer=<synthetic pointer>, intra=<synthetic pointer>, a=..., b=...)
601 at lib/evas/common/evas_tiler.c:509
602#1 rect_list_add_split_fuzzy (node=0x16b03d0, rects=0x692668,
603 accepted_error=<optimized out>) at lib/evas/common/evas_tiler.c:652
604#2 rect_list_add_split_fuzzy_and_merge (node=0x16b03d0, rects=0x692668,
605 split_accepted_error=<optimized out>, merge_accepted_error=<optimized out>)
606 at lib/evas/common/evas_tiler.c:849
607#3 _add_redraw (h=31, w=323, y=264, x=696, rects=0x692668)
608 at lib/evas/common/evas_tiler.c:956
609#4 evas_common_tilebuf_add_redraw (tb=0x692630, x=696, y=264, w=323, h=31)
610 at lib/evas/common/evas_tiler.c:986
611#5 0x00007ffff539736f in _evas_render_prev_cur_clip_cache_add (obj=obj@entry=
612 0x36cef40, e=0x689740, e=0x689740) at lib/evas/canvas/evas_render.c:158
613#6 0x00007ffff539ba0c in _evas_render_phase1_direct (render_objects=
614 0x36ceeb0, active_objects=0x689740, e=<optimized out>,
615 restack_objects=<optimized out>, delete_objects=<optimized out>)
616 at lib/evas/canvas/evas_render.c:257
617#7 evas_render_updates_internal (eo_e=0x6896b0,
618 make_updates=make_updates@entry=1 '\001', do_draw=do_draw@entry=1 '\001')
619 at lib/evas/canvas/evas_render.c:1357
620#8 0x00007ffff539d9c7 in _canvas_render_updates (eo_e=<optimized out>,
621 _pd=<optimized out>, list=<optimized out>)
622 at lib/evas/canvas/evas_render.c:1795
623#9 0x00007ffff706fa45 in _eo_op_internal (obj=0x6896b0, op_type=
624 EO_OP_TYPE_REGULAR, op=402, p_list=0x7fffffffe1f8) at lib/eo/eo.c:363
625#10 0x00007ffff70716dd in _eo_dov_internal (p_list=0x7fffffffe1f8, op_type=
626 EO_OP_TYPE_REGULAR, obj=0x6896b0) at lib/eo/eo.c:403
627#11 eo_do_internal (obj=0x6896b0, op_type=op_type@entry=EO_OP_TYPE_REGULAR)
628 at lib/eo/eo.c:434
629#12 0x00007ffff539d94f in evas_render_updates (eo_e=<optimized out>)
630 at lib/evas/canvas/evas_render.c:1779
631#13 0x00007fffe6f7743a in _ecore_evas_x_render (ee=0x687f30)
632 at modules/ecore_evas/engines/x/ecore_evas_x.c:447
633#14 0x00007ffff6e5e841 in _ecore_evas_idle_enter (data=<optimized out>)
634 at lib/ecore_evas/ecore_evas.c:59
635#15 0x00007ffff50e5059 in _ecore_call_task_cb (data=<optimized out>,
636 func=<optimized out>) at lib/ecore/ecore_private.h:300
637#16 _ecore_idle_enterer_call () at lib/ecore/ecore_idle_enterer.c:235
638#17 0x00007ffff50e766d in _ecore_main_loop_iterate_internal (
639 once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1841
640#18 0x00007ffff50e7b67 in ecore_main_loop_begin ()
641 at lib/ecore/ecore_main.c:964
642#19 0x00000000004031c1 in elm_main (argc=1, argv=0x7fffffffe5b8)
643 at gg_map.c:447
644#20 0x000000000040320c in main (argc=1, argv=0x7fffffffe5b8) at gg_map.c:454
645
646
diff --git a/doc/egraph.xoj b/doc/egraph.xoj
new file mode 100644
index 0000000..59ca038
--- /dev/null
+++ b/doc/egraph.xoj
Binary files differ
diff --git a/doc/internals.txt b/doc/internals.txt
new file mode 100644
index 0000000..7a8b34d
--- /dev/null
+++ b/doc/internals.txt
@@ -0,0 +1,89 @@
1Internals
2=========
3
4=== algo to handle threaded graph layouting correctly ===
5
6###### GENERAL ALGO
7_layouting_start(graph-2, coords-2);
8
9_add/del(structs-3);
10_repositionning(graph, structs, coords);
11
12_layouting_end(coords-2);
13
14_v2_updtate(structs-2, graph-2, coords-2);
15 _v2_structs/graph_update(structs-2, graph);
16 -> structs, graph // real add/del
17 _coords_copy(coords-2);
18 -> coords
19
20_repositionning(graph, structs, coords);
21
22_v3_update(structs-3);
23 _v3_structs/graph_update(structs-3, graph-2);
24 -> structs-2, graph-2
25
26###### TIMELINE VERTICE ADD
27egraph_vertice_add();
28 id = freeids[vertices_count];
29 v = vertices[id];
30 v->id = id;
31 vertices_count++;
32 v->v3-new = 1;
33
34_v3_update();
35 v->v2-new = v->v3-new;
36 v->v3-new = 0;
37 _v2_add()
38 v->graph2_vid = graph2_vcount;
39 graph2_vcount++;
40 igraph_add_vertices(graph2);
41
42_layouting_start();
43 // end up in coords2
44
45_layouting_end();
46_coords_copy();
47 // end up in coords
48
49_v2_update();
50 _add()
51 v->v2-new = 0;
52 v->graph_vid = graph_vcount;
53 graph_vcount++;
54 igraph_add_vertices(graph);
55 evas_object
56
57// in structs, graph, coords
58
59###### TIMELINE VERTICE DEL
60egraph_vertice_del();
61 v->v3-del = 1;
62
63_v3_update();
64 v->v2-del = v->v3-del;
65 v->v3-del = 0;
66 _v2_del()
67 igraph_delete_vertices(v->graph2_vid);
68 graph2_vcount--;
69
70_layouting_start();
71 // not in coords2
72
73_layouting_end();
74_coords_copy();
75 // not in coords
76
77_v2_update();
78 _del();
79 igraph_delete_vertices(v->graph_vid);
80 graph_vcount--;
81 freeids[vertices_count] = v->id;
82 vertices_count--;
83 free(v);
84
85// removed from structs, graph, coords
86
87###### TIMELINE VERTICE DEL
88
89
diff --git a/egraph.c b/egraph.c
new file mode 100644
index 0000000..bffcebf
--- /dev/null
+++ b/egraph.c
@@ -0,0 +1,1275 @@
1#include <err.h>
2#include <Efx.h>
3#include <Edje.h>
4
5#include "Egraph.h"
6
7#define DEBUG 0
8
9#define TYPE_MAXLEN 30
10
11static void _smart_add(Evas_Object *obj);
12static void _smart_del(Evas_Object *obj);
13static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
14static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
15static void _edge_v2_add(Egraph *eg, Egraph_Edge *e);
16static void _edge_add(Egraph *eg, Egraph_Edge *e);
17static void _edge_signal(Egraph *eg, Egraph_Edge *e, const char *signal);
18static void _edge_v2_del(Egraph *eg, Egraph_Edge *e);
19static void _edge_del(Egraph *eg, Egraph_Edge *e);
20static void _vertice_v2_add(Egraph *eg, Egraph_Vertice *v);
21static void _vertice_add(Egraph *eg, Egraph_Vertice *v);
22static void _vertice_v2_del(Egraph *eg, Egraph_Vertice *v);
23static void _vertice_del(Egraph *eg, Egraph_Vertice *v);
24static void _vertice_update_status(Egraph *eg, Egraph_Vertice *v);
25static void _vertice_signal(Egraph *eg, Egraph_Vertice *v, const char *signal);
26static void _vertice_geometry_update(Egraph *eg, Egraph_Vertice *v);
27static void _v2_update(Egraph *eg);
28static void _v3_update(Egraph *eg);
29static void _coords2_copy(Egraph *eg);
30static void _cb_blob_arrived(void *data, Efx_Map_Data *e, Evas_Object *obj);
31static void _blob_send(Evas_Object *blob,
32 Egraph_Vertice *v, Evas_Coord x, Evas_Coord y);
33static void _layouting_schedule(Egraph *eg);
34static Eina_Bool _cb_layouting_start(void *data);
35static void _cb_layouting_run(void *data, Ecore_Thread *thread);
36static void _cb_layouting_end(void *data, Ecore_Thread *thread);
37static void _cb_layouting_cancel(void *data, Ecore_Thread *thread);
38static int _igraph_query_vid(igraph_t *g, int g_len, int id);
39static void _cb_vertice_move(void *data,
40 Evas *evas, Evas_Object *obj, void *event_info);
41static void _reposition(Egraph *eg, int no_animation);
42static void _matrix_minmax_2v(const igraph_matrix_t *m, int row_count,
43 float *c1min, float *c1max,
44 float *c2min, float *c2max);
45static Evas_Object *_edje_obj_new(Egraph *eg, const char *group);
46static Evas_Object *_edje_obj_set(Egraph *eg, Evas_Object *o, const char *group);
47
48static const Evas_Smart_Cb_Description _smart_callbacks[] = {{NULL, NULL}};
49#define EGRAPH_DATA_GET(o, ptr) \
50 Egraph * ptr = evas_object_smart_data_get(o)
51/* defines _egraph_parent_sc and _egraph_smart_class_new */
52EVAS_SMART_SUBCLASS_NEW("Egraph", _egraph,
53 Evas_Smart_Class, Evas_Smart_Class,
54 evas_object_smart_clipped_class_get, _smart_callbacks);
55
56static void
57_egraph_smart_set_user(Evas_Smart_Class *sc)
58{
59 /* specializing these two */
60 sc->add = _smart_add;
61 sc->del = _smart_del;
62 sc->move = _smart_move;
63 /* clipped smart object has no hook on resizes or calculations */
64 sc->resize = _smart_resize;
65}
66
67static void
68_smart_add(Evas_Object *obj)
69{
70 EVAS_SMART_DATA_ALLOC(obj, Egraph);
71
72 priv->evas = evas_object_evas_get(obj);
73
74 _egraph_parent_sc->add(obj);
75}
76
77static void
78_smart_del(Evas_Object *obj)
79{
80 EGRAPH_DATA_GET(obj, eg);
81
82 igraph_destroy(&eg->graph);
83 if (eg->layouting.running == 2)
84 ecore_thread_cancel(eg->layouting.thread);
85
86 _egraph_parent_sc->del(obj);
87}
88
89static void
90_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
91{
92 EGRAPH_DATA_GET(obj, eg);
93
94 _reposition(eg, 1);
95
96 _egraph_parent_sc->move(obj, x, y);
97}
98
99static void
100_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
101{
102 EGRAPH_DATA_GET(obj, eg);
103
104 _reposition(eg, 1);
105}
106
107Evas_Object *
108egraph_new(Evas *evas, int directed)
109{
110 Evas_Object *obj = NULL;
111 Evas_Object *rect;
112 Egraph *eg;
113 int i;
114
115 EINA_SAFETY_ON_NULL_RETURN_VAL(evas, NULL);
116
117 efx_init();
118 eina_log_domain_level_set("efx", EINA_LOG_LEVEL_WARN);
119
120 obj = evas_object_smart_add(evas, _egraph_smart_class_new());
121 eg = evas_object_smart_data_get(obj);
122 if (!eg) goto err;
123 eg->obj = obj;
124 rect = evas_object_rectangle_add(eg->evas);
125 evas_object_color_set(rect, 0, 0, 0, 0);
126 evas_object_smart_member_add(rect, obj);
127 eg->split_vertice_edge = rect;
128
129 eg->graph_directed = directed;
130 eg->display_vertices = 1;
131 eg->display_names = 1;
132 eg->display_edges = 1;
133 eg->use_animations = 1;
134 eg->do_improvements = 1;
135 egraph_theme_file_set(obj, NULL);
136 eg->theme_edges = 1;
137 eg->layout = EGRAPH_LAYOUT_DEFAULT;
138
139 /* needed for igraph attribute handling */
140 igraph_i_set_attribute_table(&igraph_cattribute_table);
141
142 eg->vertices = eina_hash_int32_new(NULL);
143 for (i=0; i<EGRAPH_VERTICES_MAX-1; i++)
144 eg->vertices_freeids[i] = i;
145 if (igraph_empty(&eg->graph, 0, directed))
146 goto err;
147 if (igraph_empty(&eg->graph2, 0, directed))
148 goto err;
149 igraph_matrix_init(&eg->coords, 0, 2);
150 igraph_matrix_init(&eg->coords2, 0, 2);
151 eg->graph_wmin = 0;
152 eg->graph_wmax = 200;
153 eg->graph_hmin = 0;
154 eg->graph_hmax = 200;
155 eg->vertice_max_w = 0;
156 eg->vertice_max_h = 0;
157
158 return obj;
159
160err:
161 if (obj)
162 evas_object_del(obj);
163 return NULL;
164}
165
166void
167egraph_clear(Evas_Object *obj)
168{
169 EGRAPH_DATA_GET(obj, eg);
170 Eina_Iterator *it;
171 Egraph_Vertice *v;
172 void *data;
173
174 it = eina_hash_iterator_tuple_new(eg->vertices);
175 while (eina_iterator_next(it, &data)) {
176 Eina_Hash_Tuple *t = data;
177 v = t->data;
178 egraph_vertice_del(obj, v);
179 }
180}
181
182void
183egraph_theme_file_set(Evas_Object *obj, char *path)
184{
185 EGRAPH_DATA_GET(obj, eg);
186
187 if (eg->theme_path)
188 free(eg->theme_path);
189
190 if (!path) {
191 char buf[256];
192
193 snprintf(buf, sizeof(buf),
194 "%s/egraph.edj",
195 "/usr/local/share/egraph"); /* XXX use eina_prefix */
196 path = buf;
197 }
198 eg->theme_path = strndup(path, 256);
199}
200
201void
202egraph_theme_edges_set(Evas_Object *obj, int set)
203{
204 EGRAPH_DATA_GET(obj, eg);
205
206 eg->theme_edges = set;
207}
208
209void
210egraph_layout_set(Evas_Object *obj, Egraph_Layout layout)
211{
212 EGRAPH_DATA_GET(obj, eg);
213
214 eg->layout = layout;
215 _layouting_schedule(eg);
216}
217
218void
219egraph_display_vertices_set(Evas_Object *obj, int set)
220{
221 EGRAPH_DATA_GET(obj, eg);
222 Eina_Iterator *it;
223 Egraph_Vertice *v;
224 void *data;
225
226 eg->display_vertices = set;
227
228 it = eina_hash_iterator_tuple_new(eg->vertices);
229 while (eina_iterator_next(it, &data)) {
230 Eina_Hash_Tuple *t = data;
231 v = t->data;
232 if (v->o) {
233 if (set == 0)
234 evas_object_hide(v->o);
235 else
236 evas_object_show(v->o);
237 }
238 }
239
240 _reposition(eg, 0);
241}
242
243void
244egraph_display_names_set(Evas_Object *obj, int set)
245{
246 EGRAPH_DATA_GET(obj, eg);
247 Eina_Iterator *it;
248 Egraph_Vertice *v;
249 void *data;
250
251 eg->display_names = set;
252
253 it = eina_hash_iterator_tuple_new(eg->vertices);
254 while (eina_iterator_next(it, &data)) {
255 Eina_Hash_Tuple *t = data;
256 v = t->data;
257 egraph_vertice_rename(obj, v, set ? v->name : NULL);
258 }
259}
260
261void
262egraph_display_edges_set(Evas_Object *obj, int set)
263{
264 EGRAPH_DATA_GET(obj, eg);
265 Eina_List *l;
266 Egraph_Edge *e;
267
268 eg->display_edges = set;
269
270 EINA_LIST_FOREACH(eg->edges, l, e) {
271 if (e->o) {
272 if (set == 0)
273 evas_object_hide(e->o);
274 else
275 evas_object_show(e->o);
276 }
277 }
278}
279
280void
281egraph_use_animations_set(Evas_Object *obj, int set)
282{
283 EGRAPH_DATA_GET(obj, eg);
284
285 eg->use_animations = set;
286}
287
288void
289egraph_do_improvements_set(Evas_Object *obj, int set)
290{
291 EGRAPH_DATA_GET(obj, eg);
292
293 eg->do_improvements = set;
294}
295
296Egraph_Edge *
297egraph_edge_add(Evas_Object *obj, Egraph_Vertice *a, Egraph_Vertice *b,
298 void *data)
299{
300 EGRAPH_DATA_GET(obj, eg);
301 Egraph_Edge *e;
302
303 e = calloc(1, sizeof(Egraph_Edge));
304 if (!e)
305 err(1, "egraph_edge_add: cannot calloc");
306 e->v3_new = 1;
307 e->a = a;
308 e->b = b;
309 e->data = data;
310 eg->edges = eina_list_append(eg->edges, e);
311 if (DEBUG)
312 printf("egraph_edge_add %d %d\n", e->a->id, e->b->id);
313
314 egraph_edge_type_set(obj, e, "edge_normal");
315
316 _layouting_schedule(eg);
317 return e;
318}
319
320static void
321_edge_v2_add(Egraph *eg, Egraph_Edge *e)
322{
323 int a_pos, b_pos;
324
325 if (DEBUG)
326 printf("_edge_v2_add %d %d\n", e->a->id, e->b->id);
327
328 e->v2_new = 1;
329 e->v3_new = 0;
330
331 a_pos = _igraph_query_vid(&eg->graph2, eg->graph2_vcount, e->a->id);
332 b_pos = _igraph_query_vid(&eg->graph2, eg->graph2_vcount, e->b->id);
333 igraph_add_edge(&eg->graph2, a_pos, b_pos);
334}
335
336static void
337_edge_add(Egraph *eg, Egraph_Edge *e)
338{
339 Evas_Object *eobj = NULL;
340 int a_pos, b_pos;
341
342 e->new = 1;
343 e->v2_new = 0;
344
345 a_pos = _igraph_query_vid(&eg->graph, eg->graph_vcount, e->a->id);
346 b_pos = _igraph_query_vid(&eg->graph, eg->graph_vcount, e->b->id);
347 igraph_add_edge(&eg->graph, a_pos, b_pos);
348
349 if (eg->theme_edges) {
350 eobj = _edje_obj_new(eg, e->type);
351 if (eobj) {
352 e->o_usetheme = 1;
353 evas_object_resize(eobj, eg->vertice_max_w, eg->vertice_max_h); // XXX rm
354 }
355 }
356 if (!eobj) {
357 eobj = evas_object_line_add(eg->evas);
358 evas_object_color_set(eobj, 255, 0, 0, 255);
359 }
360 evas_object_smart_member_add(eobj, eg->obj);
361 evas_object_stack_below(eobj, eg->split_vertice_edge);
362 e->o = eobj;
363 _edge_signal(eg, e, "become_active");
364
365 e->a->edges = eina_list_append(e->a->edges, e);
366 e->b->edges = eina_list_append(e->b->edges, e);
367 _vertice_update_status(eg, e->a);
368 _vertice_update_status(eg, e->b);
369}
370
371void
372egraph_edge_type_set(Evas_Object *obj, Egraph_Edge *e, const char *type)
373{
374 EGRAPH_DATA_GET(obj, eg);
375
376 if (e->type)
377 free(e->type);
378
379 e->type = strndup(type, TYPE_MAXLEN);
380 if (eg->theme_edges && e->o) {
381 _edje_obj_set(eg, e->o, type);
382 }
383}
384
385static void
386_edge_signal(Egraph *eg, Egraph_Edge *e, const char *signal)
387{
388 if (eg->theme_edges && e->o);
389 edje_object_signal_emit(e->o, signal, "");
390}
391
392void
393egraph_edge_del(Evas_Object *obj, Egraph_Edge *e)
394{
395 EGRAPH_DATA_GET(obj, eg);
396
397 // XXX DEBUG find mem corrupt, del already del edge
398 if (!egraph_edge_find(obj, e->a, e->b))
399 printf("XXX DEBUG: egraph_edge_del on unknown edge !!!\n");
400 if (DEBUG)
401 printf("egraph_edge_del: %d %d\n", e->a->id, e->b->id);
402
403 e->v3_del = 1;
404 _layouting_schedule(eg);
405}
406
407static void
408_edge_v2_del(Egraph *eg, Egraph_Edge *e)
409{
410 igraph_es_t es;
411 int a_pos, b_pos;
412
413 if (e->v2_del == 1)
414 return;
415
416 if (DEBUG)
417 printf("_edge_v2_del %d %d\n", e->a->id, e->b->id);
418
419 e->v2_del = 1;
420 e->v3_del = 0;
421
422 if (!e->v3_new) {
423 a_pos = _igraph_query_vid(&eg->graph2, eg->graph2_vcount, e->a->id);
424 b_pos = _igraph_query_vid(&eg->graph2, eg->graph2_vcount, e->b->id);
425 igraph_es_pairs_small(&es, eg->graph_directed, a_pos, b_pos, -1);
426 igraph_delete_edges(&eg->graph2, es);
427 }
428}
429
430static void
431_edge_del(Egraph *eg, Egraph_Edge *e)
432{
433 igraph_es_t es;
434 int a_pos, b_pos;
435
436 if (!e->v3_new && !e->v2_new) {
437 a_pos = _igraph_query_vid(&eg->graph, eg->graph_vcount, e->a->id);
438 b_pos = _igraph_query_vid(&eg->graph, eg->graph_vcount, e->b->id);
439 igraph_es_pairs_small(&es, eg->graph_directed, a_pos, b_pos, -1);
440 igraph_delete_edges(&eg->graph, es);
441
442 e->a->edges = eina_list_remove(e->a->edges, e);
443 e->b->edges = eina_list_remove(e->b->edges, e);
444 _vertice_update_status(eg, e->a);
445 _vertice_update_status(eg, e->b);
446
447 evas_object_del(e->o);
448 }
449 eg->edges = eina_list_remove(eg->edges, e);
450 free(e);
451}
452
453Egraph_Edge *
454egraph_edge_find(Evas_Object *obj, Egraph_Vertice *a, Egraph_Vertice *b)
455{
456 EGRAPH_DATA_GET(obj, eg);
457 Egraph_Edge *e;
458 Eina_List *l;
459
460 EINA_LIST_FOREACH(eg->edges, l, e)
461 if (!(e->v3_del || e->v2_del) &&
462 ((e->a == a && e->b == b) ||
463 (e->a == b && e->b == a)))
464 return e;
465 return NULL;
466}
467
468Egraph_Vertice *
469egraph_vertice_add(Evas_Object *obj, const char *name, void *data)
470{
471 EGRAPH_DATA_GET(obj, eg);
472 Egraph_Vertice *v;
473 u_int32_t id;
474
475 if (eg->vertices_count == EGRAPH_VERTICES_MAX) {
476 printf("egraph error: maximum number of vertices reached !\n");
477 return NULL;
478 }
479 v = calloc(1, sizeof(Egraph_Vertice));
480 if (!v)
481 err(1, "egraph_vertice_add: cannot calloc");
482 id = eg->vertices_freeids[eg->vertices_count];
483 v->id = id;
484 eina_hash_add(eg->vertices, &id, v);
485 eg->vertices_count++;
486 v->v3_new = 1;
487 if (DEBUG)
488 printf("egraph_vertice_add %d\n", id);
489
490 if (name)
491 v->name = strndup(name, EGRAPH_VERTICE_NAME_MAXLEN);
492 egraph_vertice_type_set(obj, v, "vertice_normal");
493
494 v->data = data;
495
496 _layouting_schedule(eg);
497 return v;
498}
499
500static void
501_vertice_v2_add(Egraph *eg, Egraph_Vertice *v)
502{
503 v->v2_new = 1;
504 v->v3_new = 0;
505
506 igraph_add_vertices(&eg->graph2, 1, 0);
507 SETVAN(&eg->graph2, "id", eg->graph2_vcount, v->id);
508 eg->graph2_vcount++;
509}
510
511static void
512_vertice_add(Egraph *eg, Egraph_Vertice *v)
513{
514 Evas_Object *vobj = NULL;
515
516 v->new = 1;
517 v->v2_new = 0;
518
519 vobj = _edje_obj_new(eg, v->type);
520 if (!vobj) {
521 printf("egraph: could not load theme for vertice !");
522 v->v2_new = 1;
523 v->new = 0;
524 _vertice_v2_del(eg, v);
525 return;
526 }
527 evas_object_smart_member_add(vobj, eg->obj);
528 evas_object_stack_above(vobj, eg->split_vertice_edge);
529 evas_object_event_callback_add(vobj, EVAS_CALLBACK_MOVE, _cb_vertice_move, v);
530 v->o = vobj;
531 _vertice_geometry_update(eg, v);
532
533 igraph_add_vertices(&eg->graph, 1, 0);
534 SETVAN(&eg->graph, "id", eg->graph_vcount, v->id);
535 eg->graph_vcount++;
536
537 if (v->name)
538 egraph_vertice_rename(eg->obj, v, v->name);
539}
540
541void
542egraph_vertice_del(Evas_Object *obj, Egraph_Vertice *v)
543{
544 EGRAPH_DATA_GET(obj, eg);
545 Egraph_Edge *e;
546 Eina_List *l;
547
548 v->v3_del = 1;
549
550 EINA_LIST_FOREACH(eg->edges, l, e)
551 if (e->a == v || e->b == v)
552 egraph_edge_del(obj, e);
553
554 _layouting_schedule(eg);
555}
556
557static void
558_vertice_v2_del(Egraph *eg, Egraph_Vertice *v)
559{
560 Egraph_Edge *e;
561 Eina_List *l;
562 int pos;
563
564 if (v->v2_del == 1)
565 return;
566
567 v->v2_del = 1;
568 v->v3_del = 0;
569
570 if (DEBUG)
571 printf("_vertice_v2_del %d\n", v->id);
572 EINA_LIST_FOREACH(eg->edges, l, e)
573 if (e->a == v || e->b == v)
574 _edge_v2_del(eg, e);
575
576 if (!v->v3_new) {
577 pos = _igraph_query_vid(&eg->graph2, eg->graph2_vcount, v->id);
578 igraph_delete_vertices(&eg->graph2, igraph_vss_1(pos));
579 eg->graph2_vcount--;
580 }
581}
582
583static void
584_vertice_del(Egraph *eg, Egraph_Vertice *v)
585{
586 Egraph_Edge *e;
587 Eina_List *l, *lprev;
588 Evas_Object *blob;
589 int pos;
590
591 if (!v->v3_new && !v->v2_new) {
592 EINA_LIST_FOREACH_SAFE(eg->edges, l, lprev, e)
593 if (e->a == v || e->b == v)
594 _edge_del(eg, e);
595 eina_list_free(v->edges);
596
597 pos = _igraph_query_vid(&eg->graph, eg->graph_vcount, v->id);
598 igraph_delete_vertices(&eg->graph, igraph_vss_1(pos));
599 eg->graph_vcount--;
600
601 EINA_LIST_FOREACH(v->blobs_incoming, l, blob)
602 evas_object_del(blob);
603 eina_list_free(v->blobs_incoming);
604
605 evas_object_del(v->o);
606 }
607
608 eina_hash_del(eg->vertices, &v->id, NULL);
609 eg->vertices_count--;
610 eg->vertices_freeids[eg->vertices_count] = v->id;
611
612 free(v);
613}
614
615void
616egraph_vertice_type_set(Evas_Object *obj, Egraph_Vertice *v, const char *type)
617{
618 EGRAPH_DATA_GET(obj, eg);
619
620 if (v->type)
621 free(v->type);
622
623 v->type = strndup(type, TYPE_MAXLEN);
624 if (v->o)
625 _edje_obj_set(eg, v->o, type);
626}
627
628static void
629_vertice_update_status(Egraph *eg, Egraph_Vertice *v)
630{
631 Eina_List *l;
632 Egraph_Edge *e;
633 int status = 0;
634
635 if (v->is_group && (eina_list_count(v->edges) >= 1)) {
636 status = 1; /* we are a group with childs */
637 } else {
638 EINA_LIST_FOREACH(v->edges, l, e) {
639 if ((v == e->a && !e->b->is_group) ||
640 (v == e->b && !e->a->is_group)) {
641 status = 1; /* we are connected to at least on other non group node */
642 break;
643 }
644 }
645 }
646
647 if (status != v->status) {
648 if (status)
649 _vertice_signal(eg, v, "become_active");
650 else
651 _vertice_signal(eg, v, "become_inactive");
652 v->status = status;
653 }
654}
655
656static void
657_vertice_signal(Egraph *eg, Egraph_Vertice *v, const char *signal)
658{
659 if (v->o)
660 edje_object_signal_emit(v->o, signal, "");
661}
662
663void
664egraph_vertice_rename(Evas_Object *obj, Egraph_Vertice *v, const char *name)
665{
666 EGRAPH_DATA_GET(obj, eg);
667
668 if (eg->display_names == 0)
669 return;
670
671 if (name) {
672 if (v->name != name) {
673 if (v->name)
674 free(v->name);
675 v->name = strndup(name, EGRAPH_VERTICE_NAME_MAXLEN);
676 }
677 }
678 if (v->o) {
679 if (v->name)
680 edje_object_part_text_set(v->o, "label", v->name);
681 else
682 edje_object_part_text_set(v->o, "label", "");
683 _vertice_geometry_update(eg, v);
684 }
685}
686
687static void
688_vertice_geometry_update(Egraph *eg, Egraph_Vertice *v)
689{
690 int w, h;
691
692 edje_object_size_min_calc(v->o, &w, &h);
693 if (DEBUG)
694 printf("_vertice_geometry_update: %d %d\n", w, h);
695 evas_object_resize(v->o, w, h);
696 if (w > eg->vertice_max_w)
697 eg->vertice_max_w = w;
698 if (h > eg->vertice_max_h)
699 eg->vertice_max_h = h;
700 if (DEBUG)
701 printf("_vertice_geometry_update: end %d %d\n",
702 eg->vertice_max_w, eg->vertice_max_h);
703}
704
705void
706_color_int_to_rgb(u_int32_t color, int *r, int *g , int *b)
707{
708 *r = (color & 0xFF000000) >> 24;
709 *g = (color & 0x00FF0000) >> 16;
710 *b = (color & 0x0000FF00) >> 8;
711}
712
713void
714egraph_vertice_send_blob(Evas_Object *obj,
715 Egraph_Vertice *a, Egraph_Vertice *b,
716 int size, u_int32_t color)
717{
718 EGRAPH_DATA_GET(obj, eg);
719 Evas_Object *blob;
720 int ax, ay, aw, ah, bx, by, bw, bh;
721 int cr, cg, cb;
722
723 if (!a->o || !b->o)
724 return;
725 evas_object_geometry_get(a->o, &ax, &ay, &aw, &ah);
726 evas_object_geometry_get(b->o, &bx, &by, &bw, &bh);
727 _color_int_to_rgb(color, &cr, &cg, &cb);
728
729 blob = _edje_obj_new(eg, "blob");
730 if (!blob)
731 blob = evas_object_rectangle_add(eg->evas);
732 evas_object_color_set(blob, cr, cg, cb, 255);
733 evas_object_smart_member_add(blob, eg->obj);
734 evas_object_stack_above(blob, eg->split_vertice_edge);
735 evas_object_move(blob, ax, ay);
736 evas_object_resize(blob, size, size);
737 evas_object_show(blob);
738 b->blobs_incoming = eina_list_append(b->blobs_incoming, blob);
739 _blob_send(blob, b, bx, by);
740}
741
742static void
743_cb_blob_arrived(void *data, Efx_Map_Data *e, Evas_Object *obj)
744{
745 Egraph_Vertice *v;
746
747 v = data;
748 v->blobs_incoming = eina_list_remove(v->blobs_incoming, obj);
749 evas_object_del(obj);
750}
751
752static void
753_blob_send(Evas_Object *blob, Egraph_Vertice *v, Evas_Coord x, Evas_Coord y)
754{
755 if (DEBUG)
756 printf("blob_send %d %d\n", x, y);
757 efx_move(blob, EFX_EFFECT_SPEED_SINUSOIDAL,
758 &(Evas_Point){ x, y }, 0.6, _cb_blob_arrived, v);
759}
760
761static void
762_layouting_schedule(Egraph *eg)
763{
764 if (eg->layouting.running > 0) {
765 eg->layouting.todo = 1;
766 return;
767 }
768
769 eg->layouting.running = 1;
770 ecore_timer_add(0.0, _cb_layouting_start, eg); /* delayed start */
771}
772
773static void
774_v2_update(Egraph *eg)
775{
776 Eina_List *l, *lprev, *todel, *toadd;
777 Eina_Iterator *it;
778 Egraph_Vertice *v;
779 Egraph_Edge *e;
780 void *data;
781
782 /* update graph and structs based on v2_add / v2_del */
783 it = eina_hash_iterator_tuple_new(eg->vertices);
784 todel = NULL; toadd = NULL;
785 while (eina_iterator_next(it, &data)) {
786 Eina_Hash_Tuple *t = data;
787 v = t->data;
788 if (v->v2_del)
789 todel = eina_list_append(todel, v);
790 else if (v->v2_new)
791 toadd = eina_list_append(toadd, v);
792 }
793 eina_iterator_free(it);
794 EINA_LIST_FOREACH(todel, l, v)
795 _vertice_del(eg, v);
796 EINA_LIST_FOREACH(toadd, l, v)
797 _vertice_add(eg, v);
798 todel = eina_list_free(todel);
799 toadd = eina_list_free(toadd);
800 EINA_LIST_FOREACH_SAFE(eg->edges, l, lprev, e) {
801 if (e->v2_del)
802 _edge_del(eg, e);
803 else if (e->v2_new)
804 _edge_add(eg, e);
805 }
806}
807
808static void
809_v3_update(Egraph *eg)
810{
811 Eina_List *l, *lprev;
812 Eina_Iterator *it;
813 Egraph_Vertice *v;
814 Egraph_Edge *e;
815 void *data;
816 float ranx, rany;
817 int changes_count = 0;
818 int changes_diff = 0;
819 int i, id;
820
821 if (DEBUG)
822 printf("_v3_update\n");
823 /* update graph2 and structs based on v3_add / v3_del */
824 it = eina_hash_iterator_tuple_new(eg->vertices);
825 while (eina_iterator_next(it, &data)) {
826 Eina_Hash_Tuple *t = data;
827 v = t->data;
828 if (v->v3_del) {
829 _vertice_v2_del(eg, v); changes_diff--; changes_count++;
830 } else if (v->v3_new) {
831 _vertice_v2_add(eg, v); changes_diff++; changes_count++;
832 }
833 }
834 eina_iterator_free(it);
835 if (DEBUG)
836 printf("_v3_update edges\n");
837 EINA_LIST_FOREACH_SAFE(eg->edges, l, lprev, e) {
838 if (e->v3_del) {
839 _edge_v2_del(eg, e); changes_count++;
840 } else if (e->v3_new) {
841 _edge_v2_add(eg, e); changes_count++;
842 }
843 }
844
845 /* set correct coords2 size */
846 if (changes_diff > 0) {
847 for (i=0; i<changes_diff; i++) {
848 id = (eg->graph2_vcount - changes_diff) + i;
849 igraph_matrix_add_rows(&eg->coords2, 1);
850 ranx = eg->graph_wmin + fmod((float)random() / 1000, (float)((eg->graph_wmax + 1) - eg->graph_wmin));
851 rany = eg->graph_hmin + fmod((float)random() / 1000, (float)((eg->graph_hmax + 1) - eg->graph_hmin));
852 if (DEBUG)
853 printf("ranx %6.3f rany %6.3f\n", ranx, rany);
854 igraph_matrix_set(&eg->coords2, id, 0, ranx);
855 igraph_matrix_set(&eg->coords2, id, 1, rany);
856 }
857 } else if (changes_diff < 0) {
858 changes_diff = -changes_diff;
859 for (i=0; i<changes_diff; i++) {
860 id = (eg->graph2_vcount + changes_diff) - i;
861 igraph_matrix_remove_row(&eg->coords2, 0);
862 }
863 }
864
865 if (eg->layout == EGRAPH_LAYOUT_FRUCHTERMANREINGOLD) {
866 /* set minimum and maximum for each node */
867 /* XXX do that in layouting thread ? */
868 if (DEBUG)
869 printf("g wmin %d wmax %d hmin %d hmax %d\n",
870 eg->graph_wmin, eg->graph_wmax, eg->graph_hmin, eg->graph_hmax);
871 igraph_vector_init(&eg->graph2_wmin, eg->graph2_vcount);
872 igraph_vector_init(&eg->graph2_wmax, eg->graph2_vcount);
873 igraph_vector_init(&eg->graph2_hmin, eg->graph2_vcount);
874 igraph_vector_init(&eg->graph2_hmax, eg->graph2_vcount);
875 igraph_vector_fill(&eg->graph2_wmin, eg->graph_wmin);
876 igraph_vector_fill(&eg->graph2_wmax, eg->graph_wmax);
877 igraph_vector_fill(&eg->graph2_hmin, eg->graph_hmin);
878 igraph_vector_fill(&eg->graph2_hmax, eg->graph_hmax);
879 }
880
881 eg->layouting.changes_diff = changes_diff;
882}
883
884static Eina_Bool
885_cb_layouting_start(void *data)
886{
887 Egraph *eg;
888
889 eg = data;
890
891 eg->layouting.todo = 0;
892
893 _v3_update(eg);
894
895 eg->layouting.running = 2;
896 eg->layouting.thread = ecore_thread_run(_cb_layouting_run, _cb_layouting_end,
897 _cb_layouting_cancel, eg);
898
899 return EINA_FALSE; /* no repeat */
900}
901
902void
903_cb_layouting_run(void *data, Ecore_Thread *thread)
904{
905 Egraph *eg;
906 int niter;
907
908 eg = data;
909
910 if (DEBUG)
911 printf("[-] _cb_layouting_run begin (%d)\n", eg->layout);
912
913 switch(eg->layout) {
914 case EGRAPH_LAYOUT_KAMADAKAWAI:
915 if (eg->layouting.improvement) {
916 niter = 300;
917 } else {
918 if (eg->layouting.changes_diff == 0)
919 niter = 1000;
920 else
921 niter = 1000 * eg->layouting.changes_diff;
922 if (niter > 2000)
923 niter = 2000;
924 }
925 /* http://igraph.sourceforge.net/doc/html/ch18s01.html#igraph_layout_kamada_kawai
926 * int igraph_layout_kamada_kawai(const igraph_t *g, igraph_matrix_t *res,
927 * igraph_integer_t niter, igraph_real_t sigma,
928 * igraph_real_t initemp, igraph_real_t coolexp,
929 * igraph_real_t kkconst, igraph_bool_t use_seed,
930 * const igraph_vector_t *minx,
931 * const igraph_vector_t *maxx,
932 * const igraph_vector_t *miny,
933 * const igraph_vector_t *maxy);
934 * Defaults :
935 * igraph_layout_kamada_kawai(&eg->graph2, &eg->coords2,
936 * 1000, eg->vertices_count / 4, 10, 0.99,
937 * eg->vertices_count ^ 2, 1,
938 * NULL, NULL, NULL, NULL);
939 */
940 igraph_layout_kamada_kawai(&eg->graph2, &eg->coords2,
941 niter, eg->graph2_vcount, 10, 0.99,
942 eg->vertices_count ^ 2, 1,
943 NULL, NULL, NULL, NULL);
944 break;
945
946 case EGRAPH_LAYOUT_GRAPHOPT:
947 if (eg->layouting.improvement) {
948 niter = 300;
949 } else {
950 if (eg->layouting.changes_diff == 0)
951 niter = 100;
952 else
953 niter = 50 * eg->layouting.changes_diff;
954 if (niter > 500)
955 niter = 500;
956 }
957 /* http://igraph.sourceforge.net/doc/html/ch18s01.html#igraph_layout_graphopt
958 * int igraph_layout_graphopt(const igraph_t *g, igraph_matrix_t *res,
959 * igraph_integer_t niter,
960 * igraph_real_t node_charge, igraph_real_t node_mass,
961 * igraph_real_t spring_length,
962 * igraph_real_t spring_constant,
963 * igraph_real_t max_sa_movement,
964 * igraph_bool_t use_seed);
965 * Defaults :
966 * igraph_layout_graphopt(&eg->graph2, &eg->coords2,
967 * 1000, 0.001, 30, 0, 1, 5, 0);
968 */
969 igraph_layout_graphopt(&eg->graph2, &eg->coords2,
970 niter, 0.003, 10, 10, 1, 5, 1);
971 break;
972
973 case EGRAPH_LAYOUT_FRUCHTERMANREINGOLD:
974 niter = 1000;
975 /* http://igraph.sourceforge.net/doc/html/ch18s01.html#igraph_layout_fruchterman_reingold
976 * int igraph_layout_fruchterman_reingold(const igraph_t *graph, igraph_matrix_t *res,
977 * igraph_integer_t niter, igraph_real_t maxdelta,
978 * igraph_real_t area, igraph_real_t coolexp,
979 * igraph_real_t repulserad, igraph_bool_t use_seed,
980 * const igraph_vector_t *weight,
981 * const igraph_vector_t *minx,
982 * const igraph_vector_t *maxx,
983 * const igraph_vector_t *miny,
984 * const igraph_vector_t *maxy);
985 * Defaults:
986 * igraph_layout_fruchterman_reingold(&eg->graph2, &eg->coords2,
987 * 500, eg->graph2_vcount,
988 * sqrt(eg->graph2_vcount) * sqrt(eg->graph2_vcount), 1.5,
989 * eg->graph2_vcount, 0,
990 * NULL, NULL, NULL, NULL, NULL);
991 */
992 igraph_layout_fruchterman_reingold(&eg->graph2, &eg->coords2,
993 niter, 0.05,
994 sqrt(eg->graph2_vcount), 1.5,
995 sqrt(eg->graph2_vcount) * eg->graph2_vcount, 1,
996 NULL, NULL, NULL, NULL, NULL);
997 //&eg->graph2_wmin, &eg->graph2_wmax,
998 //&eg->graph2_hmin, &eg->graph2_hmax);
999 break;
1000 }
1001 if (DEBUG)
1002 printf("[-] _cb_layouting_run end\n");
1003}
1004
1005static void
1006_coords2_copy(Egraph *eg)
1007{
1008 igraph_matrix_copy(&eg->coords, &eg->coords2);
1009}
1010
1011void
1012_cb_layouting_end(void *data, Ecore_Thread *thread)
1013{
1014 Egraph *eg;
1015
1016 eg = data;
1017 _v2_update(eg);
1018 _coords2_copy(eg);
1019 _reposition(eg, 0);
1020 eg->layouting.running = 0;
1021 if (eg->layouting.todo) {
1022 eg->layouting.todo = 0;
1023 eg->layouting.improvement = 0;
1024 _layouting_schedule(eg);
1025 } else {
1026 if (eg->do_improvements) {
1027 if (eg->layouting.improvement < EGRAPH_LAYOUTING_IMPROVEMENTS) {
1028 eg->layouting.improvement++;
1029 _layouting_schedule(eg);
1030 } else {
1031 eg->layouting.improvement = 0;
1032 }
1033 }
1034 }
1035}
1036
1037void
1038_cb_layouting_cancel(void *data, Ecore_Thread *thread)
1039{
1040 Egraph *eg;
1041
1042 eg = data;
1043 eg->layouting.running = 0;
1044 eg->layouting.todo = 0;
1045 /* we are not in a clean state now, but it happends on exit only */
1046}
1047
1048/* XXX slow ! possible to do edge/vertice delete on repositionning ? */
1049static int
1050_igraph_query_vid(igraph_t *g, int g_len, int id)
1051{
1052 int i;
1053
1054 for (i=0; i<g_len; i++) {
1055 if (VAN(g, "id", i) == id)
1056 return i;
1057 }
1058 printf("egraph: WARNING: _igraph_query_id %d not found !\n", id);
1059 return -1;
1060}
1061
1062/* Apply vertice move to it's edges */
1063static void
1064_cb_vertice_move(void *data, Evas *evas, Evas_Object *obj, void *event_info)
1065{
1066 EGRAPH_DATA_GET(evas_object_smart_parent_get(obj), eg);
1067 Egraph_Vertice *v;
1068 Egraph_Edge *e;
1069 Evas_Map *m;
1070 Eina_List *l;
1071 int x, y, w, h;
1072 int ax, ay, bx, by, aw, ah, bw, bh;
1073 int p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y;
1074 float a;
1075
1076 v = data;
1077 evas_object_geometry_get(v->o, &x, &y, &w, &h);
1078
1079 EINA_LIST_FOREACH(v->edges, l, e) {
1080 if (e->new) {
1081 if (eg->display_edges)
1082 evas_object_show(e->o);
1083 e->new = 0;
1084 }
1085 if (e->o_usetheme) {
1086 /* XXX we map the edges once per node = 2 times ... */
1087 evas_object_move(e->o, x, y);
1088 m = evas_map_new(4);
1089 evas_map_smooth_set(m, 1);
1090 evas_map_util_points_populate_from_object(m, e->o);
1091 evas_object_geometry_get(e->a->o, &ax, &ay, &aw, &ah);
1092 evas_object_geometry_get(e->b->o, &bx, &by, &bw, &bh);
1093 ax = ax + aw / 2; ay = ay + ah / 2;
1094 bx = bx + bw / 2; by = by + bh / 2;
1095 aw = aw / 2; ah = ah / 2;
1096 bw = bw / 2; bh = bh / 2;
1097 /* rotate edge endpoints */
1098 a = atan2(by - ay, bx - ax);
1099#define ROTX(x, h, a) (-sin(a)*h + x)
1100#define ROTY(y, h, a) (cos(a)*h + y)
1101 p0x = ROTX(ax, ah, a); p0y = ROTY(ay, ah, a);
1102 p1x = ROTX(ax, -ah, a); p1y = ROTY(ay, -ah, a);
1103 p2x = ROTX(bx, bh, a); p2y = ROTY(by, bh, a);
1104 p3x = ROTX(bx, -bh, a); p3y = ROTY(by, -bh, a);
1105 /* set edge endpoints */
1106 evas_map_point_coord_set(m, 0, p2x, p2y, 0);
1107 evas_map_point_coord_set(m, 1, p0x, p0y, 0);
1108 evas_map_point_coord_set(m, 2, p1x, p1y, 0);
1109 evas_map_point_coord_set(m, 3, p3x, p3y, 0);
1110 evas_object_map_set(e->o, m);
1111 evas_object_map_enable_set(e->o, EINA_TRUE); // XXX do at init
1112 evas_map_free(m);
1113 } else {
1114 evas_object_line_xy_get(e->o, &ax, &ay, &bx, &by);
1115 if (e->a == v) {
1116 ax = x + w/2;
1117 ay = y + h/2;
1118 } else {
1119 bx = x + w/2;
1120 by = y + h/2;
1121 }
1122 evas_object_line_xy_set(e->o, ax, ay, bx, by);
1123 }
1124 }
1125}
1126
1127static void
1128_reposition(Egraph *eg, int no_animation)
1129{
1130 Egraph_Vertice *v;
1131 u_int32_t id;
1132 float gw_min, gw_max, gh_min, gh_max, factor_w, factor_h;
1133 float x, y;
1134 int obj_x, obj_y, obj_w, obj_h;
1135 int vcur;
1136
1137 if (DEBUG)
1138 printf("[-] _reposition\n");
1139 if (eg->graph_vcount == 0)
1140 return;
1141
1142 evas_object_geometry_get(eg->obj, &obj_x, &obj_y, &obj_w, &obj_h);
1143 _matrix_minmax_2v(&eg->coords, eg->graph_vcount,
1144 &gw_min, &gw_max, &gh_min, &gh_max);
1145 eg->graph_wmin = gw_min;
1146 eg->graph_wmax = gw_max;
1147 eg->graph_hmin = gh_min;
1148 eg->graph_hmax = gh_max;
1149
1150 if (DEBUG)
1151 printf("gw_min %6.3f gw_max %6.3f gh_min %6.3f gh_max %6.3f\n",
1152 gw_min, gw_max, gh_min, gh_max);
1153 if (gw_max == gw_min)
1154 factor_w = 1;
1155 else
1156 factor_w = (obj_w - eg->vertice_max_w) / (gw_max - gw_min);
1157 if (gh_max == gh_min)
1158 factor_h = 1;
1159 else
1160 factor_h = (obj_h - eg->vertice_max_h) / (gh_max - gh_min);
1161 if (DEBUG)
1162 printf("factor_w %6.3f factor_h %6.3f\n", factor_w, factor_h);
1163
1164 for (vcur=0; vcur<eg->graph_vcount; vcur++) {
1165 id = VAN(&eg->graph, "id", vcur);
1166
1167 x = MATRIX(eg->coords, vcur, 0);
1168 y = MATRIX(eg->coords, vcur, 1);
1169 if (DEBUG)
1170 printf("%d: %6.3f %6.3f id %d\n", vcur, x, y, id);
1171 x = obj_x + ((x - gw_min) * factor_w);
1172 y = obj_y + ((y - gh_min) * factor_h);
1173 if (DEBUG)
1174 printf(" inobj: %6.3f %6.3f\n", x, y);
1175
1176 v = eina_hash_find(eg->vertices, &id);
1177 if (eg->use_animations && !no_animation) {
1178 efx_move(v->o, EFX_EFFECT_SPEED_DECELERATE,
1179 &(Evas_Point){ x, y }, 0.5, NULL, NULL);
1180 }
1181 else
1182 evas_object_move(v->o, x, y);
1183 /* XXX fix blob repositionning
1184 Evas_Object *blob;
1185 Eina_List *l;
1186 EINA_LIST_FOREACH(v->blobs_incoming, l, blob)
1187 _blob_send(blob, v, x, y);
1188 */
1189 if (v->new) {
1190 evas_object_show(v->o);
1191 v->new = 0;
1192 }
1193 }
1194}
1195
1196/**
1197 * Compute minimum and maximum of a matrices of 2 colum vectors
1198 *
1199 * @note igraph is crazy in the coconut
1200 */
1201static void
1202_matrix_minmax_2v(const igraph_matrix_t *m, int row_count,
1203 float *c1min, float *c1max, float *c2min, float *c2max)
1204{
1205 float val;
1206 int row;
1207
1208 *c1min=MATRIX(*m, 0, 0); *c1max=MATRIX(*m, 0, 0);
1209 *c2min=MATRIX(*m, 0, 1); *c2max=MATRIX(*m, 0, 1);
1210
1211 for (row=1; row<row_count; row++) {
1212 val = MATRIX(*m, row, 0);
1213 if (val < *c1min) *c1min = val;
1214 else if (val > *c1max) *c1max = val;
1215 val = MATRIX(*m, row, 1);
1216 if (val < *c2min) *c2min = val;
1217 else if (val > *c2max) *c2max = val;
1218 }
1219}
1220
1221static Evas_Object *
1222_edje_obj_new(Egraph *eg, const char *group)
1223{
1224 Evas_Object *obj;
1225
1226 obj = edje_object_add(eg->evas);
1227 return _edje_obj_set(eg, obj, group);
1228}
1229
1230static Evas_Object *
1231_edje_obj_set(Egraph *eg, Evas_Object *obj, const char *group)
1232{
1233 if (!obj || !edje_object_file_set(obj, eg->theme_path, group)) {
1234 int err = edje_object_load_error_get(obj);
1235 const char *errmsg = edje_load_error_str(err);
1236 if (DEBUG)
1237 fprintf(stderr, "Could not load the edje file - reason:%s\n", errmsg);
1238 return NULL;
1239 }
1240 return obj;
1241}
1242
1243Egraph_Vertice *
1244egraph_group_add(Evas_Object *obj, const char *name, void *data)
1245{
1246 Egraph_Vertice *g;
1247
1248 g = egraph_vertice_add(obj, name, data);
1249 g->is_group = 1;
1250 egraph_vertice_type_set(obj, g, "vertice_group");
1251 return g;
1252}
1253
1254int
1255egraph_group_vertice_attach(Evas_Object *obj,
1256 Egraph_Vertice *group, Egraph_Vertice *v)
1257{
1258 Egraph_Edge *e;
1259
1260 group->group_vertices = eina_list_append(group->group_vertices, v);
1261 e = egraph_edge_add(obj, group, v, NULL);
1262 egraph_edge_type_set(obj, e, "edge_group");
1263 return 1;
1264}
1265
1266void
1267egraph_group_vertice_detach(Evas_Object *obj,
1268 Egraph_Vertice *group, Egraph_Vertice *v)
1269{
1270 Egraph_Edge *e;
1271
1272 group->group_vertices = eina_list_remove(group->group_vertices, v);
1273 e = egraph_edge_find(obj, group, v);
1274 egraph_edge_del(obj, e);
1275}
diff --git a/egraph.edc b/egraph.edc
new file mode 100644
index 0000000..399442a
--- /dev/null
+++ b/egraph.edc
@@ -0,0 +1,250 @@
1collections {
2 group {
3 name: "vertice_normal";
4 max: 700 700;
5 min: 700 700;
6 images {
7 image: "data/vertice.png" COMP;
8 }
9 parts {
10 part {
11 name: "image";
12 type: IMAGE;
13 description {
14 state: "default" 0.0;
15 max: 15 15;
16 min: 15 15;
17 image{
18 normal: "data/vertice.png";
19 }
20 rel1.relative: 0.0 0.0;
21 rel2.relative: 1.0 1.0;
22 color: 255 255 255 100;
23 }
24 description {
25 state: "active" 1.0;
26 inherit: "default" 0.0;
27 color: 255 255 255 255;
28 }
29 }
30 part {
31 name: "label";
32 type: TEXT;
33 description {
34 state: "default" 0.0;
35 max: 50 8;
36 fixed: 1 1;
37 color: 200 255 0 50; /* yellow low */
38 text {
39 font: "vera";
40 size: 10;
41 min: 1 1;
42 }
43 rel1.to: "image";
44 rel1.relative: 0.5 1.0;
45 rel2.to: "image";
46 rel2.relative: 0.5 1.0;
47 rel2.offset: 0 8;
48 }
49 description {
50 state: "active" 1.0;
51 inherit: "default" 0.0;
52 color: 200 255 0 255; /* yellow visible */
53 }
54 }
55 }
56 programs {
57 program {
58 name: "state_active";
59 signal: "become_active";
60 source: "";
61 action: STATE_SET "active" 0.0;
62 target: "image";
63 target: "label";
64 transition: DECELERATE 0.5;
65 }
66 program {
67 name: "state_inactive";
68 signal: "become_inactive";
69 source: "";
70 action: STATE_SET "default" 0.0;
71 target: "image";
72 target: "label";
73 transition: DECELERATE 0.5;
74 }
75 }
76 }
77 group {
78 name: "vertice_group";
79 max: 700 700;
80 min: 700 700;
81 images {
82 image: "data/vertice.png" COMP;
83 }
84 parts {
85 part {
86 name: "image";
87 type: IMAGE;
88 description {
89 state: "default" 0.0;
90 max: 15 15;
91 min: 15 15;
92 image{
93 normal: "data/vertice.png";
94 }
95 rel1.relative: 0.0 0.0;
96 rel2.relative: 1.0 1.0;
97 color: 160 120 40 70;
98 }
99 description {
100 state: "active" 1.0;
101 inherit: "default" 0.0;
102 color: 160 120 40 170;
103 }
104 }
105 part {
106 name: "label";
107 type: TEXT;
108 description {
109 state: "default" 0.0;
110 max: 50 8;
111 fixed: 1 1;
112 color: 160 120 40 70; /* yellow low */
113 text {
114 font: "vera";
115 size: 10;
116 min: 1 1;
117 }
118 rel1.to: "image";
119 rel1.relative: 0.5 1.0;
120 rel2.to: "image";
121 rel2.relative: 0.5 1.0;
122 rel2.offset: 0 8;
123 }
124 description {
125 state: "active" 1.0;
126 inherit: "default" 0.0;
127 color: 160 120 40 170; /* yellow visible */
128 }
129 }
130 }
131 programs {
132 program {
133 name: "state_active";
134 signal: "become_active";
135 action: STATE_SET "active" 0.0;
136 target: "image";
137 transition: DECELERATE 0.5;
138 }
139 program {
140 name: "state_inactive";
141 signal: "become_inactive";
142 action: STATE_SET "default" 0.0;
143 target: "image";
144 transition: DECELERATE 0.5;
145 }
146 }
147 }
148 group {
149 name: "edge_normal";
150 max: 700 700;
151 min: 700 700;
152 images {
153 image: "data/edge.png" COMP;
154 }
155 parts {
156 part {
157 name: "image";
158 type: IMAGE;
159 description {
160 state: "default" 0.0;
161 max: 50 10;
162 min: 50 10;
163 image{
164 normal: "data/edge.png";
165 }
166 rel1.relative: 0.0 0.0;
167 rel2.relative: 1.0 1.0;
168 color: 255 255 255 50;
169 }
170 description {
171 state: "active" 1.0;
172 inherit: "default" 0.0;
173 color: 255 255 255 255;
174 }
175 }
176 }
177 programs {
178 program {
179 name: "state_active";
180 signal: "become_active";
181 action: STATE_SET "active" 0.0;
182 target: "image";
183 transition: DECELERATE 0.5;
184 }
185 }
186 }
187 group {
188 name: "edge_group";
189 max: 700 700;
190 min: 700 700;
191 images {
192 image: "data/edge.png" COMP;
193 }
194 parts {
195 part {
196 name: "image";
197 type: IMAGE;
198 description {
199 state: "default" 0.0;
200 max: 50 10;
201 min: 50 10;
202 image{
203 normal: "data/edge.png";
204 }
205 rel1.relative: 0.0 0.0;
206 rel2.relative: 1.0 1.0;
207 color: 255 120 40 70;
208 }
209 description {
210 state: "active" 1.0;
211 inherit: "default" 0.0;
212 color: 255 120 40 170;
213 }
214 }
215 }
216 programs {
217 program {
218 name: "state_active";
219 signal: "become_active";
220 action: STATE_SET "active" 0.0;
221 target: "image";
222 transition: DECELERATE 0.5;
223 }
224 }
225 }
226 group {
227 name: "blob";
228 max: 700 700;
229 min: 700 700;
230 images {
231 image: "data/blob.png" COMP;
232 }
233 parts {
234 part {
235 name: "image";
236 type: IMAGE;
237 description {
238 state: "default" 0.0;
239 max: 50 50;
240 min: 3 3;
241 image{
242 normal: "data/blob.png";
243 }
244 rel1.relative: 0.0 0.0;
245 rel2.relative: 1.0 1.0;
246 }
247 }
248 }
249 }
250}
diff --git a/examples/Makefile b/examples/Makefile
new file mode 100644
index 0000000..9ac573e
--- /dev/null
+++ b/examples/Makefile
@@ -0,0 +1,12 @@
1CFLAGS += -Wall -g
2CFLAGS += $(shell pkg-config --libs --cflags elementary)
3CFLAGS += -L../ -legraph -lecore_evas
4
5SOURCES = $(shell echo *.c)
6OBJECTS = $(SOURCES:.c=.o)
7TARGETS = $(SOURCES:.c=)
8
9all: $(TARGETS)
10
11clean:
12 rm -f $(TARGETS) $(OBJECTS)
diff --git a/examples/demoapp.c b/examples/demoapp.c
new file mode 100644
index 0000000..4e64363
--- /dev/null
+++ b/examples/demoapp.c
@@ -0,0 +1,371 @@
1#include <err.h>
2
3#include <Elementary.h>
4#include <Egraph.h>
5
6Evas_Object *_mainwin;
7Evas_Object *_egraph;
8Eina_List *_vertice_list = NULL;
9Eina_List *_group_list = NULL;
10
11static void
12_cb_add_edge(void *data, Evas_Object *obj, void *event_info)
13{
14 Egraph_Vertice *a, *b;
15 int ran, count;
16 char buf[64];
17
18 if (!_egraph)
19 return;
20
21 count = eina_list_count(_vertice_list);
22 if (count == 0) {
23 a = egraph_vertice_add(_egraph, "first", NULL);
24 _vertice_list = eina_list_append(_vertice_list, a);
25 } else {
26 ran = random() % count;
27 a = eina_list_nth(_vertice_list, ran);
28 }
29 b = egraph_vertice_add(_egraph, NULL, NULL);
30 snprintf(buf, sizeof(buf), "%d", b->id);
31 egraph_vertice_rename(_egraph, b, buf);
32 _vertice_list = eina_list_append(_vertice_list, b);
33
34 egraph_edge_add(_egraph, a, b, NULL);
35}
36
37static void
38_cb_add_50edges(void *data, Evas_Object *obj, void *event_info)
39{
40 int i;
41
42 if (!_egraph)
43 return;
44
45 for (i=0; i<50; i++)
46 _cb_add_edge(data, obj, event_info);
47}
48
49static void
50_cb_add_500edges(void *data, Evas_Object *obj, void *event_info)
51{
52 int i;
53
54 if (!_egraph)
55 return;
56
57 for (i=0; i<500; i++)
58 _cb_add_edge(data, obj, event_info);
59}
60
61static void
62_cb_del_edges(void *data, Evas_Object *obj, void *event_info)
63{
64 Eina_List *l;
65 Egraph_Vertice *v;
66
67 if (!_egraph)
68 return;
69
70 egraph_clear(_egraph);
71 _vertice_list = eina_list_free(_vertice_list);
72 _group_list = eina_list_free(_group_list);
73}
74
75static void
76_cb_add_node(void *data, Evas_Object *obj, void *event_info)
77{
78 Egraph_Vertice *v;
79 char buf[64];
80
81 if (!_egraph)
82 return;
83
84 v = egraph_vertice_add(_egraph, NULL, NULL);
85 snprintf(buf, sizeof(buf), "%d", v->id);
86 egraph_vertice_rename(_egraph, v, buf);
87 _vertice_list = eina_list_append(_vertice_list, v);
88}
89
90static void
91_cb_send_100blobs(void *data, Evas_Object *obj, void *event_info)
92{
93 Egraph_Vertice *a, *b;
94 int count, ran, i;
95
96 count = eina_list_count(_vertice_list);
97 if (!count)
98 return;
99
100 for (i=0; i<100; i++) {
101 ran = random() % count;
102 a = eina_list_nth(_vertice_list, ran);
103 ran = random() % count;
104 b = eina_list_nth(_vertice_list, ran);
105 egraph_vertice_send_blob(_egraph, a, b, 5, 0xFF000000);
106 }
107}
108
109static void
110_cb_add_10n_group(void *data, Evas_Object *obj, void *event_info)
111{
112 Egraph_Vertice *group, *v;
113 char buf[64];
114 int i;
115
116 if (!_egraph)
117 return;
118
119 group = egraph_group_add(_egraph, NULL, NULL);
120 snprintf(buf, sizeof(buf), "%d-group", group->id);
121 egraph_vertice_rename(_egraph, group, buf);
122 _group_list = eina_list_append(_group_list, group);
123 for (i=0; i<10; i++) {
124 v = egraph_vertice_add(_egraph, NULL, NULL);
125 snprintf(buf, sizeof(buf), "%d-child(%d)", v->id, group->id);
126 egraph_vertice_rename(_egraph, v, buf);
127 egraph_group_vertice_attach(_egraph, group, v);
128 _vertice_list = eina_list_append(_vertice_list, v);
129 }
130}
131
132
133static void
134_cb_show_nodes(void *data, Evas_Object *obj, void *event_info)
135{
136 egraph_display_vertices_set(_egraph, elm_check_state_get(obj));
137}
138
139static void
140_cb_show_labels(void *data, Evas_Object *obj, void *event_info)
141{
142 if (!_egraph)
143 return;
144
145 egraph_display_names_set(_egraph, elm_check_state_get(obj));
146}
147
148static void
149_cb_show_edges(void *data, Evas_Object *obj, void *event_info)
150{
151 if (!_egraph)
152 return;
153
154 egraph_display_edges_set(_egraph, elm_check_state_get(obj));
155}
156
157static void
158_cb_use_animations(void *data, Evas_Object *obj, void *event_info)
159{
160 if (!_egraph)
161 return;
162
163 egraph_use_animations_set(_egraph, elm_check_state_get(obj));
164}
165
166static void
167_cb_do_improvements(void *data, Evas_Object *obj, void *event_info)
168{
169 if (!_egraph)
170 return;
171
172 egraph_do_improvements_set(_egraph, elm_check_state_get(obj));
173}
174
175static void
176_cb_use_theme_e(void *data, Evas_Object *obj, void *event_info)
177{
178 if (!_egraph)
179 return;
180
181 egraph_theme_edges_set(_egraph, elm_check_state_get(obj));
182}
183
184static void
185_cb_layout_changed(void *data, Evas_Object *obj, void *event_info)
186{
187 Elm_Object_Item *it;
188 char *selected;
189 int layout;
190
191 if (!_egraph)
192 return;
193
194 it = event_info;
195 selected = elm_object_item_text_get(it);
196 layout = EGRAPH_LAYOUT_DEFAULT;
197 if (!strcmp(selected, "Kamada K."))
198 layout = EGRAPH_LAYOUT_KAMADAKAWAI;
199 else if (!strcmp(selected, "GraphOpt"))
200 layout = EGRAPH_LAYOUT_GRAPHOPT;
201 else if (!strcmp(selected, "Fruchterman R."))
202 layout = EGRAPH_LAYOUT_FRUCHTERMANREINGOLD;
203
204 egraph_layout_set(_egraph, layout);
205}
206
207static void
208_cb_on_done(void *data, Evas_Object *obj, void *event_info)
209{
210 elm_exit();
211}
212
213EAPI_MAIN int
214elm_main(int argc, char **argv)
215{
216 Evas_Object *win, *bg, *egraph, *panes;
217 Evas_Object *bx, *tb, *tb_it, *ck, *sc, *seg_it, *lb;
218 Evas *evas;
219 int retval = -1;
220
221 win = elm_win_add(NULL, "panes", ELM_WIN_BASIC);
222 evas = evas_object_evas_get(win);
223 elm_win_title_set(win, "Egraph demo app");
224 evas_object_smart_callback_add(win, "delete,request", _cb_on_done, NULL);
225
226 bg = elm_bg_add(win);
227 elm_win_resize_object_add(win, bg);
228 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
229 evas_object_color_set(bg, 0, 0, 0, 255);
230 evas_object_show(bg);
231
232 bx = elm_box_add(win);
233 elm_box_horizontal_set(bx, EINA_TRUE);
234 evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
235 elm_win_resize_object_add(win, bx);
236 evas_object_show(bx);
237
238 tb = elm_toolbar_add(win);
239 elm_toolbar_homogeneous_set(tb, EINA_FALSE);
240 elm_toolbar_horizontal_set(tb, EINA_FALSE);
241 elm_toolbar_shrink_mode_set(tb, ELM_TOOLBAR_SHRINK_EXPAND);
242 elm_toolbar_select_mode_set(tb, ELM_OBJECT_SELECT_MODE_ALWAYS);
243 elm_toolbar_transverse_expanded_set(tb, EINA_TRUE);
244 elm_object_style_set(tb, "item_centered");
245 evas_object_size_hint_weight_set(tb, 0.0, EVAS_HINT_EXPAND);
246 evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, EVAS_HINT_FILL);
247 elm_box_pack_end(bx, tb);
248 evas_object_show(tb);
249 elm_toolbar_item_append(tb, "object-rotate-right", "Add 1 edge",
250 _cb_add_edge, NULL);
251 elm_toolbar_item_append(tb, "object-rotate-right", "Add 50 edges",
252 _cb_add_50edges, NULL);
253 elm_toolbar_item_append(tb, "object-rotate-right", "Add 500 edges",
254 _cb_add_500edges, NULL);
255 elm_toolbar_item_append(tb, "object-rotate-right", "Add 1 node alone",
256 _cb_add_node, NULL);
257 elm_toolbar_item_append(tb, "edit-delete", "Delete all",
258 _cb_del_edges, NULL);
259 elm_toolbar_item_append(tb, "object-rotate-right", "Send 100 blobs",
260 _cb_send_100blobs, NULL);
261 elm_toolbar_item_append(tb, "object-rotate-right", "Add a 10n group",
262 _cb_add_10n_group, NULL);
263 elm_toolbar_item_separator_set(elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL), EINA_FALSE);
264 lb = elm_label_add(win);
265 elm_object_text_set(lb, "<b>Layout</b>");
266 evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
267 evas_object_size_hint_align_set(lb, EVAS_HINT_FILL, EVAS_HINT_FILL);
268 tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
269 elm_object_item_part_content_set(tb_it, "object", lb);
270 sc = elm_segment_control_add(win);
271 //evas_object_size_hint_weight_set(sc, em->weight.w, em->weight.h);
272 //evas_object_size_hint_align_set(sc, em->align.x, em->align.y);
273 seg_it = elm_segment_control_item_add(sc, NULL, "GraphOpt");
274 elm_segment_control_item_selected_set(seg_it, EINA_TRUE);
275 seg_it = elm_segment_control_item_add(sc, NULL, "Kamada K.");
276 elm_segment_control_item_selected_set(seg_it, EINA_FALSE);
277 seg_it = elm_segment_control_item_add(sc, NULL, "Fruchterman R.");
278 elm_segment_control_item_selected_set(seg_it, EINA_FALSE);
279 evas_object_smart_callback_add(sc, "changed", _cb_layout_changed, NULL);
280 evas_object_show(sc);
281 tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
282 elm_object_item_part_content_set(tb_it, "object", sc);
283 //elm_toolbar_item_separator_set(elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL), EINA_FALSE);
284 ck = elm_check_add(win);
285 elm_object_text_set(ck, "Show Node");
286 elm_check_state_set(ck, EINA_TRUE);
287 evas_object_show(ck);
288 evas_object_smart_callback_add(ck, "changed", _cb_show_nodes, NULL);
289 tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
290 elm_object_item_part_content_set(tb_it, "object", ck);
291 ck = elm_check_add(win);
292 elm_object_text_set(ck, "Show Label");
293 elm_check_state_set(ck, EINA_TRUE);
294 evas_object_show(ck);
295 evas_object_smart_callback_add(ck, "changed", _cb_show_labels, NULL);
296 tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
297 elm_object_item_part_content_set(tb_it, "object", ck);
298 ck = elm_check_add(win);
299 elm_object_text_set(ck, "Show Edges");
300 elm_check_state_set(ck, EINA_TRUE);
301 evas_object_show(ck);
302 evas_object_smart_callback_add(ck, "changed", _cb_show_edges, NULL);
303 tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
304 elm_object_item_part_content_set(tb_it, "object", ck);
305 ck = elm_check_add(win);
306 elm_object_text_set(ck, "Use animations");
307 elm_check_state_set(ck, EINA_TRUE);
308 evas_object_show(ck);
309 evas_object_smart_callback_add(ck, "changed", _cb_use_animations, NULL);
310 tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
311 elm_object_item_part_content_set(tb_it, "object", ck);
312 ck = elm_check_add(win);
313 elm_object_text_set(ck, "Do improvements");
314 elm_check_state_set(ck, EINA_TRUE);
315 evas_object_show(ck);
316 evas_object_smart_callback_add(ck, "changed", _cb_do_improvements, NULL);
317 tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
318 elm_object_item_part_content_set(tb_it, "object", ck);
319 ck = elm_check_add(win);
320 elm_object_text_set(ck, "Use theme for edges");
321 elm_check_state_set(ck, EINA_TRUE);
322 evas_object_show(ck);
323 evas_object_smart_callback_add(ck, "changed", _cb_use_theme_e, NULL);
324 tb_it = elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL);
325 elm_object_item_part_content_set(tb_it, "object", ck);
326 //elm_toolbar_item_separator_set(elm_toolbar_item_append(tb, NULL, NULL, NULL, NULL), EINA_FALSE);
327 elm_toolbar_item_append(tb, "exit", "Quit",
328 _cb_on_done, NULL);
329
330 panes = elm_panes_add(win);
331 evas_object_size_hint_weight_set(panes, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
332 evas_object_size_hint_align_set(panes, EVAS_HINT_FILL, EVAS_HINT_FILL);
333 elm_panes_content_right_size_set(panes, 0.0);
334 elm_box_pack_end(bx, panes);
335 evas_object_show(panes);
336
337 egraph = egraph_new(evas, 1);
338 if (!egraph)
339 goto quit;
340 evas_object_size_hint_weight_set(egraph, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
341 evas_object_size_hint_align_set(egraph, EVAS_HINT_FILL, EVAS_HINT_FILL);
342 evas_object_show(egraph);
343 elm_object_part_content_set(panes, "left", egraph);
344
345 lb = elm_label_add(win);
346 elm_object_style_set(lb, "marker");
347 evas_object_color_set(lb, 255, 255, 255, 255);
348 elm_object_text_set(lb,
349 "Demo application for Egraph<br/>"
350 "<br/>"
351 "Enjoy !<br/>");
352 evas_object_show(lb);
353 elm_object_part_content_set(panes, "right", lb);
354
355 evas_object_resize(win, 150, 150); // XXX workaround elm sizing issue
356 evas_object_show(win);
357 evas_object_resize(win, 950, 715);
358 evas_object_show(win);
359 _egraph = egraph;
360 _mainwin = win;
361
362 _cb_add_50edges(NULL, NULL, NULL);
363
364 elm_run();
365 retval = 0;
366
367quit:
368 elm_shutdown();
369 return retval;
370}
371ELM_MAIN()
diff --git a/examples/simplegraph.c b/examples/simplegraph.c
new file mode 100644
index 0000000..43e6d59
--- /dev/null
+++ b/examples/simplegraph.c
@@ -0,0 +1,59 @@
1#include <Ecore.h>
2#include <Ecore_Evas.h>
3#include <stdio.h>
4#include <errno.h>
5
6#include "../Egraph.h"
7
8Evas_Object *_egraph_obj = NULL;
9
10static void
11_on_destroy(Ecore_Evas *ee)
12{
13 ecore_main_loop_quit();
14}
15
16static void
17_canvas_resize_cb(Ecore_Evas *ee)
18{
19 int w, h;
20
21 printf("_canvas_resize_cb\n");
22 ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
23 evas_object_resize(_egraph_obj, w, h);
24}
25
26int
27main(void)
28{
29 Ecore_Evas *ee;
30 Evas *evas;
31 Egraph_Vertice *a, *b;
32 Egraph_Edge *e;
33
34 if (!ecore_evas_init())
35 return EXIT_FAILURE;
36 ee = ecore_evas_new(NULL, 10, 10, 100, 100, NULL);
37 if (!ee)
38 return -1;
39 ecore_evas_callback_destroy_set(ee, _on_destroy);
40 ecore_evas_callback_resize_set(ee, _canvas_resize_cb);
41 ecore_evas_show(ee);
42 evas = ecore_evas_get(ee);
43
44 _egraph_obj = egraph_new(evas, 1);
45 evas_object_resize(_egraph_obj, 100, 100);
46 evas_object_show(_egraph_obj);
47
48 a = egraph_vertice_add(_egraph_obj, "a", NULL);
49 b = egraph_vertice_add(_egraph_obj, "b", NULL);
50 e = egraph_edge_add(_egraph_obj, a, b, NULL);
51
52 ecore_main_loop_begin();
53
54 evas_object_del(_egraph_obj);
55 ecore_evas_free(ee);
56 ecore_evas_shutdown();
57
58 return (!_egraph_obj);
59}
diff --git a/retest.sh b/retest.sh
new file mode 100755
index 0000000..c778fa1
--- /dev/null
+++ b/retest.sh
@@ -0,0 +1,9 @@
1#!/bin/sh
2
3make clean && \
4 make && \
5 sudo make install && \
6 make -C tests/ clean && \
7 make -C tests/ run && \
8 make -C examples clean && \
9 make -C examples
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 0000000..8b70170
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,32 @@
1CFLAGS += -Wall -g
2CFLAGS += $(shell pkg-config --libs --cflags igraph)
3CFLAGS += $(shell pkg-config --libs --cflags efx)
4CFLAGS += -L../ -legraph -lecore_evas
5
6SOURCES = $(shell echo *.c)
7OBJECTS = $(SOURCES:.c=.o)
8TARGETS = $(SOURCES:.c=)
9
10all: $(TARGETS)
11
12run: $(TARGETS)
13 @count=0 ;\
14 errors=0 ;\
15 for test in $(TARGETS); do \
16 echo =============================================================================== ;\
17 echo $$test ;\
18 LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:../ ./$$test ;\
19 if [ $$? -eq 0 ]; then \
20 echo OK ;\
21 else \
22 echo FAILED ;\
23 errors=$$(($$errors + 1)) ;\
24 fi ;\
25 count=$$(($$count + 1)) ;\
26 done ;\
27 echo =============================================================================== ;\
28 echo "$$count tests executed, $$errors errors" ;\
29 exit $$errors
30
31clean:
32 rm -f $(TARGETS) $(OBJECTS)
diff --git a/tests/README.txt b/tests/README.txt
new file mode 100644
index 0000000..9a25111
--- /dev/null
+++ b/tests/README.txt
@@ -0,0 +1,4 @@
1egraph library unit tests
2
3do "make run" to execute them
4returns the number of tests that failed
diff --git a/tests/creategraph.c b/tests/creategraph.c
new file mode 100644
index 0000000..d27e3d5
--- /dev/null
+++ b/tests/creategraph.c
@@ -0,0 +1,37 @@
1#include <Ecore.h>
2#include <Ecore_Evas.h>
3#include <stdio.h>
4#include <errno.h>
5
6#include "../Egraph.h"
7
8int
9main(void)
10{
11 Ecore_Evas *ee;
12 Evas *evas;
13 Evas_Object *obj = NULL;
14 Egraph_Vertice *a, *b;
15 Egraph_Edge *e;
16
17 if (!ecore_evas_init())
18 return EXIT_FAILURE;
19 ee = ecore_evas_new(NULL, 10, 10, 100, 100, NULL);
20 if (!ee)
21 return -1;
22 ecore_evas_show(ee);
23 evas = ecore_evas_get(ee);
24
25 obj = egraph_new(evas, 1);
26
27 a = egraph_vertice_add(obj, "a", NULL);
28 b = egraph_vertice_add(obj, NULL, NULL);
29 e = egraph_edge_add(obj, a, b, NULL);
30 egraph_vertice_del(obj, a);
31
32 evas_object_del(obj);
33 ecore_evas_free(ee);
34 ecore_evas_shutdown();
35
36 return (!obj);
37}