510 lines
13 KiB
C
510 lines
13 KiB
C
/*
|
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
|
*/
|
|
#include "config.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <Ecore.h>
|
|
#include <Ecore_X.h>
|
|
#include <Ecore_Evas.h>
|
|
#include <Ecore_Ipc.h>
|
|
#include <Ecore_File.h>
|
|
#include <Evas.h>
|
|
#include <Eet.h>
|
|
#include <Edje.h>
|
|
|
|
#define E_TYPEDEFS 1
|
|
#include "e_xinerama.h"
|
|
#undef E_TYPEDEFS
|
|
#include "e_xinerama.h"
|
|
|
|
EAPI int e_init_init(void);
|
|
EAPI int e_init_shutdown(void);
|
|
EAPI void e_init_show(void);
|
|
EAPI void e_init_hide(void);
|
|
EAPI void e_init_title_set(const char *str);
|
|
EAPI void e_init_version_set(const char *str);
|
|
EAPI void e_init_status_set(const char *str);
|
|
EAPI void e_init_done(void);
|
|
|
|
/* local subsystem functions */
|
|
static int _e_ipc_init(void);
|
|
static int _e_ipc_cb_server_add(void *data, int type, void *event);
|
|
static int _e_ipc_cb_server_del(void *data, int type, void *event);
|
|
static int _e_ipc_cb_server_data(void *data, int type, void *event);
|
|
|
|
/* local subsystem globals */
|
|
static Ecore_Ipc_Server *_e_ipc_server = NULL;
|
|
static const char *theme = NULL;
|
|
static int font_hinting = -1;
|
|
static int engine = -1;
|
|
static const char *title = NULL;
|
|
static const char *verstr = NULL;
|
|
static Eina_List *fpath = NULL;
|
|
static Ecore_X_Window *initwins = NULL;
|
|
static int initwins_num = 0;
|
|
static Ecore_Ipc_Server *server = NULL;
|
|
|
|
static int
|
|
delayed_ok(void *data)
|
|
{
|
|
kill(getppid(), SIGUSR2);
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int i;
|
|
char *s;
|
|
double scale;
|
|
|
|
for (i = 1; i < argc; i++)
|
|
{
|
|
if ((i == 1) &&
|
|
((!strcmp(argv[i], "-h")) ||
|
|
(!strcmp(argv[i], "-help")) ||
|
|
(!strcmp(argv[i], "--help"))))
|
|
{
|
|
printf(
|
|
"This is an internal tool for Enlightenment.\n"
|
|
"do not use it.\n"
|
|
);
|
|
exit(0);
|
|
}
|
|
else if (!theme) theme = argv[i];
|
|
else if (engine < 0) engine = atoi(argv[i]);
|
|
else if (font_hinting < 0) font_hinting = atoi(argv[i]);
|
|
else if (!title) title = argv[i];
|
|
else if (!verstr) verstr = argv[i];
|
|
else fpath = eina_list_append(fpath, argv[i]);
|
|
}
|
|
|
|
ecore_init();
|
|
ecore_x_init(NULL);
|
|
ecore_app_args_set(argc, (const char **)argv);
|
|
eet_init();
|
|
evas_init();
|
|
ecore_evas_init();
|
|
edje_init();
|
|
edje_frametime_set(1.0 / 30.0);
|
|
s = getenv("E_SCALE");
|
|
scale = 1.0;
|
|
if (s) scale = atof(s);
|
|
edje_scale_set(scale);
|
|
ecore_file_init();
|
|
ecore_ipc_init();
|
|
|
|
if (_e_ipc_init())
|
|
{
|
|
e_init_init();
|
|
e_init_show();
|
|
e_init_title_set(title);
|
|
e_init_version_set(verstr);
|
|
e_init_status_set("");
|
|
ecore_timer_add(0.2, delayed_ok, NULL);
|
|
ecore_main_loop_begin();
|
|
}
|
|
|
|
if (_e_ipc_server)
|
|
{
|
|
ecore_ipc_server_del(_e_ipc_server);
|
|
_e_ipc_server = NULL;
|
|
}
|
|
|
|
ecore_ipc_shutdown();
|
|
ecore_file_shutdown();
|
|
ecore_evas_shutdown();
|
|
edje_shutdown();
|
|
evas_shutdown();
|
|
eet_shutdown();
|
|
ecore_x_shutdown();
|
|
ecore_shutdown();
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* local subsystem functions */
|
|
static int
|
|
_e_ipc_init(void)
|
|
{
|
|
char *sdir;
|
|
|
|
sdir = getenv("E_IPC_SOCKET");
|
|
if (!sdir)
|
|
{
|
|
printf("The E_IPC_SOCKET environment variable is not set. This is\n"
|
|
"exported by Enlightenment to all processes it launches.\n"
|
|
"This environment variable must be set and must point to\n"
|
|
"Enlightenment's IPC socket file (minus port number).\n");
|
|
return 0;
|
|
}
|
|
_e_ipc_server = ecore_ipc_server_connect(ECORE_IPC_LOCAL_SYSTEM, sdir, 0, NULL);
|
|
if (!_e_ipc_server) return 0;
|
|
|
|
ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, _e_ipc_cb_server_add, NULL);
|
|
ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, _e_ipc_cb_server_del, NULL);
|
|
ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, _e_ipc_cb_server_data, NULL);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
_e_ipc_cb_server_add(void *data, int type, void *event)
|
|
{
|
|
Ecore_Ipc_Event_Server_Add *e;
|
|
|
|
e = event;
|
|
server = e->server;
|
|
ecore_ipc_server_send(server,
|
|
7/*E_IPC_DOMAIN_INIT*/,
|
|
1/*hello*/,
|
|
0, 0, 0,
|
|
initwins, initwins_num * sizeof(Ecore_X_Window));
|
|
ecore_ipc_server_flush(server);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
_e_ipc_cb_server_del(void *data, int type, void *event)
|
|
{
|
|
/* quit now */
|
|
ecore_main_loop_quit();
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
_e_ipc_cb_server_data(void *data, int type, void *event)
|
|
{
|
|
Ecore_Ipc_Event_Server_Data *e;
|
|
|
|
e = event;
|
|
if (e->major != 7/*E_IPC_DOMAIN_INIT*/) return 1;
|
|
switch (e->minor)
|
|
{
|
|
case 1:
|
|
if (e->data) e_init_status_set(e->data);
|
|
break;
|
|
case 2:
|
|
/* quit now */
|
|
e_init_done();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static void _e_init_cb_signal_disable(void *data, Evas_Object *obj, const char *emission, const char *source);
|
|
static void _e_init_cb_signal_enable(void *data, Evas_Object *obj, const char *emission, const char *source);
|
|
static void _e_init_cb_signal_done_ok(void *data, Evas_Object *obj, const char *emission, const char *source);
|
|
static int _e_init_cb_window_configure(void *data, int ev_type, void *ev);
|
|
static int _e_init_cb_timeout(void *data);
|
|
static Ecore_Evas *_e_init_evas_new(Ecore_X_Window root, int w, int h, Ecore_X_Window *winret);
|
|
|
|
/* local subsystem globals */
|
|
static Ecore_X_Window _e_init_root_win = 0;
|
|
static Ecore_X_Window _e_init_win = 0;
|
|
static Ecore_Evas *_e_init_ecore_evas = NULL;
|
|
static Evas *_e_init_evas = NULL;
|
|
static Evas_Object *_e_init_object = NULL;
|
|
static Ecore_Event_Handler *_e_init_configure_handler = NULL;
|
|
static Ecore_Timer *_e_init_timeout_timer = NULL;
|
|
|
|
/* externally accessible functions */
|
|
EAPI int
|
|
e_init_init(void)
|
|
{
|
|
Ecore_X_Window root, *roots;
|
|
Evas_Object *o;
|
|
Eina_List *l, *screens;
|
|
int i, num, w, h;
|
|
const char *s;
|
|
|
|
e_xinerama_init();
|
|
|
|
_e_init_configure_handler =
|
|
ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE,
|
|
_e_init_cb_window_configure, NULL);
|
|
|
|
num = 0;
|
|
roots = ecore_x_window_root_list(&num);
|
|
if ((!roots) || (num <= 0))
|
|
{
|
|
return 0;
|
|
}
|
|
root = roots[0];
|
|
_e_init_root_win = root;
|
|
|
|
s = theme;
|
|
initwins = malloc(num * 2 * sizeof(Ecore_X_Window));
|
|
initwins_num = num * 2;
|
|
|
|
/* extra root windows/screens */
|
|
for (i = 1; i < num; i++)
|
|
{
|
|
ecore_x_window_size_get(roots[i], &w, &h);
|
|
_e_init_ecore_evas = _e_init_evas_new(roots[i], w, h, &_e_init_win);
|
|
_e_init_evas = ecore_evas_get(_e_init_ecore_evas);
|
|
initwins[(i * 2) + 0] = roots[i];
|
|
initwins[(i * 2) + 1] = _e_init_win;
|
|
|
|
o = edje_object_add(_e_init_evas);
|
|
edje_object_file_set(o, s, "e/init/extra_screen");
|
|
evas_object_move(o, 0, 0);
|
|
evas_object_resize(o, w, h);
|
|
evas_object_show(o);
|
|
}
|
|
|
|
/* primary screen/root */
|
|
ecore_x_window_size_get(root, &w, &h);
|
|
_e_init_ecore_evas = _e_init_evas_new(root, w, h, &_e_init_win);
|
|
_e_init_evas = ecore_evas_get(_e_init_ecore_evas);
|
|
initwins[0] = root;
|
|
initwins[1] = _e_init_win;
|
|
|
|
/* look at xinerama asto how to slice this up */
|
|
screens = (Eina_List *)e_xinerama_screens_get();
|
|
if (screens)
|
|
{
|
|
E_Screen *scr;
|
|
EINA_LIST_FOREACH(screens, l, scr)
|
|
{
|
|
o = edje_object_add(_e_init_evas);
|
|
if (l == screens)
|
|
{
|
|
edje_object_file_set(o, s, "e/init/splash");
|
|
_e_init_object = o;
|
|
}
|
|
else
|
|
edje_object_file_set(o, s, "e/init/extra_screen");
|
|
evas_object_move(o, scr->x, scr->y);
|
|
evas_object_resize(o, scr->w, scr->h);
|
|
evas_object_show(o);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
o = edje_object_add(_e_init_evas);
|
|
edje_object_file_set(o, s, "e/init/splash");
|
|
_e_init_object = o;
|
|
evas_object_move(o, 0, 0);
|
|
evas_object_resize(o, w, h);
|
|
evas_object_show(o);
|
|
}
|
|
|
|
edje_object_part_text_set(_e_init_object, "e.text.disable_text",
|
|
"Disable splash screen");
|
|
edje_object_signal_callback_add(_e_init_object, "e,action,init,disable", "e",
|
|
_e_init_cb_signal_disable, NULL);
|
|
edje_object_signal_callback_add(_e_init_object, "e,action,init,enable", "e",
|
|
_e_init_cb_signal_enable, NULL);
|
|
edje_object_signal_callback_add(_e_init_object, "e,state,done_ok", "e",
|
|
_e_init_cb_signal_done_ok, NULL);
|
|
free(roots);
|
|
|
|
_e_init_timeout_timer = ecore_timer_add(240.0, _e_init_cb_timeout, NULL);
|
|
return 1;
|
|
}
|
|
|
|
EAPI int
|
|
e_init_shutdown(void)
|
|
{
|
|
if (_e_init_configure_handler)
|
|
ecore_event_handler_del(_e_init_configure_handler);
|
|
_e_init_configure_handler = NULL;
|
|
e_init_hide();
|
|
return 1;
|
|
}
|
|
|
|
EAPI void
|
|
e_init_show(void)
|
|
{
|
|
if (!_e_init_ecore_evas) return;
|
|
ecore_evas_raise(_e_init_ecore_evas);
|
|
ecore_evas_show(_e_init_ecore_evas);
|
|
}
|
|
|
|
EAPI void
|
|
e_init_hide(void)
|
|
{
|
|
if (!_e_init_ecore_evas) return;
|
|
ecore_evas_hide(_e_init_ecore_evas);
|
|
evas_object_del(_e_init_object);
|
|
ecore_evas_free(_e_init_ecore_evas);
|
|
_e_init_ecore_evas = NULL;
|
|
_e_init_evas = NULL;
|
|
_e_init_win = 0;
|
|
_e_init_object = NULL;
|
|
}
|
|
|
|
EAPI void
|
|
e_init_title_set(const char *str)
|
|
{
|
|
if (!_e_init_object) return;
|
|
edje_object_part_text_set(_e_init_object, "e.text.title", str);
|
|
}
|
|
|
|
EAPI void
|
|
e_init_version_set(const char *str)
|
|
{
|
|
if (!_e_init_object) return;
|
|
edje_object_part_text_set(_e_init_object, "e.text.version", str);
|
|
}
|
|
|
|
EAPI void
|
|
e_init_status_set(const char *str)
|
|
{
|
|
if (!_e_init_object) return;
|
|
edje_object_part_text_set(_e_init_object, "e.text.status", str);
|
|
}
|
|
|
|
EAPI void
|
|
e_init_done(void)
|
|
{
|
|
if (!_e_init_object) return;
|
|
edje_object_signal_emit(_e_init_object, "e,state,done", "e");
|
|
if (_e_init_timeout_timer) ecore_timer_del(_e_init_timeout_timer);
|
|
_e_init_timeout_timer = ecore_timer_add(60.0, _e_init_cb_timeout, NULL);
|
|
}
|
|
|
|
|
|
static void
|
|
_e_init_cb_signal_disable(void *data, Evas_Object *obj, const char *emission, const char *source)
|
|
{
|
|
if (!server) return;
|
|
ecore_ipc_server_send(server,
|
|
7/*E_IPC_DOMAIN_INIT*/,
|
|
2/*set splash*/,
|
|
0, 0, 0,
|
|
NULL, 0);
|
|
ecore_ipc_server_flush(server);
|
|
}
|
|
|
|
static void
|
|
_e_init_cb_signal_enable(void *data, Evas_Object *obj, const char *emission, const char *source)
|
|
{
|
|
if (!server) return;
|
|
ecore_ipc_server_send(server,
|
|
7/*E_IPC_DOMAIN_INIT*/,
|
|
2/*set splash*/,
|
|
1, 0, 0,
|
|
NULL, 0);
|
|
ecore_ipc_server_flush(server);
|
|
}
|
|
|
|
static void
|
|
_e_init_cb_signal_done_ok(void *data, Evas_Object *obj, const char *emission, const char *source)
|
|
{
|
|
e_init_hide();
|
|
if (_e_init_timeout_timer)
|
|
{
|
|
ecore_timer_del(_e_init_timeout_timer);
|
|
_e_init_timeout_timer = NULL;
|
|
}
|
|
ecore_main_loop_quit();
|
|
}
|
|
|
|
static int
|
|
_e_init_cb_window_configure(void *data, int ev_type, void *ev)
|
|
{
|
|
Ecore_X_Event_Window_Configure *e;
|
|
|
|
e = ev;
|
|
/* really simple - don't handle xinerama - because this event will only
|
|
* happen in single head */
|
|
if (e->win != _e_init_root_win) return 1;
|
|
ecore_evas_resize(_e_init_ecore_evas, e->w, e->h);
|
|
evas_object_resize(_e_init_object, e->w, e->h);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
_e_init_cb_timeout(void *data)
|
|
{
|
|
e_init_hide();
|
|
_e_init_timeout_timer = NULL;
|
|
ecore_main_loop_quit();
|
|
return 0;
|
|
}
|
|
|
|
static Ecore_Evas *
|
|
_e_init_evas_new(Ecore_X_Window root, int w, int h, Ecore_X_Window *winret)
|
|
{
|
|
Ecore_Evas *ee = NULL;
|
|
Evas *e;
|
|
Eina_List *l;
|
|
const char *path;
|
|
|
|
if ((engine == 0) || (engine == 1))
|
|
{
|
|
ee = ecore_evas_software_x11_new(NULL, root, 0, 0, w, h);
|
|
ecore_evas_override_set(ee, 1);
|
|
ecore_evas_software_x11_direct_resize_set(ee, 1);
|
|
*winret = ecore_evas_software_x11_window_get(ee);
|
|
}
|
|
else if (engine == 2)
|
|
{
|
|
ee = ecore_evas_gl_x11_new(NULL, root, 0, 0, w, h);
|
|
ecore_evas_override_set(ee, 1);
|
|
ecore_evas_gl_x11_direct_resize_set(ee, 1);
|
|
*winret = ecore_evas_gl_x11_window_get(ee);
|
|
}
|
|
else if (engine == 3)
|
|
{
|
|
ee = ecore_evas_xrender_x11_new(NULL, root, 0, 0, w, h);
|
|
ecore_evas_override_set(ee, 1);
|
|
ecore_evas_xrender_x11_direct_resize_set(ee, 1);
|
|
*winret = ecore_evas_xrender_x11_window_get(ee);
|
|
}
|
|
else if (engine == 4)
|
|
{
|
|
ee = ecore_evas_software_x11_16_new(NULL, root, 0, 0, w, h);
|
|
ecore_evas_override_set(ee, 1);
|
|
ecore_evas_software_x11_16_direct_resize_set(ee, 1);
|
|
*winret = ecore_evas_software_x11_16_window_get(ee);
|
|
}
|
|
else
|
|
{
|
|
printf("The select engine is unknown or incorrectly set. Please specify a correct one.\n");
|
|
exit(0);
|
|
}
|
|
|
|
e = ecore_evas_get(ee);
|
|
|
|
evas_image_cache_set(e, 4096 * 1024);
|
|
evas_font_cache_set(e, 512 * 1024);
|
|
|
|
EINA_LIST_FOREACH(fpath, l, path)
|
|
evas_font_path_append(e, path);
|
|
|
|
if (font_hinting == 0)
|
|
{
|
|
if (evas_font_hinting_can_hint(e, EVAS_FONT_HINTING_BYTECODE))
|
|
evas_font_hinting_set(e, EVAS_FONT_HINTING_BYTECODE);
|
|
else if (evas_font_hinting_can_hint(e, EVAS_FONT_HINTING_AUTO))
|
|
evas_font_hinting_set(e, EVAS_FONT_HINTING_AUTO);
|
|
else
|
|
evas_font_hinting_set(e, EVAS_FONT_HINTING_NONE);
|
|
}
|
|
else if (font_hinting == 1)
|
|
{
|
|
if (evas_font_hinting_can_hint(e, EVAS_FONT_HINTING_AUTO))
|
|
evas_font_hinting_set(e, EVAS_FONT_HINTING_AUTO);
|
|
else
|
|
evas_font_hinting_set(e, EVAS_FONT_HINTING_NONE);
|
|
}
|
|
else if (font_hinting == 2)
|
|
evas_font_hinting_set(e, EVAS_FONT_HINTING_NONE);
|
|
|
|
ecore_evas_name_class_set(ee, "E", "Init_Window");
|
|
ecore_evas_title_set(ee, "Enlightenment Init");
|
|
|
|
ecore_evas_raise(ee);
|
|
ecore_evas_show(ee);
|
|
|
|
return ee;
|
|
}
|