diff --git a/config/default/e.src b/config/default/e.src index b5acfdfcd..5d4ba89b2 100644 --- a/config/default/e.src +++ b/config/default/e.src @@ -519,4 +519,6 @@ group "E_Config" struct { value "device_auto_open" int: 0; value "xsettings.match_e17_theme" uchar: 1; value "xsettings.match_e17_icon_theme" uchar: 1; + value "update.check" uchar: 0; + value "update.later" uchar: 0; } diff --git a/config/illume/e.src b/config/illume/e.src index 4e5f9cca9..8a6bef4f9 100644 --- a/config/illume/e.src +++ b/config/illume/e.src @@ -1681,4 +1681,6 @@ group "E_Config" struct { value "device_desktop" int: 0; value "device_auto_mount" int: 0; value "device_auto_open" int: 0; + value "update.check" uchar: 1; + value "update.later" uchar: 0; } diff --git a/config/standard/e.src b/config/standard/e.src index daa3fea54..fc483f8bd 100644 --- a/config/standard/e.src +++ b/config/standard/e.src @@ -1851,4 +1851,6 @@ group "E_Config" struct { value "xsettings.enabled" uchar: 1; value "xsettings.match_e17_theme" uchar: 1; value "xsettings.match_e17_icon_theme" uchar: 1; + value "update.check" uchar: 1; + value "update.later" uchar: 0; } diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 164e33748..880422ca2 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -150,6 +150,7 @@ e_theme_about.h \ e_theme.h \ e_thumb.h \ e_toolbar.h \ +e_update.h \ e_user.h \ e_utils.h \ e_widget_aspect.h \ @@ -296,6 +297,7 @@ e_theme_about.c \ e_theme.c \ e_thumb.c \ e_toolbar.c \ +e_update.c \ e_user.c \ e_utils.c \ e_widget_aspect.c \ diff --git a/src/bin/e_config.c b/src/bin/e_config.c index ca32c5064..c67f6f8be 100644 --- a/src/bin/e_config.c +++ b/src/bin/e_config.c @@ -899,6 +899,9 @@ e_config_init(void) E_CONFIG_VAL(D, T, xsettings.net_icon_theme_name, STR); E_CONFIG_VAL(D, T, xsettings.gtk_font_name, STR); + E_CONFIG_VAL(D, T, update.check, UCHAR); + E_CONFIG_VAL(D, T, update.later, UCHAR); + e_config_load(); e_config_save_queue(); @@ -1164,6 +1167,11 @@ e_config_load(void) COPYVAL(xsettings.match_e17_icon_theme); IFCFGEND; + IFCFG(0x0147); + COPYVAL(update.check); + COPYVAL(update.later); + IFCFGEND; + e_config->config_version = E_CONFIG_FILE_VERSION; _e_config_free(tcfg); } diff --git a/src/bin/e_config.h b/src/bin/e_config.h index d811e1fe2..9f96b9be9 100644 --- a/src/bin/e_config.h +++ b/src/bin/e_config.h @@ -33,7 +33,7 @@ typedef struct _E_Event_Config_Icon_Theme E_Event_Config_Icon_Theme; /* increment this whenever a new set of config values are added but the users * config doesn't need to be wiped - simply new values need to be put in */ -#define E_CONFIG_FILE_GENERATION 0x0146 +#define E_CONFIG_FILE_GENERATION 0x0147 #define E_CONFIG_FILE_VERSION ((E_CONFIG_FILE_EPOCH << 16) | E_CONFIG_FILE_GENERATION) struct _E_Config @@ -333,6 +333,11 @@ struct _E_Config const char *net_icon_theme_name; // GUI const char *gtk_font_name; } xsettings; + + struct { + unsigned char check; // INTERNAL + unsigned char later; // INTERNAL + } update; }; struct _E_Config_Env_Var diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index 964d1b053..4bcbf3a16 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -141,3 +141,4 @@ #include "e_backlight.h" #include "e_deskenv.h" #include "e_xsettings.h" +#include "e_update.h" diff --git a/src/bin/e_main.c b/src/bin/e_main.c index 3c1e4f7ef..b045edf99 100644 --- a/src/bin/e_main.c +++ b/src/bin/e_main.c @@ -267,17 +267,6 @@ main(int argc, char **argv) } TS("Ecore Event Handlers Done"); -#ifdef HAVE_ECORE_IMF - TS("Ecore_IMF Init"); - if (!ecore_imf_init()) - { - e_error_message_show(_("Enlightenment cannot initialize Ecore_IMF!\n")); - _e_main_shutdown(-1); - } - TS("Ecore_IMF Init Done"); - _e_main_shutdown_push(ecore_imf_shutdown); -#endif - TS("Ecore_File Init"); if (!ecore_file_init()) { @@ -318,6 +307,17 @@ main(int argc, char **argv) ecore_x_io_error_handler_set(_e_main_cb_x_fatal, NULL); +#ifdef HAVE_ECORE_IMF + TS("Ecore_IMF Init"); + if (!ecore_imf_init()) + { + e_error_message_show(_("Enlightenment cannot initialize Ecore_IMF!\n")); + _e_main_shutdown(-1); + } + TS("Ecore_IMF Init Done"); + _e_main_shutdown_push(ecore_imf_shutdown); +#endif + TS("Ecore_Evas Init"); if (!ecore_evas_init()) { @@ -871,6 +871,15 @@ main(int argc, char **argv) TS("E_XSettings Init Done"); _e_main_shutdown_push(e_xsettings_shutdown); + TS("E_Update Init"); + if (!e_update_init()) + { + e_error_message_show(_("Enlightenment cannot initialize the Update system.\n")); + _e_main_shutdown(-1); + } + TS("E_Update Init Done"); + _e_main_shutdown_push(e_update_shutdown); + if (!after_restart) { if (e_config->show_splash) diff --git a/src/bin/e_update.c b/src/bin/e_update.c new file mode 100644 index 000000000..73394b18c --- /dev/null +++ b/src/bin/e_update.c @@ -0,0 +1,225 @@ +#include "e.h" + +static Ecore_Con_Url *url_up = NULL; +static Eina_List *handlers = NULL; +static Ecore_Timer *update_timer = NULL; +static E_Dialog *dialog = NULL; + +static void +_update_done(void) +{ + Ecore_Event_Handler *h; + + if (url_up) + { + ecore_con_url_free(url_up); + url_up = NULL; + } +} + +static void +_delete_cb(void *obj __UNUSED__) +{ + dialog = NULL; +} + +static void +_ok_cb(void *data __UNUSED__, E_Dialog *dia __UNUSED__) +{ + e_object_del(E_OBJECT(dialog)); + if (e_config->update.later > 0) + { + e_config->update.later = 0; + e_config_save_queue(); + } +} + +static void +_bother_me_later_cb(void *data __UNUSED__, E_Dialog *dia __UNUSED__) +{ + e_object_del(E_OBJECT(dialog)); + // 12 * 12 * 1hr === about 6 days. limit, so bother-me later will wait + // a week in between botherings. botherings reset on e start or restart + if (e_config->update.later < 12) + { + e_config->update.later++; + e_config_save_queue(); + } +} + +static void +_never_tell_me_cb(void *data __UNUSED__, E_Dialog *dia __UNUSED__) +{ + if (update_timer) ecore_timer_del(update_timer); + update_timer = NULL; + e_object_del(E_OBJECT(dialog)); + e_config->update.check = 0; + e_config->update.later = 0; + e_config_save_queue(); +} + +static void +_new_version(const char *ver) +{ + E_Manager *man; + E_Container *con; + char text[2048]; + + if (dialog) return; + man = e_manager_current_get(); + if (!man) return; + con = e_container_current_get(man); + if (!con) return; + + dialog = e_dialog_new(con, "E", "_update_available"); + + e_object_del_attach_func_set(E_OBJECT(dialog), _delete_cb); + e_dialog_button_add(dialog, _("OK"), NULL, + _ok_cb, NULL); + e_dialog_button_add(dialog, _("Bother me later"), NULL, + _bother_me_later_cb, NULL); + e_dialog_button_add(dialog, _("Never tell me"), NULL, + _never_tell_me_cb, NULL); + e_dialog_button_focus_num(dialog, 1); + e_dialog_title_set(dialog, _("Update Notice")); + e_dialog_icon_set(dialog, "dialog-warning", 64); + + snprintf(text, sizeof(text), + _("Your enlightenment version is
" + "not the current latest release.
" + "The latest version is:
" + "
" + "%s
" + "
" + "Please visit www.enlightenment.org
" + "or update your system packages
" + "to get a new version."), ver); + e_dialog_text_set(dialog, text); + e_win_centered_set(dialog->win, 1); + e_dialog_show(dialog); +} + +static Eina_Bool +_upload_data_cb(void *data __UNUSED__, int ev_type __UNUSED__, void *event) +{ + Ecore_Con_Event_Url_Data *ev = event; + if (ev->url_con != url_up) return EINA_TRUE; + if (ev->size > 0) + { + char *txt = alloca(ev->size + 1); + + memcpy(txt, ev->data, ev->size); + txt[ev->size] = 0; + + if (!strncmp(txt, "OK", 2)) + { + } + else if (!strncmp(txt, "OLD", 3)) + { + char *ver = strchr(txt, ' '); + if (ver) + { + ver++; + _new_version(ver); + } + } + } + return EINA_FALSE; +} + +static Eina_Bool +_upload_progress_cb(void *data __UNUSED__, int ev_type __UNUSED__, void *event) +{ + Ecore_Con_Event_Url_Progress *ev = event; + if (ev->url_con != url_up) return EINA_TRUE; + return EINA_FALSE; +} + +static Eina_Bool +_upload_complete_cb(void *data __UNUSED__, int ev_type __UNUSED__, void *event) +{ + Ecore_Con_Event_Url_Complete *ev = event; + if (ev->url_con != url_up) return EINA_TRUE; + if (ev->status != 200) + { + _update_done(); + return EINA_FALSE; + } + _update_done(); + return EINA_FALSE; +} + +static void +_update_check(void) +{ + char buf[1024]; + + if (url_up) _update_done(); + snprintf(buf, sizeof(buf), "UPDATE enlightenment %s", VERSION); + url_up = ecore_con_url_new("http://www.enlightenment.org/update.php"); + if (url_up) + ecore_con_url_post(url_up, buf, strlen(buf), "text/plain"); + else + _update_done(); +} + +static Eina_Bool +_update_timeout_cb(void *data) +{ + double t = 3600.0; // base minimum betwene checks -> 1hr min + int later = e_config->update.later; + + if (e_config->update.check) _update_check(); + if (update_timer) ecore_timer_del(update_timer); + if (later > 0) + { + later++; + t *= (later * later); + } + update_timer = ecore_timer_add(t, _update_timeout_cb, data); + return EINA_FALSE; +} + +EINTERN int +e_update_init(void) +{ + if (ecore_con_url_init()) + { + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_CON_EVENT_URL_DATA, _upload_data_cb, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_CON_EVENT_URL_PROGRESS, _upload_progress_cb, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_CON_EVENT_URL_COMPLETE, _upload_complete_cb, NULL)); + if (e_config->update.check) + { + e_config->update.check = 0; + _update_timeout_cb(NULL); + e_config->update.check = 1; + } + } + return 1; +} + +EINTERN int +e_update_shutdown(void) +{ + if (handlers) + { + _update_done(); + ecore_con_url_shutdown(); + } + if (update_timer) + { + ecore_timer_del(update_timer); + update_timer = NULL; + } + if (dialog) e_object_del(E_OBJECT(dialog)); + dialog = NULL; + _update_done(); + return 1; +} + diff --git a/src/bin/e_update.h b/src/bin/e_update.h new file mode 100644 index 000000000..fda54ab78 --- /dev/null +++ b/src/bin/e_update.h @@ -0,0 +1,7 @@ +#ifndef E_UPDATE_H +# define E_UPDATE_H + +EINTERN int e_update_init(void); +EINTERN int e_update_shutdown(void); + +#endif