1 #include "e.h"
2
3 E_API int E_EVENT_INIT_DONE = 0;
4
5 /* local variables */
6 static int done = 0;
7 static int undone = 0;
8 static Evas_Object *_e_init_object = NULL;
9 static Eina_List *splash_objs = NULL;
10 static Ecore_Timer *_e_init_timeout_timer = NULL;
11 static Ecore_Job *_e_init_update_job = NULL;
12 static Ecore_Event_Handler *_e_init_event_zone_add = NULL;
13 static Ecore_Event_Handler *_e_init_event_zone_del = NULL;
14 static Ecore_Event_Handler *_e_init_event_zone_move_resize = NULL;
15 static Eina_Bool _pre_called = EINA_FALSE;
16
17 static Eina_Bool
_e_init_cb_timeout(void * data EINA_UNUSED)18 _e_init_cb_timeout(void *data EINA_UNUSED)
19 {
20 _e_init_timeout_timer = NULL;
21 e_init_hide();
22 return ECORE_CALLBACK_CANCEL;
23 }
24
25 static void
_e_init_cb_signal_done_ok(void * data EINA_UNUSED,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)26 _e_init_cb_signal_done_ok(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
27 {
28 e_init_hide();
29 }
30
31 static void
_e_init_render_pre(void * data EINA_UNUSED,Evas * e,void * info EINA_UNUSED)32 _e_init_render_pre(void *data EINA_UNUSED, Evas *e, void *info EINA_UNUSED)
33 {
34 Eina_List *l;
35 Evas_Object *o;
36
37 _pre_called = EINA_TRUE;
38 evas_event_callback_del(e, EVAS_CALLBACK_RENDER_PRE, _e_init_render_pre);
39 EINA_LIST_FOREACH(splash_objs, l, o)
40 {
41 evas_object_show(o);
42 }
43 }
44
45 static E_Zone *
_get_zone_num(int num)46 _get_zone_num(int num)
47 {
48 E_Zone *zone;
49 Eina_List *l;
50
51 EINA_LIST_FOREACH(e_comp->zones, l, zone)
52 {
53 if ((int)zone->num == num) return zone;
54 }
55 return NULL;
56 }
57
58 static Evas_Object *
_get_splash_num(int num)59 _get_splash_num(int num)
60 {
61 Evas_Object *o;
62 Eina_List *l;
63
64 EINA_LIST_FOREACH(splash_objs, l, o)
65 {
66 int n = (intptr_t)evas_object_data_get(o, "num");
67 if (n > 0)
68 {
69 n--;
70 if (num == n) return o;
71 }
72 }
73 return NULL;
74 }
75
76 static void
_e_init_splash_obj_zone_update(Evas_Object * o,E_Zone * zone)77 _e_init_splash_obj_zone_update(Evas_Object *o, E_Zone *zone)
78 {
79 evas_object_clip_set(o, zone->bg_clip_object);
80 evas_object_move(o, zone->x, zone->y);
81 evas_object_resize(o, zone->w, zone->h);
82 evas_object_layer_set(o, E_LAYER_MAX - 1000);
83 }
84
85 static Evas_Object *
_e_init_splash_obj_new(E_Zone * zone)86 _e_init_splash_obj_new(E_Zone *zone)
87 {
88 Evas_Object *o;
89
90 o = edje_object_add(e_comp->evas);
91 evas_object_data_set(o, "num", (void *)(intptr_t)(zone->num + 1));
92 if (!zone->num)
93 {
94 e_theme_edje_object_set(o, NULL, "e/init/splash");
95 edje_object_part_text_set(o, "e.text.disable_text", "");
96 edje_object_signal_callback_add(o, "e,state,done_ok", "e",
97 _e_init_cb_signal_done_ok, NULL);
98 }
99 else
100 e_theme_edje_object_set(o, NULL, "e/init/extra_screen");
101 _e_init_splash_obj_zone_update(o, zone);
102 splash_objs = eina_list_append(splash_objs, o);
103 return o;
104 }
105
106 static void
_e_init_zone_change_job(void * data EINA_UNUSED)107 _e_init_zone_change_job(void *data EINA_UNUSED)
108 {
109 Evas_Object *o;
110 E_Zone *zone;
111 Eina_List *l, *ll;
112
113 _e_init_update_job = NULL;
114 if (done > 0) return;
115 // pass 1 - delete splash objects for zones that have gone OR
116 // update the zone obj to have the right clip and geometry
117 EINA_LIST_FOREACH_SAFE(splash_objs, l, ll, o)
118 {
119 int num = (intptr_t)evas_object_data_get(o, "num");
120 if (num > 0)
121 {
122 num--;
123 zone = _get_zone_num(num);
124 if (!zone)
125 {
126 if (o == _e_init_object)
127 {
128 if (_e_init_timeout_timer)
129 {
130 ecore_timer_del(_e_init_timeout_timer);
131 _e_init_timeout_timer =
132 ecore_timer_add(2.0, _e_init_cb_timeout, NULL);
133 }
134 _e_init_object = NULL;
135 }
136 splash_objs = eina_list_remove_list(splash_objs, l);
137 evas_object_del(o);
138 }
139 else _e_init_splash_obj_zone_update(o, zone);
140 }
141 // something went wrong - so delete it
142 else
143 {
144 if (o == _e_init_object) _e_init_object = NULL;
145 splash_objs = eina_list_remove_list(splash_objs, l);
146 evas_object_del(o);
147 }
148 }
149 // pass 2 - add splash objects for new zones
150 EINA_LIST_FOREACH(e_comp->zones, l, zone)
151 {
152 o = _get_splash_num(zone->num);
153 if (!o) // no splash obj for this zone, add one
154 {
155 o = _e_init_splash_obj_new(zone);
156 if (_pre_called) evas_object_show(o);
157 }
158 }
159 }
160
161 static Eina_Bool
_e_init_zone_change(void * data EINA_UNUSED,int type EINA_UNUSED,void * event EINA_UNUSED)162 _e_init_zone_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
163 {
164 if (_e_init_update_job) ecore_job_del(_e_init_update_job);
165 _e_init_update_job = ecore_job_add(_e_init_zone_change_job, NULL);
166 return ECORE_CALLBACK_PASS_ON;
167 }
168
169 /* public functions */
170 EINTERN int
e_init_init(void)171 e_init_init(void)
172 {
173 E_EVENT_INIT_DONE = ecore_event_type_new();
174
175 done = 0;
176 return 1;
177 }
178
179 EINTERN int
e_init_shutdown(void)180 e_init_shutdown(void)
181 {
182 /* if not killed, kill init */
183 ecore_event_handler_del(_e_init_event_zone_add);
184 ecore_event_handler_del(_e_init_event_zone_del);
185 if (_e_init_event_zone_move_resize)
186 {
187 ecore_event_handler_del(_e_init_event_zone_move_resize);
188 _e_init_event_zone_move_resize = NULL;
189 }
190 _e_init_event_zone_add = NULL;
191 _e_init_event_zone_del = NULL;
192 e_init_hide();
193 return 1;
194 }
195
196 E_API void
e_init_show(void)197 e_init_show(void)
198 {
199 Evas_Object *o;
200 E_Zone *zone;
201 Eina_List *l;
202 /* exec init */
203
204 _e_init_event_zone_add =
205 ecore_event_handler_add(E_EVENT_ZONE_ADD, _e_init_zone_change, NULL);
206 _e_init_event_zone_del =
207 ecore_event_handler_add(E_EVENT_ZONE_DEL, _e_init_zone_change, NULL);
208 _e_init_event_zone_move_resize =
209 ecore_event_handler_add(E_EVENT_ZONE_MOVE_RESIZE, _e_init_zone_change, NULL);
210 EINA_LIST_FOREACH(e_comp->zones, l, zone)
211 {
212 o = _e_init_splash_obj_new(zone);
213 if (!zone->num) _e_init_object = o;
214 }
215 evas_event_callback_add
216 (e_comp->evas, EVAS_CALLBACK_RENDER_PRE, _e_init_render_pre, NULL);
217 _e_init_timeout_timer = ecore_timer_loop_add(60.0, _e_init_cb_timeout, NULL);
218 e_init_title_set(_("Enlightenment"));
219 e_init_version_set(VERSION);
220 }
221
222 E_API void
e_init_hide(void)223 e_init_hide(void)
224 {
225 if (_e_init_event_zone_move_resize)
226 {
227 ecore_event_handler_del(_e_init_event_zone_move_resize);
228 _e_init_event_zone_move_resize = NULL;
229 }
230 E_FREE_LIST(splash_objs, evas_object_del);
231 e_comp_shape_queue();
232 _e_init_object = NULL;
233 E_FREE_FUNC(_e_init_timeout_timer, ecore_timer_del);
234 E_FREE_FUNC(_e_init_update_job, ecore_job_del);
235 }
236
237 E_API void
e_init_title_set(const char * str)238 e_init_title_set(const char *str)
239 {
240 if (!_e_init_object) return;
241 edje_object_part_text_set(_e_init_object, "e.text.title", str);
242 }
243
244 E_API void
e_init_version_set(const char * str)245 e_init_version_set(const char *str)
246 {
247 if (!_e_init_object) return;
248 edje_object_part_text_set(_e_init_object, "e.text.version", str);
249 }
250
251 E_API void
e_init_status_set(const char * str)252 e_init_status_set(const char *str)
253 {
254 if (!_e_init_object) return;
255 edje_object_part_text_set(_e_init_object, "e.text.status", str);
256 }
257
258 E_API void
e_init_done(void)259 e_init_done(void)
260 {
261 Eina_List *l;
262 Evas_Object *o;
263
264 undone--;
265 if (undone > 0) return;
266 if (!done)
267 {
268 done = 1;
269 ecore_event_add(E_EVENT_INIT_DONE, NULL, NULL, NULL);
270 EINA_LIST_FOREACH(splash_objs, l, o)
271 {
272 edje_object_signal_emit(o, "e,state,done", "e");
273 }
274 }
275 }
276
277 E_API void
e_init_undone(void)278 e_init_undone(void)
279 {
280 undone++;
281 }
282
283 E_API int
e_init_count_get(void)284 e_init_count_get(void)
285 {
286 return undone;
287 }
288