Git init
[platform/core/uifw/e17.git] / src / bin / e_init_main.c
1 #include "config.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include <Ecore.h>
7 #include <Ecore_X.h>
8 #include <Ecore_Evas.h>
9 #include <Ecore_Ipc.h>
10 #include <Evas.h>
11 #include <Edje.h>
12
13 #ifdef EAPI
14 #undef EAPI
15 #endif
16 #ifdef WIN32
17 # ifdef BUILDING_DLL
18 #  define EAPI __declspec(dllexport)
19 # else
20 #  define EAPI __declspec(dllimport)
21 # endif
22 #else
23 # ifdef __GNUC__
24 #  if __GNUC__ >= 4
25 /* BROKEN in gcc 4 on amd64 */
26 #if 0
27 #   pragma GCC visibility push(hidden)
28 #endif
29 #   define EAPI __attribute__ ((visibility("default")))
30 #  else
31 #   define EAPI
32 #  endif
33 # else
34 #  define EAPI
35 # endif
36 #endif
37
38 #ifdef EINTERN
39 #undef EINTERN
40 #endif
41 #ifdef __GNUC__
42 # if __GNUC__ >= 4
43 #  define EINTERN __attribute__ ((visibility("hidden")))
44 # else
45 #  define EINTERN
46 # endif
47 #else
48 # define EINTERN
49 #endif
50
51 #define E_TYPEDEFS 1
52 #include "e_xinerama.h"
53 #undef E_TYPEDEFS
54 #include "e_xinerama.h"
55
56 EINTERN int e_init_init(void);
57 EINTERN int e_init_shutdown(void);
58 EAPI void e_init_show(void);
59 EAPI void e_init_hide(void);
60 EAPI void e_init_title_set(const char *str);
61 EAPI void e_init_version_set(const char *str);
62 EAPI void e_init_status_set(const char *str);
63 EAPI void e_init_done(void);
64
65 /* local subsystem functions */
66 static int _e_ipc_init(void);
67 static Eina_Bool _e_ipc_cb_server_add(void *data, int type, void *event);
68 static Eina_Bool _e_ipc_cb_server_del(void *data, int type, void *event);
69 static Eina_Bool _e_ipc_cb_server_data(void *data, int type, void *event);
70
71 /* local subsystem globals */
72 static Ecore_Ipc_Server *_e_ipc_server = NULL;
73 static const char *theme = NULL;
74 static int font_hinting = -1;
75 static int engine = -1;
76 static const char *title = NULL;
77 static const char *verstr = NULL;
78 static Eina_List *fpath = NULL;
79 static Ecore_X_Window *initwins = NULL;
80 static int initwins_num = 0;
81 static Ecore_Ipc_Server *server = NULL;
82
83 static Eina_Bool
84 delayed_ok(void *data __UNUSED__)
85 {
86    kill(getppid(), SIGUSR2);
87    return ECORE_CALLBACK_CANCEL;
88 }
89
90 int
91 main(int argc, char **argv)
92 {
93    int i;
94    char *s;
95    double scale;
96
97    for (i = 1; i < argc; i++)
98      {
99         if ((i == 1) && 
100             ((!strcmp(argv[i], "-h")) ||
101              (!strcmp(argv[i], "-help")) ||
102              (!strcmp(argv[i], "--help"))))
103           {
104              printf(
105                     "This is an internal tool for Enlightenment.\n"
106                     "do not use it.\n"
107                     );
108              exit(0);
109           }
110         else if (!theme) theme = argv[i];
111         else if (engine < 0) engine = atoi(argv[i]);
112         else if (font_hinting < 0) font_hinting = atoi(argv[i]);
113         else if (!title) title = argv[i];
114         else if (!verstr) verstr = argv[i];
115         else fpath = eina_list_append(fpath, argv[i]);
116      }
117
118    ecore_init();
119    ecore_x_init(NULL);
120    ecore_app_args_set(argc, (const char **)argv);
121    evas_init();
122    ecore_evas_init();
123    edje_init();
124    edje_frametime_set(1.0 / 30.0);
125    s = getenv("E_SCALE");
126    scale = 1.0;
127    if (s) scale = atof(s);
128    edje_scale_set(scale);
129    ecore_ipc_init();
130
131    if (_e_ipc_init())
132      {
133         e_init_init();
134         e_init_show();
135         e_init_title_set(title);
136         e_init_version_set(verstr);
137         e_init_status_set("");
138         ecore_timer_add(0.2, delayed_ok, NULL);
139         ecore_main_loop_begin();
140      }
141
142    if (_e_ipc_server)
143      {
144         ecore_ipc_server_del(_e_ipc_server);
145         _e_ipc_server = NULL;
146      }
147
148    ecore_ipc_shutdown();
149    ecore_evas_shutdown();
150    edje_shutdown();
151    evas_shutdown();
152    ecore_x_shutdown();
153    ecore_shutdown();
154
155    return 0;
156 }
157
158 /* local subsystem functions */
159 static int
160 _e_ipc_init(void)
161 {
162    char *sdir;
163
164    sdir = getenv("E_IPC_SOCKET");
165    if (!sdir)
166      {
167         printf("The E_IPC_SOCKET environment variable is not set. This is\n"
168                "exported by Enlightenment to all processes it launches.\n"
169                "This environment variable must be set and must point to\n"
170                "Enlightenment's IPC socket file (minus port number).\n");
171         return 0;
172      }
173    _e_ipc_server = ecore_ipc_server_connect(ECORE_IPC_LOCAL_SYSTEM, sdir, 0, NULL);
174    if (!_e_ipc_server) return 0;
175
176    ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, _e_ipc_cb_server_add, NULL);
177    ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, _e_ipc_cb_server_del, NULL);
178    ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, _e_ipc_cb_server_data, NULL);
179
180    return 1;
181 }
182
183 static Eina_Bool
184 _e_ipc_cb_server_add(void *data __UNUSED__, int type __UNUSED__, void *event)
185 {
186    Ecore_Ipc_Event_Server_Add *e;
187
188    e = event;
189    server = e->server;
190    ecore_ipc_server_send(server,
191                          7/*E_IPC_DOMAIN_INIT*/,
192                          1/*hello*/,
193                          0, 0, 0,
194                          initwins, initwins_num * sizeof(Ecore_X_Window));
195    ecore_ipc_server_flush(server);
196    return ECORE_CALLBACK_PASS_ON;
197 }
198
199 static Eina_Bool
200 _e_ipc_cb_server_del(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
201 {
202    /* quit now */
203    ecore_main_loop_quit();
204    return ECORE_CALLBACK_PASS_ON;
205 }
206
207 static Eina_Bool
208 _e_ipc_cb_server_data(void *data __UNUSED__, int type __UNUSED__, void *event)
209 {
210    Ecore_Ipc_Event_Server_Data *e;
211
212    e = event;
213    if (e->major != 7/*E_IPC_DOMAIN_INIT*/) return ECORE_CALLBACK_PASS_ON;
214    switch (e->minor)
215      {
216       case 1:
217         if (e->data) e_init_status_set(e->data);
218         break;
219       case 2:
220         /* quit now */
221         e_init_done();
222         break;
223       default:
224         break;
225      }
226    return ECORE_CALLBACK_PASS_ON;
227 }
228
229 static void _e_init_cb_signal_disable(void *data, Evas_Object *obj, const char *emission, const char *source);
230 static void _e_init_cb_signal_enable(void *data, Evas_Object *obj, const char *emission, const char *source);
231 static void _e_init_cb_signal_done_ok(void *data, Evas_Object *obj, const char *emission, const char *source);
232 static Eina_Bool _e_init_cb_window_configure(void *data, int ev_type, void *ev);
233 static Eina_Bool _e_init_cb_timeout(void *data);
234 static Ecore_Evas *_e_init_evas_new(Ecore_X_Window root, int w, int h, Ecore_X_Window *winret);
235
236 /* local subsystem globals */
237 static Ecore_X_Window _e_init_root_win = 0;
238 static Ecore_X_Window _e_init_win = 0;
239 static Ecore_Evas *_e_init_ecore_evas = NULL;
240 static Evas *_e_init_evas = NULL;
241 static Evas_Object *_e_init_object = NULL;
242 static Ecore_Event_Handler *_e_init_configure_handler = NULL;
243 static Ecore_Timer *_e_init_timeout_timer = NULL;
244
245 /* externally accessible functions */
246 EINTERN int
247 e_init_init(void)
248 {
249    Ecore_X_Window root, *roots;
250    Evas_Object *o;
251    Eina_List *l, *screens;
252    int i, num, w, h;
253    const char *s;
254
255    e_xinerama_init();
256
257    _e_init_configure_handler = 
258      ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, 
259                              _e_init_cb_window_configure, NULL);
260
261    num = 0;
262    roots = ecore_x_window_root_list(&num);
263    if ((!roots) || (num <= 0)) return 0;
264    root = roots[0];
265    _e_init_root_win = root;
266
267    s = theme;
268    initwins = malloc(num * 2 * sizeof(Ecore_X_Window));
269    initwins_num = num * 2;
270
271    /* extra root windows/screens */
272    for (i = 1; i < num; i++)
273      {
274         ecore_x_window_size_get(roots[i], &w, &h);
275         _e_init_ecore_evas = _e_init_evas_new(roots[i], w, h, &_e_init_win);
276         _e_init_evas = ecore_evas_get(_e_init_ecore_evas);
277         initwins[(i * 2) + 0] = roots[i];
278         initwins[(i * 2) + 1] = _e_init_win;
279
280         o = edje_object_add(_e_init_evas);
281         edje_object_file_set(o, s, "e/init/extra_screen");
282         evas_object_move(o, 0, 0);
283         evas_object_resize(o, w, h);
284         evas_object_show(o);
285      }
286
287    /* primary screen/root */
288    ecore_x_window_size_get(root, &w, &h);
289    _e_init_ecore_evas = _e_init_evas_new(root, w, h, &_e_init_win);
290    _e_init_evas = ecore_evas_get(_e_init_ecore_evas);
291    initwins[0] = root;
292    initwins[1] = _e_init_win;
293
294    /* look at xinerama asto how to slice this up */
295    screens = (Eina_List *)e_xinerama_screens_get();
296    if (screens)
297      {
298         E_Screen *scr;
299
300         EINA_LIST_FOREACH(screens, l, scr)
301           {
302              o = edje_object_add(_e_init_evas);
303              if (l == screens)
304                {
305                   edje_object_file_set(o, s, "e/init/splash");
306                   _e_init_object = o;
307                }
308              else
309                edje_object_file_set(o, s, "e/init/extra_screen");
310              evas_object_move(o, scr->x, scr->y);
311              evas_object_resize(o, scr->w, scr->h);
312              evas_object_show(o);
313           }
314      }
315    else
316      {
317         o = edje_object_add(_e_init_evas);
318         edje_object_file_set(o, s, "e/init/splash");
319         _e_init_object = o;
320         evas_object_move(o, 0, 0);
321         evas_object_resize(o, w, h);
322         evas_object_show(o);
323      }
324
325    edje_object_part_text_set(_e_init_object, "e.text.disable_text", 
326                              "Disable splash screen");
327    edje_object_signal_callback_add(_e_init_object, "e,action,init,disable", "e",
328                                    _e_init_cb_signal_disable, NULL);
329    edje_object_signal_callback_add(_e_init_object, "e,action,init,enable", "e",
330                                    _e_init_cb_signal_enable, NULL);
331    edje_object_signal_callback_add(_e_init_object, "e,state,done_ok", "e",
332                                    _e_init_cb_signal_done_ok, NULL);
333    free(roots);
334
335    _e_init_timeout_timer = ecore_timer_add(240.0, _e_init_cb_timeout, NULL);
336    return 1;
337 }
338
339 EINTERN int
340 e_init_shutdown(void)
341 {
342    if (_e_init_configure_handler) 
343      ecore_event_handler_del(_e_init_configure_handler);
344    _e_init_configure_handler = NULL;
345    e_init_hide();
346    return 1;
347 }
348
349 EAPI void
350 e_init_show(void)
351 {
352    if (!_e_init_ecore_evas) return;
353    ecore_evas_raise(_e_init_ecore_evas);
354    ecore_evas_show(_e_init_ecore_evas);
355 }
356
357 EAPI void
358 e_init_hide(void)
359 {
360    if (!_e_init_ecore_evas) return;
361    ecore_evas_hide(_e_init_ecore_evas);
362    evas_object_del(_e_init_object);
363    ecore_evas_free(_e_init_ecore_evas);
364    _e_init_ecore_evas = NULL;
365    _e_init_evas = NULL;
366    _e_init_win = 0;
367    _e_init_object = NULL;
368 }
369
370 EAPI void
371 e_init_title_set(const char *str)
372 {
373    if (!_e_init_object) return;
374    edje_object_part_text_set(_e_init_object, "e.text.title", str);
375 }
376
377 EAPI void
378 e_init_version_set(const char *str)
379 {
380    if (!_e_init_object) return;
381    edje_object_part_text_set(_e_init_object, "e.text.version", str);
382 }
383
384 EAPI void
385 e_init_status_set(const char *str)
386 {
387    if (!_e_init_object) return;
388    edje_object_part_text_set(_e_init_object, "e.text.status", str);
389 }
390
391 EAPI void
392 e_init_done(void)
393 {
394    if (!_e_init_object) return;
395    edje_object_signal_emit(_e_init_object, "e,state,done", "e");
396    if (_e_init_timeout_timer) ecore_timer_del(_e_init_timeout_timer);
397    _e_init_timeout_timer = ecore_timer_add(60.0, _e_init_cb_timeout, NULL);
398 }
399
400
401 static void
402 _e_init_cb_signal_disable(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
403 {
404    if (!server) return;
405    ecore_ipc_server_send(server,
406                          7/*E_IPC_DOMAIN_INIT*/,
407                          2/*set splash*/,
408                          0, 0, 0,
409                          NULL, 0);
410    ecore_ipc_server_flush(server);
411 }
412
413 static void
414 _e_init_cb_signal_enable(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
415 {
416    if (!server) return;
417    ecore_ipc_server_send(server,
418                          7/*E_IPC_DOMAIN_INIT*/,
419                          2/*set splash*/,
420                          1, 0, 0,
421                          NULL, 0);
422    ecore_ipc_server_flush(server);
423 }
424
425 static void
426 _e_init_cb_signal_done_ok(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
427 {
428    e_init_hide();
429    if (_e_init_timeout_timer)
430      {
431         ecore_timer_del(_e_init_timeout_timer);
432         _e_init_timeout_timer = NULL;
433      }
434    ecore_main_loop_quit();
435 }
436
437 static Eina_Bool
438 _e_init_cb_window_configure(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
439 {
440    Ecore_X_Event_Window_Configure *e;
441
442    e = ev;
443    /* really simple - don't handle xinerama - because this event will only
444     * happen in single head */
445    if (e->win != _e_init_root_win) return ECORE_CALLBACK_PASS_ON;
446    ecore_evas_resize(_e_init_ecore_evas, e->w, e->h);
447    evas_object_resize(_e_init_object, e->w, e->h);
448    return ECORE_CALLBACK_PASS_ON;
449 }
450
451 static Eina_Bool
452 _e_init_cb_timeout(void *data __UNUSED__)
453 {
454    e_init_hide();
455    _e_init_timeout_timer = NULL;
456    ecore_main_loop_quit();
457    return ECORE_CALLBACK_CANCEL;
458 }
459
460 static Ecore_Evas *
461 _e_init_evas_new(Ecore_X_Window root, int w, int h, Ecore_X_Window *winret)
462 {
463    Ecore_Evas *ee = NULL;
464    Evas *e;
465    Eina_List *l;
466    const char *path;
467
468    if ((engine == 0) || (engine == 1))
469      {
470         ee = ecore_evas_software_x11_new(NULL, root, 0, 0, w, h);
471         ecore_evas_override_set(ee, 1);
472         ecore_evas_software_x11_direct_resize_set(ee, 1);
473         *winret = ecore_evas_software_x11_window_get(ee);
474      }
475    else if (engine == 2)
476      {
477         ee = ecore_evas_gl_x11_new(NULL, root, 0, 0, w, h);
478         ecore_evas_override_set(ee, 1);
479         ecore_evas_gl_x11_direct_resize_set(ee, 1);
480         *winret = ecore_evas_gl_x11_window_get(ee);
481      }
482    else if (engine == 3)
483      {
484         ee = ecore_evas_xrender_x11_new(NULL, root, 0, 0, w, h);
485         ecore_evas_override_set(ee, 1);
486         ecore_evas_xrender_x11_direct_resize_set(ee, 1);
487         *winret = ecore_evas_xrender_x11_window_get(ee);
488      }
489    else if (engine == 4)
490      {
491         ee = ecore_evas_software_x11_16_new(NULL, root, 0, 0, w, h);
492         ecore_evas_override_set(ee, 1);
493         ecore_evas_software_x11_16_direct_resize_set(ee, 1);
494         *winret = ecore_evas_software_x11_16_window_get(ee);
495      }
496    else
497      {
498         printf("The select engine is unknown or incorrectly set. Please specify a correct one.\n");
499         exit(0);
500      }
501
502    e = ecore_evas_get(ee);
503
504    evas_image_cache_set(e, 4096 * 1024);
505    evas_font_cache_set(e, 512 * 1024);
506
507    EINA_LIST_FOREACH(fpath, l, path) 
508      evas_font_path_append(e, path);
509
510    if (font_hinting == 0)
511      {
512         if (evas_font_hinting_can_hint(e, EVAS_FONT_HINTING_BYTECODE))
513           evas_font_hinting_set(e, EVAS_FONT_HINTING_BYTECODE);
514         else if (evas_font_hinting_can_hint(e, EVAS_FONT_HINTING_AUTO))
515           evas_font_hinting_set(e, EVAS_FONT_HINTING_AUTO);
516         else
517           evas_font_hinting_set(e, EVAS_FONT_HINTING_NONE);
518      }
519    else if (font_hinting == 1)
520      {
521         if (evas_font_hinting_can_hint(e, EVAS_FONT_HINTING_AUTO))
522           evas_font_hinting_set(e, EVAS_FONT_HINTING_AUTO);
523         else
524           evas_font_hinting_set(e, EVAS_FONT_HINTING_NONE);
525      }
526    else if (font_hinting == 2)
527      evas_font_hinting_set(e, EVAS_FONT_HINTING_NONE);
528
529    ecore_evas_name_class_set(ee, "E", "Init_Window");
530    ecore_evas_title_set(ee, "Enlightenment Init");
531
532    ecore_evas_raise(ee);
533    ecore_evas_show(ee);
534
535    return ee;
536 }