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