diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 21cadf276..23984b9bd 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -29,7 +29,8 @@ internal_bin_PROGRAMS = \ enlightenment_fm_op \ enlightenment_init \ enlightenment_sys \ -enlightenment_thumb +enlightenment_thumb \ +enlightenment_backlight ENLIGHTENMENTHEADERS = \ e_about.h \ @@ -361,6 +362,11 @@ e_sys_main.c enlightenment_sys_LDADD = @E_SYS_LIBS@ +enlightenment_backlight_SOURCES = \ +e_backlight_main.c + +enlightenment_backlight_LDADD = + enlightenment_init_SOURCES = \ e_init_main.c \ e_xinerama.c @@ -373,6 +379,7 @@ enlightenment_init_LDADD = @E_INIT_LIBS@ setuid_root_mode = a=rx,u+xs install-data-hook: @chmod $(setuid_root_mode) $(DESTDIR)$(libdir)/enlightenment/utils/enlightenment_sys$(EXEEXT) || true + @chmod $(setuid_root_mode) $(DESTDIR)$(libdir)/enlightenment/utils/enlightenment_backlight$(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 4759c5299..50bed8ebb 100644 --- a/src/bin/e_actions.c +++ b/src/bin/e_actions.c @@ -2644,20 +2644,20 @@ ACT_FN_GO_ACPI(undim_screen, __UNUSED__) e_backlight_mode_set(zone, E_BACKLIGHT_MODE_NORMAL); } -ACT_FN_GO_ACPI(backlight_set, ) +ACT_FN_GO(backlight_set, ) { E_Zone *zone = _e_actions_zone_get(obj); - double v = atof(params); + int v = atoi(params); e_backlight_mode_set(zone, E_BACKLIGHT_MODE_NORMAL); - e_backlight_level_set(zone, v, -1.0); + e_backlight_level_set(zone, ((double)v / 100.0), -1.0); } -ACT_FN_GO_ACPI(backlight_adjust, ) +ACT_FN_GO(backlight_adjust, ) { E_Zone *zone = _e_actions_zone_get(obj); - double v = atof(params); + int v = atoi(params); e_backlight_mode_set(zone, E_BACKLIGHT_MODE_NORMAL); - e_backlight_level_set(zone, e_backlight_level_get(zone) + v, -1.0); + e_backlight_level_set(zone, e_backlight_level_get(zone) + ((double)v / 100.0), -1.0); } /* local subsystem globals */ @@ -2956,22 +2956,22 @@ e_actions_init(void) ACT_GO_ACPI(undim_screen); e_action_predef_name_set(N_("Screen"), N_("Undim"), "undim_screen", NULL, NULL, 0); - ACT_GO_ACPI(backlight_set); + ACT_GO(backlight_set); e_action_predef_name_set(N_("Screen"), N_("Backlight Set"), "backlight_set", - NULL, "syntax: brightness(0.0 - 1.0), example: 0.5", 1); + NULL, "syntax: brightness(0 - 100), example: 50", 1); e_action_predef_name_set(N_("Screen"), N_("Backlight Min"), "backlight_set", - "0.0", NULL, 0); + "0", NULL, 0); e_action_predef_name_set(N_("Screen"), N_("Backlight Mid"), "backlight_set", - "0.5", NULL, 0); + "50", NULL, 0); e_action_predef_name_set(N_("Screen"), N_("Backlight Max"), "backlight_set", - "1.0", NULL, 0); - ACT_GO_ACPI(backlight_adjust); + "100", NULL, 0); + ACT_GO(backlight_adjust); e_action_predef_name_set(N_("Screen"), N_("Backlight Adjust"), "backlight_adjust", - NULL, "syntax: brightness(-1.0 - 1.0), example: -0.2", 1); + NULL, "syntax: brightness(-100 - 100), example: -20", 1); e_action_predef_name_set(N_("Screen"), N_("Backlight Up"), "backlight_adjust", - "0.1", NULL, 0); + "10", NULL, 0); e_action_predef_name_set(N_("Screen"), N_("Backlight Down"), "backlight_adjust", - "-0.1", NULL, 0); + "-10", NULL, 0); /* window_move_to_center */ ACT_GO(window_move_to_center); diff --git a/src/bin/e_backlight.c b/src/bin/e_backlight.c index 160153124..9b5289533 100644 --- a/src/bin/e_backlight.c +++ b/src/bin/e_backlight.c @@ -1,40 +1,31 @@ #include "e.h" -#include -#ifdef HAVE_HAL -#include -#endif // FIXME: backlight should be tied per zone but this implementation is just // a signleton right now as thats 99% of use cases. but api supports // doing more. for now make it work in the singleton -// FIXME: backlight should have config values for: -// 1. normal mode (eg on login/ start of e) -// 2. dim level (eg 0.5) -// 3. anim slide time (eg 0.5) - -// FIXME: tried using hal backlight stuff... doesn't work -//#define HAL_BL 1 - #define MODE_RANDR 0 -#define MODE_HAL 1 +#define MODE_SYS 1 static double bl_val = 1.0; static double bl_animval = 1.0; static E_Backlight_Mode bl_mode = E_BACKLIGHT_MODE_NORMAL; static int sysmode = MODE_RANDR; static Ecore_Animator *bl_anim = NULL; - -#ifdef HAL_BL -static E_DBus_Connection *_hal_conn = NULL; -static const char *_hal_bl_dev = NULL; -static const char *_hal_bl_iface = NULL; -static int _hal_nlevels = 1; -#endif +static const char *bl_sysval = NULL; +static Ecore_Event_Handler *bl_sys_exit_handler = NULL; +static Ecore_Exe *bl_sys_set_exe = NULL; +static Eina_Bool bl_sys_pending_set = EINA_FALSE; static void _e_backlight_update(E_Zone *zone); static void _e_backlight_set(E_Zone *zone, double val); static Eina_Bool _bl_anim(void *data, double pos); +static char *_bl_read_file(const char *file); +static int _bl_sys_num_get(const char *file); +static void _bl_sys_find(void); +static void _bl_sys_level_get(void); +static Eina_Bool _e_bl_cb_exit(void *data __UNUSED__, int type __UNUSED__, void *event); +static void _bl_sys_level_set(double val); EINTERN int e_backlight_init(void) @@ -48,29 +39,14 @@ e_backlight_init(void) EINTERN int e_backlight_shutdown(void) { -#ifdef HAL_BL - if (_hal_conn) - { - e_dbus_connection_close(_hal_conn); - _hal_conn = NULL; -#ifdef HAVE_HAL - e_hal_shutdown(); -#endif - e_dbus_shutdown(); - if (_hal_bl_dev) - { - eina_stringshare_del(_hal_bl_dev); - _hal_bl_dev = NULL; - } - if (_hal_bl_iface) - { - eina_stringshare_del(_hal_bl_iface); - _hal_bl_iface = NULL; - } - } -#endif if (bl_anim) ecore_animator_del(bl_anim); bl_anim = NULL; + if (bl_sysval) eina_stringshare_del(bl_sysval); + bl_sysval = NULL; + if (bl_sys_exit_handler) ecore_event_handler_del(bl_sys_exit_handler); + bl_sys_exit_handler = NULL; + bl_sys_set_exe = NULL; + bl_sys_pending_set = EINA_FALSE; return 1; } @@ -81,7 +57,7 @@ e_backlight_update(void) E_Manager *man; E_Container *con; E_Zone *zone; - + EINA_LIST_FOREACH(e_manager_list(), m, man) { EINA_LIST_FOREACH(man->containers, c, con) @@ -102,15 +78,14 @@ e_backlight_level_set(E_Zone *zone, double val, double tim) // set backlight associated with zone to val over period of tim // if tim == 0.0 - then do it instantnly, if time == -1 use some default // transition time - if (!zone) e_backlight_update(); - else _e_backlight_update(zone); + if (val < 0.0) val = 0.0; + else if (val > 1.0) val = 1.0; if (val == bl_val) return; if (!zone) zone = e_util_zone_current_get(e_manager_current_get()); bl_now = bl_val; bl_val = val; if (bl_mode != E_BACKLIGHT_MODE_NORMAL) return; if (tim < 0.0) tim = e_config->backlight.transition; - // FIXME: save bl level for normal if (tim == 0.0) { if (bl_anim) @@ -130,8 +105,6 @@ EAPI double e_backlight_level_get(E_Zone *zone) { // zone == NULL == everything - if (!zone) e_backlight_update(); - else _e_backlight_update(zone); return bl_val; } @@ -161,139 +134,6 @@ e_backlight_mode_get(E_Zone *zone __UNUSED__) } /* local subsystem functions */ -#ifdef HAL_BL -#ifdef HAVE_HAL -void -_e_backlight_hal_val_reply(void *data __UNUSED__, - DBusMessage *reply, - DBusError *error) -{ - dbus_uint32_t val; - - if (dbus_error_is_set(error)) - { - printf("Error: %s - %s\n", error->name, error->message); - return; - } - dbus_message_get_args(reply, error, DBUS_TYPE_UINT32, - &val, DBUS_TYPE_INVALID); - printf("Received: %i\n", val); -} - -static void -_e_backlight_hal_val_get(void) -{ - DBusMessage *msg; - - if (!_hal_bl_dev) return; - msg = dbus_message_new_method_call - ("org.freedesktop.Hal", - _hal_bl_dev, - _hal_bl_iface, - "GetBrightness" - ); - e_dbus_message_send(_hal_conn, msg, _e_backlight_hal_val_reply, -1, NULL); - dbus_message_unref(msg); -} - -static void -_e_backlight_hal_val_set(double val) -{ - DBusMessage *msg; - dbus_uint32_t ival = 0; - - if (!_hal_bl_dev) return; - msg = dbus_message_new_method_call - ("org.freedesktop.Hal", - _hal_bl_dev, - _hal_bl_iface, - "SetBrightness" - ); - ival = val * (_hal_nlevels - 1); - printf("hal set %i\n", ival); - dbus_message_append_args(msg, DBUS_TYPE_UINT32, &ival, DBUS_TYPE_INVALID); - dbus_message_set_no_reply(msg, EINA_TRUE); - e_dbus_message_send(_hal_conn, msg, NULL, -1, NULL); - dbus_message_unref(msg); -} - -static void -_e_backlight_prop(void *data __UNUSED__, - void *reply_data, - DBusError *error) -{ - E_Hal_Properties *ret = reply_data; - int err; - int nlevels; - const Eina_List *sl; - - if (!ret) goto error; - - if (dbus_error_is_set(error)) - { - dbus_error_free(error); - goto error; - } - nlevels = e_hal_property_bool_get(ret, "laptop_panel.num_levels", &err); - if (err) goto error; - _hal_nlevels = nlevels; - printf("nlevels: %i\n", nlevels); - - sl = e_hal_property_strlist_get(ret, "info.interfaces", &err); - if (err) goto error; - if (sl) - { - if (_hal_bl_iface) eina_stringshare_del(_hal_bl_iface); - _hal_bl_iface = eina_stringshare_add(sl->data); - printf("%s\n", _hal_bl_iface); - } - _e_backlight_hal_val_get(); - return; -error: - if (_hal_bl_dev) - { - eina_stringshare_del(_hal_bl_dev); - _hal_bl_dev = NULL; - } - if (_hal_bl_iface) - { - eina_stringshare_del(_hal_bl_iface); - _hal_bl_iface = NULL; - } -} - -static void -_e_backlight_panel_found(void *user_data __UNUSED__, - void *reply_data, - DBusError *error) -{ - E_Hal_Manager_Find_Device_By_Capability_Return *ret = reply_data; - Eina_List *l; - char *device; - - if (!ret || !ret->strings) return; - - if (dbus_error_is_set(error)) - { - dbus_error_free(error); - return; - } - if (!_hal_bl_dev) - { - EINA_LIST_FOREACH(ret->strings, l, device) - { - printf("BL+: %s\n", device); - if (!_hal_bl_dev) _hal_bl_dev = eina_stringshare_add(device); - } - } - if (_hal_bl_dev) - { - e_hal_device_get_all_properties(_hal_conn, _hal_bl_dev, - _e_backlight_prop, NULL); - } -} -#endif -#endif static void _e_backlight_update(E_Zone *zone) @@ -316,24 +156,12 @@ _e_backlight_update(E_Zone *zone) } else { -#ifdef HAL_BL -#ifdef HAVE_HAL - sysmode = MODE_HAL; - if (!_hal_conn) - { - e_dbus_init(); - e_hal_init(); - _hal_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM); - } - if (_hal_conn) + _bl_sys_find(); + if (bl_sysval) { - if (!_hal_bl_dev) - e_hal_manager_find_device_by_capability - (_hal_conn, "laptop_panel", - _e_backlight_panel_found, NULL); + sysmode = MODE_SYS; + _bl_sys_level_get(); } -#endif -#endif } } @@ -354,13 +182,12 @@ _e_backlight_set(E_Zone *zone, double val) } if (out) free(out); } - else if (sysmode == MODE_HAL) + else if (sysmode == MODE_SYS) { -#ifdef HAL_BL -#ifdef HAVE_HAL - _e_backlight_hal_val_set(val); -#endif -#endif + if (bl_sysval) + { + _bl_sys_level_set(val); + } } } @@ -381,3 +208,143 @@ _bl_anim(void *data, double pos) } return EINA_TRUE; } + +static char * +_bl_read_file(const char *file) +{ + FILE *f = fopen(file, "r"); + size_t len; + char buf[4096], *p; + if (!f) return NULL; + len = fread(buf, 1, sizeof(buf) - 1, f); + if (len == 0) + { + fclose(f); + return NULL; + } + buf[len] = 0; + for (p = buf; *p; p++) + { + if (p[0] == '\n') p[0] = 0; + } + fclose(f); + return strdup(buf); +} + +static int +_bl_sys_num_get(const char *file) +{ + char *max; + int maxval = -1; + + max = _bl_read_file(file); + if (max) + { + maxval = atoi(max); + free(max); + } + return maxval; +} + +static void +_bl_sys_find(void) +{ + int maxval = 0; + const char *tryfile; + + if (bl_sysval) return; + tryfile = "/sys/devices/virtual/backlight/acpi_video0/max_brightness"; + maxval = _bl_sys_num_get(tryfile); + if (maxval > 0) + { + bl_sysval = eina_stringshare_add(tryfile); + return; + } + else + { + Eina_List *files; + const char *dir = "/sys/devices/virtual/backlight"; + + files = ecore_file_ls(dir); + if (files) + { + char *file; + + EINA_LIST_FREE(files, file) + { + if (!bl_sysval) + { + char buf[PATH_MAX]; + + snprintf(buf, sizeof(buf), + "%s/%s/max_brightness", dir, file); + maxval = _bl_sys_num_get(buf); + if (maxval > 0) + bl_sysval = eina_stringshare_add(buf); + } + free(file); + } + } + } +} + +static void +_bl_sys_level_get(void) +{ + const char *maxfile = bl_sysval; + char *valfile, *p; + int maxval, val; + + if (!bl_sysval) return; + valfile = strdup(maxfile); + p = strrchr(valfile, '/'); + if (p) + { + p[1] = 0; + strcat(p, "brightness"); + } + maxval = _bl_sys_num_get(maxfile); + if (maxval > 0) + { + val = _bl_sys_num_get(valfile); + if ((val >= 0) && (val <= maxval)) + bl_val = (double)val / (double)maxval; + } +} + +static Eina_Bool +_e_bl_cb_exit(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Exe_Event_Del *ev; + + ev = event; + if (ev->exe == bl_sys_set_exe) + { + bl_sys_set_exe = NULL; + if (bl_sys_pending_set) + { + bl_sys_pending_set = EINA_FALSE; + _bl_sys_level_set(bl_val); + } + } + return ECORE_CALLBACK_RENEW; +} + +static void +_bl_sys_level_set(double val) +{ + char buf[PATH_MAX]; + + if (!bl_sys_exit_handler) + bl_sys_exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, + _e_bl_cb_exit, NULL); + if (bl_sys_set_exe) + { + bl_sys_pending_set = EINA_TRUE; + return; + } + snprintf(buf, sizeof(buf), + "%s/enlightenment/utils/enlightenment_backlight %i", + e_prefix_lib_get(), (int)(val * 1000.0)); + bl_sys_set_exe = ecore_exe_run(buf, NULL); +} diff --git a/src/bin/e_backlight_main.c b/src/bin/e_backlight_main.c new file mode 100644 index 000000000..97b303ef6 --- /dev/null +++ b/src/bin/e_backlight_main.c @@ -0,0 +1,158 @@ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +/* local subsystem functions */ +static char * +read_file(const char *file) +{ + FILE *f = fopen(file, "r"); + size_t len; + char buf[4096], *p; + if (!f) return NULL; + len = fread(buf, 1, sizeof(buf) - 1, f); + if (len == 0) + { + fclose(f); + return NULL; + } + buf[len] = 0; + for (p = buf; *p; p++) + { + if (p[0] == '\n') p[0] = 0; + } + fclose(f); + return strdup(buf); +} + +static int +write_file(const char *file, int val) +{ + char buf[256]; + int fd = open(file, O_WRONLY); + if (fd < 0) + { + perror("open"); + return -1; + } + snprintf(buf, sizeof(buf), "%i", val); + if (write(fd, buf, strlen(buf)) != (int)strlen(buf)) + { + perror("write"); + close(fd); + return -1; + } + close(fd); + return 0; +} + +/* local subsystem globals */ + +/* externally accessible functions */ +int +main(int argc, + char **argv) +{ + int i; + int level; + char *maxstr; + int maxlevel = 0, curlevel; + char file[4096] = ""; + + 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 == 2) + { + level = atoi(argv[1]); + } + else + { + exit(1); + } + + if (setuid(0) != 0) + { + printf("ERROR: UNABLE TO ASSUME ROOT PRIVILEGES\n"); + exit(5); + } + if (setgid(0) != 0) + { + printf("ERROR: UNABLE TO ASSUME ROOT GROUP PRIVILEGES\n"); + exit(7); + } + + maxstr = read_file("/sys/devices/virtual/backlight/acpi_video0/max_brightness_max"); + if (maxstr) + { + maxlevel = atoi(maxstr); + if (maxlevel <= 0) + { + free(maxstr); + maxstr = NULL; + } + else + { + snprintf(file, sizeof(file), "/sys/devices/virtual/backlight/acpi_video0/brightness"); + free(maxstr); + maxstr = NULL; + } + } + if (maxlevel <= 0) + { + DIR *dirp = opendir("/sys/devices/virtual/backlight"); + struct dirent *dp; + + if (!dirp) return 1; + while ((dp = readdir(dirp))) + { + if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, ".."))) + { + char buf[4096]; + + snprintf(buf, sizeof(buf), "/sys/devices/virtual/backlight/%s/max_brightness", dp->d_name); + maxstr = read_file(buf); + if (maxstr) + { + maxlevel = atoi(maxstr); + if (maxlevel <= 0) + { + free(maxstr); + maxstr = NULL; + } + else + { + snprintf(file, sizeof(file), "/sys/devices/virtual/backlight/%s/brightness", dp->d_name); + free(maxstr); + maxstr = NULL; + break; + } + } + } + } + closedir(dirp); + } + if (maxlevel > 0) + { + curlevel = (maxlevel * level) / 1000; + return write_file(file, curlevel); + } + return -1; +}