diff --git a/configure.in b/configure.in
index 1fb9aa5ce..1d8ca1208 100644
--- a/configure.in
+++ b/configure.in
@@ -103,12 +103,15 @@ AC_SUBST(PACKAGE_LIB_DIR)
if test "x${prefix}" = "xNONE"; then
PACKAGE_DATA_DIR="${ac_default_prefix}/share/${PACKAGE}"
LOCALE_DIR="${ac_default_prefix}/share/locale"
+ PACKAGE_SYSCONF_DIR="${ac_default_prefix}/etc"
else
PACKAGE_DATA_DIR="${prefix}/share/${PACKAGE}"
LOCALE_DIR="${prefix}/share/locale"
+ PACKAGE_SYSCONF_DIR="${sysconfdir}"
fi
AC_SUBST(PACKAGE_DATA_DIR)
AC_SUBST(LOCALE_DIR)
+AC_SUBST(PACKAGE_SYSCONF_DIR)
x_dir=""
x_cflags=""
@@ -289,6 +292,7 @@ data/other/Makefile
data/xsession/Makefile
data/xsession/enlightenment.desktop
data/backgrounds/Makefile
+data/etc/Makefile
doc/Makefile
po/Makefile
intl/Makefile
diff --git a/data/Makefile.am b/data/Makefile.am
index c9590c2a2..99cfb88b2 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -1,3 +1,3 @@
MAINTAINERCLEANFILES = Makefile.in
-SUBDIRS = fonts images init themes other xsession input_methods backgrounds
+SUBDIRS = fonts images init themes other xsession input_methods backgrounds etc
diff --git a/data/etc/.cvsignore b/data/etc/.cvsignore
new file mode 100644
index 000000000..9a4d3f774
--- /dev/null
+++ b/data/etc/.cvsignore
@@ -0,0 +1,3 @@
+Makefile
+Makefile.in
+*.tar.gz
diff --git a/data/etc/Makefile.am b/data/etc/Makefile.am
new file mode 100644
index 000000000..13108007e
--- /dev/null
+++ b/data/etc/Makefile.am
@@ -0,0 +1,6 @@
+MAINTAINERCLEANFILES = Makefile.in
+filesdir = $(sysconfdir)/enlightenment
+files_DATA = \
+sysactions.conf
+
+EXTRA_DIST = $(files_DATA)
diff --git a/data/etc/sysactions.conf b/data/etc/sysactions.conf
new file mode 100644
index 000000000..72ff13fe6
--- /dev/null
+++ b/data/etc/sysactions.conf
@@ -0,0 +1,54 @@
+# ENLIGHTENMENT SYSTEM ACTIONS CONFIGURATION
+#
+# This is a system configuration for allowing or denying certain users or
+# groups to be able to do certain actions that involve system restricted
+# actions such as halt, reboot, suspend, hibernate etc.
+#
+# This file is read in order from top to bottom - the first rule to MATCH
+# will be used for a user or a group, and nothing after that is read.
+#
+# You must put all the ACTION definitons BEFORE user and group rule matches.
+# Any action definitons after a rule match has been found will be ignored.
+# This allows actions to be re-defined for different user groups, so matches
+# so the command for an action can change for matches to the rules later on.
+#
+# Any user or group NOT matched by an allow or a deny will be ALLOWED to
+# perform the action by default (system administrators should be aware of
+# this and implement whatever policies they see fit). Generally speaking
+# a user of a workstation, desktop or laptop is intended to have such abilities
+# to perform these actions, thus the default of allow. For multi-user systems
+# the system administrator is considerd capable enough to restrict what they
+# see they need to.
+#
+# A WARNING to admins: do NOT allow access for users to this system remotely
+# UNLESS you fully trust them or you have locked down permissions to halt/reboot
+# suspend etc. here first. You have been warned.
+#
+# FORMAT:
+#
+# action: halt /sbin/shutdown -h now
+# action: reboot /sbin/shutdown -r now
+# action: suspend /etc/acpi/sleep.sh force
+# action: hibernate /etc/acpi/hibernate.sh force
+#
+# user: username allow: halt reboot suspend hibernate
+# group: groupname deny: *
+# group: * deny: *
+# user: * allow: suspend
+# user: billy allow: halt reboot
+# group: staff deny: halt suspend hibernate
+#
+# etc.
+#
+# user and group name can use glob matches (* == all for example) like the
+# shell. as can action names allowed or denied.
+
+action: halt /sbin/shutdown -h now
+action: reboot /sbin/shutdown -r now
+action: suspend /etc/acpi/sleep.sh force
+action: hibernate /etc/acpi/hibernate.sh force
+
+user: root allow: *
+group: operator allow: *
+group: staff allow: *
+user: * deny: *
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
index 4919441e1..5671cc52e 100644
--- a/src/bin/Makefile.am
+++ b/src/bin/Makefile.am
@@ -10,7 +10,8 @@ INCLUDES = -I$(top_srcdir) \
-DPACKAGE_BIN_DIR=\"@PACKAGE_BIN_DIR@\" \
-DPACKAGE_LIB_DIR=\"@PACKAGE_LIB_DIR@\" \
-DPACKAGE_DATA_DIR=\"@PACKAGE_DATA_DIR@\" \
- -DLOCALE_DIR=\"@LOCALE_DIR@\"
+ -DLOCALE_DIR=\"@LOCALE_DIR@\" \
+ -DPACKAGE_SYSCONF_DIR=\"@PACKAGE_SYSCONF_DIR@\"
bin_PROGRAMS = \
enlightenment \
@@ -19,7 +20,8 @@ enlightenment_eapp \
enlightenment_eapp_cache_gen \
enlightenment_imc \
enlightenment_start \
-enlightenment_thumb
+enlightenment_thumb \
+enlightenment_sys
ENLIGHTENMENTHEADERS = \
e.h \
@@ -178,8 +180,9 @@ e_int_config_wallpaper.h \
e_int_config_wallpaper_import.h \
e_int_config_wallpaper_gradient.h \
e_color_dialog.h \
-e_fdo_menu_to_order.h
-
+e_fdo_menu_to_order.h \
+e_sys.h
+
enlightenment_src = \
e_user.c \
e_manager.c \
@@ -333,6 +336,7 @@ e_int_config_wallpaper_import.c \
e_int_config_wallpaper_gradient.c \
e_color_dialog.c \
e_fdo_menu_to_order.c \
+e_sys.c \
$(ENLIGHTENMENTHEADERS)
enlightenment_SOURCES = \
@@ -379,6 +383,15 @@ e_sha1.h
enlightenment_thumb_LDFLAGS = @e_libs@ @dlopen_libs@
+enlightenment_sys_SOURCES = \
+e_sys_main.c
+
+enlightenment_sys_LDFLAGS = @e_libs@ @dlopen_libs@
+
+setuid_root_mode = a=rx,u+s
+install-exec-hook:
+ @chmod $(setuid_root_mode) $(DESTDIR)$(bindir)/enlightenment_sys$(EXEEXT) || true
+
installed_headersdir = $(prefix)/include/enlightenment
installed_headers_DATA = $(ENLIGHTENMENTHEADERS)
diff --git a/src/bin/e_actions.c b/src/bin/e_actions.c
index d77202710..10c4cad3c 100644
--- a/src/bin/e_actions.c
+++ b/src/bin/e_actions.c
@@ -66,8 +66,6 @@ static void _e_action_free(E_Action *act);
static Evas_Bool _e_actions_cb_free(Evas_Hash *hash, const char *key, void *data, void *fdata);
static E_Maximize _e_actions_maximize_parse(const char *maximize);
-static E_Dialog *exit_dialog = NULL;
-
/* to save writing this in N places - the sctions are defined here */
/***************************************************************************/
ACT_FN_GO(window_move)
@@ -1364,14 +1362,16 @@ ACT_FN_GO(desk_deskshow_toggle)
e_desk_deskshow(zone);
}
}
+
/***************************************************************************/
+static E_Dialog *exit_dialog = NULL;
static void
_e_actions_cb_exit_dialog_ok(void *data, E_Dialog *dia)
{
- ecore_main_loop_quit();
e_object_del(E_OBJECT(exit_dialog));
exit_dialog = NULL;
+ e_sys_action_do(E_SYS_EXIT, NULL);
}
static void
@@ -1415,10 +1415,261 @@ ACT_FN_GO(exit)
/***************************************************************************/
ACT_FN_GO(restart)
{
- restart = 1;
- ecore_main_loop_quit();
+ e_sys_action_do(E_SYS_RESTART, NULL);
}
+/***************************************************************************/
+ACT_FN_GO(exit_now)
+{
+ e_sys_action_do(E_SYS_EXIT_NOW, NULL);
+}
+
+/***************************************************************************/
+static E_Dialog *logout_dialog = NULL;
+
+static void
+_e_actions_cb_logout_dialog_ok(void *data, E_Dialog *dia)
+{
+ e_object_del(E_OBJECT(logout_dialog));
+ logout_dialog = NULL;
+ e_sys_action_do(E_SYS_LOGOUT, NULL);
+}
+
+static void
+_e_actions_cb_logout_dialog_cancel(void *data, E_Dialog *dia)
+{
+ e_object_del(E_OBJECT(logout_dialog));
+ logout_dialog = NULL;
+}
+
+static void
+_e_actions_cb_logout_dialog_delete(E_Win *win)
+{
+ E_Dialog *dia;
+
+ dia = win->data;
+ _e_actions_cb_logout_dialog_cancel(NULL, dia);
+}
+
+ACT_FN_GO(logout)
+{
+ if (logout_dialog) e_object_del(E_OBJECT(logout_dialog));
+ logout_dialog = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_logout_dialog");
+ if (!logout_dialog) return;
+ e_win_delete_callback_set(logout_dialog->win, _e_actions_cb_logout_dialog_delete);
+ e_dialog_title_set(logout_dialog, _("Are you sure you want to log out?"));
+ e_dialog_text_set(logout_dialog,
+ _("You are about to log out.
"
+ "
"
+ "Are you sure you want to do this?"
+ ));
+ e_dialog_icon_set(logout_dialog, "enlightenment/logout", 64);
+ e_dialog_button_add(logout_dialog, _("Yes"), NULL,
+ _e_actions_cb_logout_dialog_ok, NULL);
+ e_dialog_button_add(logout_dialog, _("No"), NULL,
+ _e_actions_cb_logout_dialog_cancel, NULL);
+ e_dialog_button_focus_num(logout_dialog, 1);
+ e_win_centered_set(logout_dialog->win, 1);
+ e_dialog_show(logout_dialog);
+}
+
+/***************************************************************************/
+static E_Dialog *halt_dialog = NULL;
+
+static void
+_e_actions_cb_halt_dialog_ok(void *data, E_Dialog *dia)
+{
+ e_object_del(E_OBJECT(halt_dialog));
+ halt_dialog = NULL;
+ e_sys_action_do(E_SYS_HALT, NULL);
+}
+
+static void
+_e_actions_cb_halt_dialog_cancel(void *data, E_Dialog *dia)
+{
+ e_object_del(E_OBJECT(halt_dialog));
+ halt_dialog = NULL;
+}
+
+static void
+_e_actions_cb_halt_dialog_delete(E_Win *win)
+{
+ E_Dialog *dia;
+
+ dia = win->data;
+ _e_actions_cb_halt_dialog_cancel(NULL, dia);
+}
+
+ACT_FN_GO(halt)
+{
+ if (halt_dialog) e_object_del(E_OBJECT(halt_dialog));
+ halt_dialog = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_halt_dialog");
+ if (!halt_dialog) return;
+ e_win_delete_callback_set(halt_dialog->win, _e_actions_cb_halt_dialog_delete);
+ e_dialog_title_set(halt_dialog, _("Are you sure you want to turn off?"));
+ e_dialog_text_set(halt_dialog,
+ _("You requested to turn off your Computer.
"
+ "
"
+ "Are you sure you want to shut down?"
+ ));
+ e_dialog_icon_set(halt_dialog, "enlightenment/halt", 64);
+ e_dialog_button_add(halt_dialog, _("Yes"), NULL,
+ _e_actions_cb_halt_dialog_ok, NULL);
+ e_dialog_button_add(halt_dialog, _("No"), NULL,
+ _e_actions_cb_halt_dialog_cancel, NULL);
+ e_dialog_button_focus_num(halt_dialog, 1);
+ e_win_centered_set(halt_dialog->win, 1);
+ e_dialog_show(halt_dialog);
+}
+
+/***************************************************************************/
+static E_Dialog *reboot_dialog = NULL;
+
+static void
+_e_actions_cb_reboot_dialog_ok(void *data, E_Dialog *dia)
+{
+ e_object_del(E_OBJECT(reboot_dialog));
+ reboot_dialog = NULL;
+ e_sys_action_do(E_SYS_REBOOT, NULL);
+}
+
+static void
+_e_actions_cb_reboot_dialog_cancel(void *data, E_Dialog *dia)
+{
+ e_object_del(E_OBJECT(reboot_dialog));
+ reboot_dialog = NULL;
+}
+
+static void
+_e_actions_cb_reboot_dialog_delete(E_Win *win)
+{
+ E_Dialog *dia;
+
+ dia = win->data;
+ _e_actions_cb_reboot_dialog_cancel(NULL, dia);
+}
+
+ACT_FN_GO(reboot)
+{
+ if (reboot_dialog) e_object_del(E_OBJECT(reboot_dialog));
+ reboot_dialog = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_reboot_dialog");
+ if (!reboot_dialog) return;
+ e_win_delete_callback_set(reboot_dialog->win, _e_actions_cb_reboot_dialog_delete);
+ e_dialog_title_set(reboot_dialog, _("Are you sure you want to reboot?"));
+ e_dialog_text_set(reboot_dialog,
+ _("You requested to reboot your Computer.
"
+ "
"
+ "Are you sure you want to restart it?"
+ ));
+ e_dialog_icon_set(reboot_dialog, "enlightenment/reboot", 64);
+ e_dialog_button_add(reboot_dialog, _("Yes"), NULL,
+ _e_actions_cb_reboot_dialog_ok, NULL);
+ e_dialog_button_add(reboot_dialog, _("No"), NULL,
+ _e_actions_cb_reboot_dialog_cancel, NULL);
+ e_dialog_button_focus_num(reboot_dialog, 1);
+ e_win_centered_set(reboot_dialog->win, 1);
+ e_dialog_show(reboot_dialog);
+}
+
+/***************************************************************************/
+static E_Dialog *suspend_dialog = NULL;
+
+static void
+_e_actions_cb_suspend_dialog_ok(void *data, E_Dialog *dia)
+{
+ e_object_del(E_OBJECT(suspend_dialog));
+ suspend_dialog = NULL;
+ e_sys_action_do(E_SYS_SUSPEND, NULL);
+}
+
+static void
+_e_actions_cb_suspend_dialog_cancel(void *data, E_Dialog *dia)
+{
+ e_object_del(E_OBJECT(suspend_dialog));
+ suspend_dialog = NULL;
+}
+
+static void
+_e_actions_cb_suspend_dialog_delete(E_Win *win)
+{
+ E_Dialog *dia;
+
+ dia = win->data;
+ _e_actions_cb_suspend_dialog_cancel(NULL, dia);
+}
+
+ACT_FN_GO(suspend)
+{
+ if (suspend_dialog) e_object_del(E_OBJECT(suspend_dialog));
+ suspend_dialog = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_suspend_dialog");
+ if (!suspend_dialog) return;
+ e_win_delete_callback_set(suspend_dialog->win, _e_actions_cb_suspend_dialog_delete);
+ e_dialog_title_set(suspend_dialog, _("Are you sure you want to turn off?"));
+ e_dialog_text_set(suspend_dialog,
+ _("You requested to suspend your Computer.
"
+ "
"
+ "Are you sure you want to suspend?"
+ ));
+ e_dialog_icon_set(suspend_dialog, "enlightenment/suspend", 64);
+ e_dialog_button_add(suspend_dialog, _("Yes"), NULL,
+ _e_actions_cb_suspend_dialog_ok, NULL);
+ e_dialog_button_add(suspend_dialog, _("No"), NULL,
+ _e_actions_cb_suspend_dialog_cancel, NULL);
+ e_dialog_button_focus_num(suspend_dialog, 1);
+ e_win_centered_set(suspend_dialog->win, 1);
+ e_dialog_show(suspend_dialog);
+}
+
+/***************************************************************************/
+static E_Dialog *hibernate_dialog = NULL;
+
+static void
+_e_actions_cb_hibernate_dialog_ok(void *data, E_Dialog *dia)
+{
+ e_object_del(E_OBJECT(hibernate_dialog));
+ hibernate_dialog = NULL;
+ e_sys_action_do(E_SYS_HIBERNATE, NULL);
+}
+
+static void
+_e_actions_cb_hibernate_dialog_cancel(void *data, E_Dialog *dia)
+{
+ e_object_del(E_OBJECT(hibernate_dialog));
+ hibernate_dialog = NULL;
+}
+
+static void
+_e_actions_cb_hibernate_dialog_delete(E_Win *win)
+{
+ E_Dialog *dia;
+
+ dia = win->data;
+ _e_actions_cb_hibernate_dialog_cancel(NULL, dia);
+}
+
+ACT_FN_GO(hibernate)
+{
+ if (hibernate_dialog) e_object_del(E_OBJECT(hibernate_dialog));
+ hibernate_dialog = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_hibernate_dialog");
+ if (!hibernate_dialog) return;
+ e_win_delete_callback_set(hibernate_dialog->win, _e_actions_cb_hibernate_dialog_delete);
+ e_dialog_title_set(hibernate_dialog, _("Are you sure you want to hibernate?"));
+ e_dialog_text_set(hibernate_dialog,
+ _("You requested to hibernate your Computer.
"
+ "
"
+ "Are you sure you want to suspend to disk?"
+ ));
+ e_dialog_icon_set(hibernate_dialog, "enlightenment/hibernate", 64);
+ e_dialog_button_add(hibernate_dialog, _("Yes"), NULL,
+ _e_actions_cb_hibernate_dialog_ok, NULL);
+ e_dialog_button_add(hibernate_dialog, _("No"), NULL,
+ _e_actions_cb_hibernate_dialog_cancel, NULL);
+ e_dialog_button_focus_num(hibernate_dialog, 1);
+ e_win_centered_set(hibernate_dialog->win, 1);
+ e_dialog_show(hibernate_dialog);
+}
+
+/***************************************************************************/
ACT_FN_GO(pointer_resize_push)
{
E_Manager *man = NULL;
@@ -1438,6 +1689,7 @@ ACT_FN_GO(pointer_resize_push)
}
}
+/***************************************************************************/
ACT_FN_GO(pointer_resize_pop)
{
E_Manager *man = NULL;
@@ -1467,6 +1719,7 @@ ACT_FN_GO(exebuf)
e_exebuf_show(zone);
}
+/***************************************************************************/
ACT_FN_GO(desk_lock)
{
/* E_Zone *zone;
@@ -1768,16 +2021,32 @@ e_actions_init(void)
ACT_GO_MOUSE(winlist);
ACT_GO_KEY(winlist);
- /* restart */
ACT_GO(restart);
e_register_action_predef_name(_("Enlightenment"), _("Restart"), "restart", NULL,
EDIT_RESTRICT_ACTION | EDIT_RESTRICT_PARAMS, 0);
-
- /* exit */
ACT_GO(exit);
e_register_action_predef_name(_("Enlightenment"), _("Exit"), "exit", NULL,
EDIT_RESTRICT_ACTION | EDIT_RESTRICT_PARAMS, 0);
+ ACT_GO(logout);
+ e_register_action_predef_name(_("Enlightenment"), _("Log Out"), "logout", NULL,
+ EDIT_RESTRICT_ACTION | EDIT_RESTRICT_PARAMS, 0);
+ ACT_GO(exit_now);
+ e_register_action_predef_name(_("Enlightenment"), _("Exit Immediately"), "exit_now", NULL,
+ EDIT_RESTRICT_ACTION | EDIT_RESTRICT_PARAMS, 0);
+ ACT_GO(halt);
+ e_register_action_predef_name(_("System"), _("Shut Down"), "halt", NULL,
+ EDIT_RESTRICT_ACTION | EDIT_RESTRICT_PARAMS, 0);
+ ACT_GO(reboot);
+ e_register_action_predef_name(_("System"), _("Reboot"), "reboot", NULL,
+ EDIT_RESTRICT_ACTION | EDIT_RESTRICT_PARAMS, 0);
+ ACT_GO(suspend);
+ e_register_action_predef_name(_("System"), _("Suspend"), "suspend", NULL,
+ EDIT_RESTRICT_ACTION | EDIT_RESTRICT_PARAMS, 0);
+ ACT_GO(hibernate);
+ e_register_action_predef_name(_("System"), _("Suspend to Disk"), "hibernate", NULL,
+ EDIT_RESTRICT_ACTION | EDIT_RESTRICT_PARAMS, 0);
+
ACT_GO(pointer_resize_push);
ACT_GO(pointer_resize_pop);
diff --git a/src/bin/e_ilist.c b/src/bin/e_ilist.c
index 48a6305b1..1deabe5a6 100644
--- a/src/bin/e_ilist.c
+++ b/src/bin/e_ilist.c
@@ -175,6 +175,18 @@ e_ilist_selected_get(Evas_Object *obj)
return sd->selected;
}
+EAPI void
+e_ilist_unselect(Evas_Object *obj)
+{
+ E_Smart_Item *si;
+
+ API_ENTRY return;
+ if (!sd->items) return;
+ si = evas_list_nth(sd->items, sd->selected);
+ if (si) edje_object_signal_emit(si->base_obj, "e,state,unselected", "e");
+ sd->selected = -1;
+}
+
EAPI const char *
e_ilist_selected_label_get(Evas_Object *obj)
{
diff --git a/src/bin/e_ilist.h b/src/bin/e_ilist.h
index 415e0e838..68142c313 100644
--- a/src/bin/e_ilist.h
+++ b/src/bin/e_ilist.h
@@ -18,6 +18,7 @@ EAPI void e_ilist_selected_geometry_get (Evas_Object *obj, Evas_Coord *x
EAPI void e_ilist_min_size_get (Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
EAPI void e_ilist_selector_set (Evas_Object *obj, int selector);
EAPI int e_ilist_selector_get (Evas_Object *obj);
+EAPI void e_ilist_unselect (Evas_Object *obj);
EAPI void e_ilist_remove_num (Evas_Object *obj, int n);
EAPI void e_ilist_remove_label (Evas_Object *obj, const char *label);
EAPI const char *e_ilist_nth_label_get (Evas_Object *obj, int n);
diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h
index 653af4970..9955c124a 100644
--- a/src/bin/e_includes.h
+++ b/src/bin/e_includes.h
@@ -155,3 +155,5 @@
#include "e_widget_csel.h"
#include "e_color_dialog.h"
#include "e_fdo_menu_to_order.h"
+#include "e_sys.h"
+
diff --git a/src/bin/e_int_menus.c b/src/bin/e_int_menus.c
index 6c4cf0443..1dee2bf26 100644
--- a/src/bin/e_int_menus.c
+++ b/src/bin/e_int_menus.c
@@ -18,8 +18,6 @@ struct _Main_Data
};
/* local subsystem functions */
-static void _e_int_menus_quit (void);
-static void _e_int_menus_quit_cb (void *data);
static void _e_int_menus_main_del_hook (void *obj);
static void _e_int_menus_main_about (void *data, E_Menu *m, E_Menu_Item *mi);
static int _e_int_menus_main_run_defer_cb (void *data);
@@ -28,6 +26,10 @@ static int _e_int_menus_main_lock_defer_cb (void *data);
static void _e_int_menus_main_lock (void *data, E_Menu *m, E_Menu_Item*mi);
static void _e_int_menus_main_restart (void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_int_menus_main_exit (void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_main_halt (void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_main_reboot (void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_main_suspend (void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_main_hibernate (void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_int_menus_apps_scan (E_Menu *m);
static void _e_int_menus_apps_start (void *data, E_Menu *m);
static void _e_int_menus_apps_del_hook (void *obj);
@@ -56,8 +58,6 @@ static void _e_int_menus_augmentation_add (E_Menu *m, Evas_List *augmentation
static void _e_int_menus_augmentation_del (E_Menu *m, Evas_List *augmentation);
/* local subsystem globals */
-static Ecore_Job *_e_int_menus_quit_job = NULL;
-
static Evas_Hash *_e_int_menus_augmentation = NULL;
/* externally accessible functions */
@@ -150,6 +150,43 @@ e_int_menus_main_new(void)
mi = e_menu_item_new(m);
e_menu_item_separator_set(mi, 1);
+
+ if (e_sys_action_possible_get(E_SYS_HALT) ||
+ e_sys_action_possible_get(E_SYS_REBOOT) ||
+ e_sys_action_possible_get(E_SYS_SUSPEND) ||
+ e_sys_action_possible_get(E_SYS_HIBERNATE))
+ {
+ if (e_sys_action_possible_get(E_SYS_HALT))
+ {
+ mi = e_menu_item_new(m);
+ e_menu_item_label_set(mi, _("Shut Down your Computer"));
+ e_util_menu_item_edje_icon_set(mi, "enlightenment/halt");
+ e_menu_item_callback_set(mi, _e_int_menus_main_halt, NULL);
+ }
+ if (e_sys_action_possible_get(E_SYS_REBOOT))
+ {
+ mi = e_menu_item_new(m);
+ e_menu_item_label_set(mi, _("Reboot your Computer"));
+ e_util_menu_item_edje_icon_set(mi, "enlightenment/reboot");
+ e_menu_item_callback_set(mi, _e_int_menus_main_reboot, NULL);
+ }
+ if (e_sys_action_possible_get(E_SYS_SUSPEND))
+ {
+ mi = e_menu_item_new(m);
+ e_menu_item_label_set(mi, _("Suspend your Computer"));
+ e_util_menu_item_edje_icon_set(mi, "enlightenment/suspend");
+ e_menu_item_callback_set(mi, _e_int_menus_main_suspend, NULL);
+ }
+ if (e_sys_action_possible_get(E_SYS_HIBERNATE))
+ {
+ mi = e_menu_item_new(m);
+ e_menu_item_label_set(mi, _("Hibernate your Computer"));
+ e_util_menu_item_edje_icon_set(mi, "enlightenment/hibernate");
+ e_menu_item_callback_set(mi, _e_int_menus_main_hibernate, NULL);
+ }
+ mi = e_menu_item_new(m);
+ e_menu_item_separator_set(mi, 1);
+ }
mi = e_menu_item_new(m);
e_menu_item_label_set(mi, _("Restart Enlightenment"));
@@ -313,27 +350,6 @@ e_int_menus_menu_augmentation_del(const char *menu, E_Int_Menu_Augmentation *mau
}
/* local subsystem functions */
-static void
-_e_int_menus_quit(void)
-{
- if (_e_int_menus_quit_job)
- {
- ecore_job_del(_e_int_menus_quit_job);
- _e_int_menus_quit_job = NULL;
- }
- _e_int_menus_quit_job = ecore_job_add(_e_int_menus_quit_cb, NULL);
-}
-
-static void
-_e_int_menus_quit_cb(void *data)
-{
- E_Action *a;
-
- a = e_action_find("exit");
- if ((a) && (a->func.go)) a->func.go(NULL, NULL);
- _e_int_menus_quit_job = NULL;
-}
-
static void
_e_int_menus_main_del_hook(void *obj)
{
@@ -428,7 +444,46 @@ _e_int_menus_main_restart(void *data, E_Menu *m, E_Menu_Item *mi)
static void
_e_int_menus_main_exit(void *data, E_Menu *m, E_Menu_Item *mi)
{
- if (!e_util_immortal_check()) _e_int_menus_quit();
+ E_Action *a;
+
+ a = e_action_find("exit");
+ if ((a) && (a->func.go)) a->func.go(NULL, NULL);
+}
+
+static void
+_e_int_menus_main_halt(void *data, E_Menu *m, E_Menu_Item *mi)
+{
+ E_Action *a;
+
+ a = e_action_find("halt");
+ if ((a) && (a->func.go)) a->func.go(NULL, NULL);
+}
+
+static void
+_e_int_menus_main_reboot(void *data, E_Menu *m, E_Menu_Item *mi)
+{
+ E_Action *a;
+
+ a = e_action_find("reboot");
+ if ((a) && (a->func.go)) a->func.go(NULL, NULL);
+}
+
+static void
+_e_int_menus_main_suspend(void *data, E_Menu *m, E_Menu_Item *mi)
+{
+ E_Action *a;
+
+ a = e_action_find("suspend");
+ if ((a) && (a->func.go)) a->func.go(NULL, NULL);
+}
+
+static void
+_e_int_menus_main_hibernate(void *data, E_Menu *m, E_Menu_Item *mi)
+{
+ E_Action *a;
+
+ a = e_action_find("hibernate");
+ if ((a) && (a->func.go)) a->func.go(NULL, NULL);
}
static void
diff --git a/src/bin/e_main.c b/src/bin/e_main.c
index 1eec4641d..72db3aece 100644
--- a/src/bin/e_main.c
+++ b/src/bin/e_main.c
@@ -457,6 +457,14 @@ main(int argc, char **argv)
}
_e_main_shutdown_push(e_thumb_shutdown);
+ /* init the enlightenment sys command system */
+ if (!e_sys_init())
+ {
+ e_error_message_show(_("Enlightenment cannot initialize the System Command system.\n"));
+ _e_main_shutdown(-1);
+ }
+ _e_main_shutdown_push(e_sys_shutdown);
+
/* init the enlightenment file manager */
if (!e_fm_icon_init() || !e_fm_init() || !e_fm2_init())
diff --git a/src/bin/e_sys.c b/src/bin/e_sys.c
new file mode 100644
index 000000000..cd7065e91
--- /dev/null
+++ b/src/bin/e_sys.c
@@ -0,0 +1,192 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "e.h"
+
+/* local subsystem functions */
+static int _e_sys_cb_exit(void *data, int type, void *event);
+
+static Ecore_Event_Handler *_e_sys_exe_exit_handler = NULL;
+static int _e_sys_exe_pending = 0;
+static Ecore_Exe *_e_sys_halt_check_exe = NULL;
+static Ecore_Exe *_e_sys_reboot_check_exe = NULL;
+static Ecore_Exe *_e_sys_suspend_check_exe = NULL;
+static Ecore_Exe *_e_sys_hibernate_check_exe = NULL;
+static int _e_sys_can_halt = 0;
+static int _e_sys_can_reboot = 0;
+static int _e_sys_can_suspend = 0;
+static int _e_sys_can_hibernate = 0;
+
+/* externally accessible functions */
+EAPI int
+e_sys_init(void)
+{
+ char buf[4096];
+
+ /* this is not optimal - but it does work cleanly */
+ _e_sys_exe_exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
+ _e_sys_cb_exit, NULL);
+ snprintf(buf, sizeof(buf), "%s/enlightenment_sys -t halt", e_prefix_bin_get());
+ _e_sys_halt_check_exe = ecore_exe_run(buf, NULL);
+ _e_sys_exe_pending++;
+ snprintf(buf, sizeof(buf), "%s/enlightenment_sys -t reboot", e_prefix_bin_get());
+ _e_sys_reboot_check_exe = ecore_exe_run(buf, NULL);
+ _e_sys_exe_pending++;
+ snprintf(buf, sizeof(buf), "%s/enlightenment_sys -t suspend", e_prefix_bin_get());
+ _e_sys_suspend_check_exe = ecore_exe_run(buf, NULL);
+ _e_sys_exe_pending++;
+ snprintf(buf, sizeof(buf), "%s/enlightenment_sys -t hibernate", e_prefix_bin_get());
+ _e_sys_hibernate_check_exe = ecore_exe_run(buf, NULL);
+ _e_sys_exe_pending++;
+ return 1;
+}
+
+EAPI int
+e_sys_shutdown(void)
+{
+ if (_e_sys_exe_exit_handler)
+ ecore_event_handler_del(_e_sys_exe_exit_handler);
+ _e_sys_exe_exit_handler = NULL;
+ _e_sys_halt_check_exe = NULL;
+ _e_sys_reboot_check_exe = NULL;
+ _e_sys_suspend_check_exe = NULL;
+ _e_sys_hibernate_check_exe = NULL;
+ return 1;
+}
+
+EAPI int
+e_sys_action_possible_get(E_Sys_Action a)
+{
+ switch (a)
+ {
+ case E_SYS_EXIT:
+ case E_SYS_RESTART:
+ case E_SYS_EXIT_NOW:
+ return 1;
+ case E_SYS_LOGOUT:
+ return 0;
+ case E_SYS_HALT:
+ return _e_sys_can_halt;
+ case E_SYS_REBOOT:
+ return _e_sys_can_reboot;
+ case E_SYS_SUSPEND:
+ return _e_sys_can_suspend;
+ case E_SYS_HIBERNATE:
+ return _e_sys_can_hibernate;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+EAPI int
+e_sys_action_do(E_Sys_Action a, char *param)
+{
+ char buf[4096];
+
+ switch (a)
+ {
+ case E_SYS_EXIT:
+ if (!e_util_immortal_check())
+ ecore_main_loop_quit();
+ break;
+ case E_SYS_RESTART:
+ restart = 1;
+ ecore_main_loop_quit();
+ break;
+ case E_SYS_EXIT_NOW:
+ exit(0);
+ break;
+ case E_SYS_LOGOUT:
+ /* FIXME: go through to every window and if it wants delete req - ask
+ * it to delete, otherwise just close it. set handler for window
+ * deletes, and once all windows are deleted - exit, OR if a timer
+ * expires - pop up dialog saying something is not responding
+ */
+ break;
+ case E_SYS_HALT:
+ /* shutdown -h now */
+ snprintf(buf, sizeof(buf), "%s/enlightenment_sys halt",
+ e_prefix_bin_get());
+ ecore_exe_run(buf, NULL);
+ /* FIXME: track command return value and have dialog */
+ break;
+ case E_SYS_REBOOT:
+ /* shutdown -r now */
+ snprintf(buf, sizeof(buf), "%s/enlightenment_sys reboot",
+ e_prefix_bin_get());
+ ecore_exe_run(buf, NULL);
+ /* FIXME: track command return value and have dialog */
+ break;
+ case E_SYS_SUSPEND:
+ /* /etc/acpi/sleep.sh force */
+ snprintf(buf, sizeof(buf), "%s/enlightenment_sys suspend",
+ e_prefix_bin_get());
+ ecore_exe_run(buf, NULL);
+ /* FIXME: track command return value and have dialog */
+ break;
+ case E_SYS_HIBERNATE:
+ /* /etc/acpi/hibernate.sh force */
+ snprintf(buf, sizeof(buf), "%s/enlightenment_sys hibernate",
+ e_prefix_bin_get());
+ ecore_exe_run(buf, NULL);
+ /* FIXME: track command return value and have dialog */
+ break;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+/* local subsystem functions */
+static int
+_e_sys_cb_exit(void *data, int type, void *event)
+{
+ Ecore_Exe_Event_Del *ev;
+
+ ev = event;
+ if ((_e_sys_halt_check_exe) && (ev->exe == _e_sys_halt_check_exe))
+ {
+ if (ev->exit_code == 0)
+ {
+ _e_sys_can_halt = 1;
+ _e_sys_halt_check_exe = NULL;
+ }
+ _e_sys_exe_pending--;
+ }
+ else if ((_e_sys_reboot_check_exe) && (ev->exe == _e_sys_reboot_check_exe))
+ {
+ if (ev->exit_code == 0)
+ {
+ _e_sys_can_reboot = 1;
+ _e_sys_reboot_check_exe = NULL;
+ }
+ _e_sys_exe_pending--;
+ }
+ else if ((_e_sys_suspend_check_exe) && (ev->exe == _e_sys_suspend_check_exe))
+ {
+ if (ev->exit_code == 0)
+ {
+ _e_sys_can_suspend = 1;
+ _e_sys_suspend_check_exe = NULL;
+ }
+ _e_sys_exe_pending--;
+ }
+ else if ((_e_sys_hibernate_check_exe) && (ev->exe == _e_sys_hibernate_check_exe))
+ {
+ if (ev->exit_code == 0)
+ {
+ _e_sys_can_hibernate = 1;
+ _e_sys_hibernate_check_exe = NULL;
+ }
+ _e_sys_exe_pending--;
+ }
+
+ if (_e_sys_exe_pending <= 0)
+ {
+ if (_e_sys_exe_exit_handler)
+ ecore_event_handler_del(_e_sys_exe_exit_handler);
+ _e_sys_exe_exit_handler = NULL;
+ }
+ return 1;
+}
diff --git a/src/bin/e_sys.h b/src/bin/e_sys.h
new file mode 100644
index 000000000..f4350cc21
--- /dev/null
+++ b/src/bin/e_sys.h
@@ -0,0 +1,30 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#ifdef E_TYPEDEFS
+
+typedef enum _E_Sys_Action E_Sys_Action;
+
+enum _E_Sys_Action
+{
+ E_SYS_EXIT,
+ E_SYS_RESTART,
+ E_SYS_EXIT_NOW,
+ E_SYS_LOGOUT,
+ E_SYS_HALT,
+ E_SYS_REBOOT,
+ E_SYS_SUSPEND,
+ E_SYS_HIBERNATE
+};
+
+#else
+#ifndef E_SYS_H
+#define E_SYS_H
+
+EAPI int e_sys_init(void);
+EAPI int e_sys_shutdown(void);
+EAPI int e_sys_action_possible_get(E_Sys_Action a);
+EAPI int e_sys_action_do(E_Sys_Action a, char *param);
+
+#endif
+#endif
diff --git a/src/bin/e_sys_main.c b/src/bin/e_sys_main.c
new file mode 100644
index 000000000..53a3cb892
--- /dev/null
+++ b/src/bin/e_sys_main.c
@@ -0,0 +1,232 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* local subsystem functions */
+static int auth_action_ok(char *a);
+static int auth_etc_enlightenment_sysactions(char *a, char *u, char *g);
+static char *get_word(char *s, char *d);
+
+/* local subsystem globals */
+Evas_Hash *actions = NULL;
+
+/* externally accessible functions */
+int
+main(int argc, char **argv)
+{
+ int i;
+ int test = 0;
+ char *action, *cmd;
+
+ for (i = 1; i < argc; i++)
+ {
+ if ((!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);
+ }
+ }
+ if (argc == 3)
+ {
+ if (!strcmp(argv[1], "-t")) test = 1;
+ action = argv[2];
+ }
+ else if (argc == 2)
+ {
+ action = argv[1];
+ }
+ else
+ {
+ exit(-1);
+ }
+
+ evas_init();
+
+ if (!auth_action_ok(action))
+ {
+ printf("ERROR: ACTION NOT ALLOWED: %s\n", action);
+ exit(10);
+ }
+ /* we can add more levels of auth here */
+
+ cmd = evas_hash_find(actions, action);
+ if (!cmd)
+ {
+ printf("ERROR: UNDEFINED ACTION: %s\n", action);
+ exit(20);
+ }
+ if (!test) return system(cmd);
+
+ evas_shutdown();
+
+ return 0;
+}
+
+/* local subsystem functions */
+static int
+auth_action_ok(char *a)
+{
+ struct passwd *pw;
+ struct group *gp;
+ char *usr = NULL, *grp;
+ int ret;
+
+ pw = getpwuid(getuid());
+ if (!pw) return 0;
+ usr = pw->pw_name;
+ if (!usr) return 0;
+ gp = getgrgid(getgid());
+ if (gp) grp = gp->gr_name;
+ /* first stage - check:
+ * PREFIX/etc/enlightenment/sysactions.conf
+ */
+ ret = auth_etc_enlightenment_sysactions(a, usr, grp);
+ if (ret == 1) return 1;
+ else if (ret == -1) return 0;
+ /* the DEFAULT - allow */
+ return 1;
+}
+
+static int
+auth_etc_enlightenment_sysactions(char *a, char *u, char *g)
+{
+ FILE *f;
+ char file[4096], buf[4096], id[4096], ugname[4096], perm[4096], act[4096];
+ char *p, *pp, *s;
+ int len, line = 0, ok = 0;
+ int allow = 0;
+ int deny = 0;
+
+ snprintf(file, sizeof(file), "/etc/enlightenment/sysactions.conf");
+ f = fopen(file, "r");
+ if (!f)
+ {
+ snprintf(file, sizeof(file), PACKAGE_SYSCONF_DIR"/enlightenment/sysactions.conf");
+ f = fopen(file, "r");
+ if (!f) return 0;
+ }
+ while (fgets(buf, sizeof(buf), f))
+ {
+ line++;
+ len = strlen(buf);
+ if (len < 1) continue;
+ if (buf[len - 1] == '\n') buf[len - 1] = 0;
+ /* format:
+ *
+ * # comment
+ * user: username [allow:|deny:] halt reboot ...
+ * group: groupname [allow:|deny:] suspend ...
+ */
+ if (buf[0] == '#') continue;
+ p = buf;
+ p = get_word(p, id);
+ p = get_word(p, ugname);
+ pp = p;
+ p = get_word(p, perm);
+ allow = 0;
+ deny = 0;
+ if (!strcmp(id, "user:"))
+ {
+ if (!fnmatch(u, ugname, 0))
+ {
+ if (!strcmp(perm, "allow:")) allow = 1;
+ else if (!strcmp(perm, "deny:")) deny = 1;
+ else
+ goto malformed;
+ }
+ else
+ continue;
+ }
+ else if (!strcmp(id, "group:"))
+ {
+ if (!fnmatch(u, ugname, 0))
+ {
+ if (!strcmp(perm, "allow:")) allow = 1;
+ else if (!strcmp(perm, "deny:")) deny = 1;
+ else
+ goto malformed;
+ }
+ else
+ continue;
+ }
+ else if (!strcmp(id, "action:"))
+ {
+ while ((*pp) && (isspace(*pp))) pp++;
+ s = evas_hash_find(actions, ugname);
+ if (s)
+ {
+ actions = evas_hash_del(actions, ugname, s);
+ free(s);
+ }
+ actions = evas_hash_add(actions, ugname, strdup(pp));
+ continue;
+ }
+ else if (id[0] == 0)
+ continue;
+ else
+ goto malformed;
+
+ for (;;)
+ {
+ p = get_word(p, act);
+ if (act[0] == 0) break;
+ if (!fnmatch(act, a, 0))
+ {
+ if (allow) ok = 1;
+ else if (deny) ok = -1;
+ goto done;
+ }
+ }
+
+ continue;
+ malformed:
+ printf("WARNING: %s:%i\n"
+ "LINE: '%s'\n"
+ "MALFORMED LINE. SKIPPED.\n",
+ file, line, buf);
+ }
+ done:
+ fclose(f);
+ return ok;
+}
+
+static char *
+get_word(char *s, char *d)
+{
+ char *p1, *p2;
+
+ p1 = s;
+ p2 = d;
+ while (*p1)
+ {
+ if (p2 == d)
+ {
+ if (isspace(*p1))
+ {
+ p1++;
+ continue;
+ }
+ }
+ if (isspace(*p1)) break;
+ *p2 = *p1;
+ p1++;
+ p2++;
+ }
+ *p2 = 0;
+ return p1;
+}
+
diff --git a/src/bin/e_widget_ilist.c b/src/bin/e_widget_ilist.c
index 24db6e0b1..6e09f7adb 100644
--- a/src/bin/e_widget_ilist.c
+++ b/src/bin/e_widget_ilist.c
@@ -105,6 +105,15 @@ e_widget_ilist_selected_get(Evas_Object *obj)
return e_ilist_selected_get(wd->o_ilist);
}
+EAPI void
+e_widget_ilist_unselect(Evas_Object *obj)
+{
+ E_Widget_Data *wd;
+
+ wd = e_widget_data_get(obj);
+ e_ilist_unselect(wd->o_ilist);
+}
+
EAPI const char *
e_widget_ilist_selected_label_get(Evas_Object *obj)
{
diff --git a/src/bin/e_widget_ilist.h b/src/bin/e_widget_ilist.h
index bcc29add7..fbb79d207 100644
--- a/src/bin/e_widget_ilist.h
+++ b/src/bin/e_widget_ilist.h
@@ -13,6 +13,7 @@ EAPI void e_widget_ilist_selected_set(Evas_Object *obj, int n);
EAPI void e_widget_ilist_selector_set(Evas_Object *obj, int selector);
EAPI void e_widget_ilist_go(Evas_Object *obj);
EAPI int e_widget_ilist_selected_get(Evas_Object *obj);
+EAPI void e_widget_ilist_unselect(Evas_Object *obj);
EAPI const char *e_widget_ilist_selected_label_get(Evas_Object *obj);
EAPI void e_widget_ilist_remove_num(Evas_Object *obj, int n);
EAPI void e_widget_ilist_remove_label(Evas_Object *obj, const char *label);
diff --git a/src/modules/battery/e_mod_main.c b/src/modules/battery/e_mod_main.c
index dd59bafdb..b07b32896 100644
--- a/src/modules/battery/e_mod_main.c
+++ b/src/modules/battery/e_mod_main.c
@@ -101,6 +101,7 @@ _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
_button_cb_mouse_down, inst);
battery_config->instances = evas_list_append(battery_config->instances, inst);
battery_config->battery_check_mode = CHECK_NONE;
+ battery_config->battery_prev_level = -1;
battery_config->battery_prev_drain = 1;
battery_config->battery_prev_ac = -1;
battery_config->battery_prev_battery = -1;
@@ -391,14 +392,15 @@ _battery_linux_acpi_check(void)
{
FILE *f;
char *tmp;
+ int design_cap;
+ int last_full;
snprintf(buf, sizeof(buf), "/proc/acpi/battery/%s/info", name);
f = fopen(buf, "r");
if (f)
{
- int design_cap = 0;
- int last_full = 0;
-
+ design_cap = 0;
+ last_full = 0;
/* present */
fgets(buf2, sizeof(buf2), f); buf2[sizeof(buf2) - 1] = 0;
/* design capacity */
@@ -420,8 +422,6 @@ _battery_linux_acpi_check(void)
free(tmp);
}
fclose(f);
- bat_max += design_cap;
- bat_filled += last_full;
}
snprintf(buf, sizeof(buf), "/proc/acpi/battery/%s/state", name);
f = fopen(buf, "r");
@@ -448,7 +448,7 @@ _battery_linux_acpi_check(void)
tmp = _battery_string_get(buf2);
if (tmp)
{
- if (!strcmp(tmp, "unknown")) rate_unknown = 1;
+ if (!strcmp(tmp, "unknown")) rate_unknown++;
else rate = atoi(tmp);
free(tmp);
}
@@ -457,7 +457,7 @@ _battery_linux_acpi_check(void)
tmp = _battery_string_get(buf2);
if (tmp)
{
- if (!strcmp(tmp, "unknown")) level_unknown = 1;
+ if (!strcmp(tmp, "unknown")) level_unknown++;
else level = atoi(tmp);
free(tmp);
}
@@ -472,15 +472,18 @@ _battery_linux_acpi_check(void)
if (!strcmp(charging_state, "discharging"))
{
discharging++;
- if ((rate == 0) && (rate_unknown == 0)) rate_unknown = 1;
+ if ((rate == 0) && (rate_unknown == 0)) rate_unknown++;
}
else if (!strcmp(charging_state, "charging"))
{
charging++;
- if ((rate == 0) && (rate_unknown == 0)) rate_unknown = 1;
+ if ((rate == 0) && (rate_unknown == 0)) rate_unknown++;
}
else if (!strcmp(charging_state, "charged"))
- rate_unknown = 0;
+ {
+// level = last_full;
+ rate_unknown--;
+ }
free(charging_state);
}
E_FREE(capacity_state);
@@ -488,17 +491,36 @@ _battery_linux_acpi_check(void)
bat_drain += rate;
bat_level += level;
}
+ bat_max += design_cap;
+ bat_filled += last_full;
}
ecore_list_destroy(bats);
}
-
- if (battery_config->battery_prev_drain < 1) battery_config->battery_prev_drain = 1;
- if (bat_drain < 1) bat_drain = battery_config->battery_prev_drain;
- battery_config->battery_prev_drain = bat_drain;
-
+
+ if ((rate_unknown) && (bat_level != battery_config->battery_prev_level) &&
+ (battery_config->battery_prev_level >= 0))
+ {
+ bat_drain =
+ ((bat_level - battery_config->battery_prev_level) * 60 * 60) /
+ battery_config->poll_time;
+ if (bat_drain < 0) bat_drain = -bat_drain;
+ if (bat_drain == 0) bat_drain = 1;
+ rate_unknown = 0;
+ }
+ else
+ {
+ if (battery_config->battery_prev_drain < 1)
+ battery_config->battery_prev_drain = 1;
+ if (bat_drain < 1)
+ bat_drain = battery_config->battery_prev_drain;
+ battery_config->battery_prev_drain = bat_drain;
+ }
+
if (bat_filled > 0) bat_val = (100 * bat_level) / bat_filled;
else bat_val = 100;
+ battery_config->battery_prev_level = bat_level;
+
if (discharging) minutes = (60 * bat_level) / bat_drain;
else
{
diff --git a/src/modules/battery/e_mod_main.h b/src/modules/battery/e_mod_main.h
index e97247a06..c1bc9500e 100644
--- a/src/modules/battery/e_mod_main.h
+++ b/src/modules/battery/e_mod_main.h
@@ -28,6 +28,7 @@ struct _Config
int battery_prev_drain;
int battery_prev_ac;
int battery_prev_battery;
+ int battery_prev_level;
};
#ifdef __FreeBSD__
diff --git a/src/modules/cpufreq/Makefile.am b/src/modules/cpufreq/Makefile.am
index c7e33340a..5551a3c0c 100644
--- a/src/modules/cpufreq/Makefile.am
+++ b/src/modules/cpufreq/Makefile.am
@@ -29,7 +29,7 @@ freqset_DATA = \
freqset$(EXEEXT)
setuid_root_mode = a=rx,u+s
-install-data-hook:
+install-exec-hook:
@chmod $(setuid_root_mode) $(DESTDIR)$(freqsetdir)/freqset$(EXEEXT) || true
noinst_PROGRAMS = freqset
diff --git a/src/modules/cpufreq/freqset.c b/src/modules/cpufreq/freqset.c
index 655be0193..5f12e7d20 100644
--- a/src/modules/cpufreq/freqset.c
+++ b/src/modules/cpufreq/freqset.c
@@ -53,29 +53,21 @@ main(int argc, char *argv[])
#else
if (!strcmp(argv[1], "frequency"))
{
- new_frequency = atoi(argv[2]);
-
- f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed", "w");
- if (!f)
+ if(sys_cpu_setall("scaling_setspeed", argv[2]) == 0)
{
fprintf(stderr, "Unable to open frequency interface for writing.\n");
return 1;
}
- fprintf(f, "%d\n", new_frequency);
- fclose(f);
return 0;
}
else if (!strcmp(argv[1], "governor"))
{
- f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "w");
- if (!f)
+ if(sys_cpu_setall("scaling_governor", argv[2]) == 0)
{
fprintf(stderr, "Unable to open governor interface for writing.\n");
return 1;
}
- fprintf(f, "%s\n", argv[2]);
- fclose(f);
return 0;
}
@@ -88,3 +80,23 @@ main(int argc, char *argv[])
seteuid(-1);
}
+
+int sys_cpu_setall(const char *control, const char *value)
+{
+ int num = 0;
+ char filename[4096];
+ FILE *f;
+
+ while(1){
+ snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpufreq/%s", num, control);
+ f = fopen(filename, "w");
+
+ if(!f){
+ return(num);
+ }
+ fprintf(f, "%s\n", value);
+ fclose(f);
+ num++;
+ }
+ return -1;
+}