6 // FIXME: backlight should be tied per zone but this implementation is just
7 // a signleton right now as thats 99% of use cases. but api supports
8 // doing more. for now make it work in the singleton
14 static double bl_val = 1.0;
15 static double bl_animval = 1.0;
16 static E_Backlight_Mode bl_mode = E_BACKLIGHT_MODE_NORMAL;
17 static int sysmode = MODE_NONE;
18 static Ecore_Animator *bl_anim = NULL;
20 static Ecore_Event_Handler *_e_backlight_handler_config_mode = NULL;
21 static Ecore_Event_Handler *_e_backlight_handler_border_fullscreen = NULL;
22 static Ecore_Event_Handler *_e_backlight_handler_border_unfullscreen = NULL;
23 static Ecore_Event_Handler *_e_backlight_handler_border_remove = NULL;
24 static Ecore_Event_Handler *_e_backlight_handler_border_iconify = NULL;
25 static Ecore_Event_Handler *_e_backlight_handler_border_uniconify = NULL;
26 static Ecore_Event_Handler *_e_backlight_handler_border_desk_set = NULL;
27 static Ecore_Event_Handler *_e_backlight_handler_desk_show = NULL;
29 static Ecore_Timer *_e_backlight_timer = NULL;
31 static void _e_backlight_update(E_Zone *zone);
32 static void _e_backlight_set(E_Zone *zone, double val);
33 static Eina_Bool _bl_anim(void *data, double pos);
34 static Eina_Bool bl_avail = EINA_FALSE;
35 static Eina_Bool _e_backlight_handler(void *d, int type, void *ev);
36 static Eina_Bool _e_backlight_timer_cb(void *d);
38 static const char *bl_sysval = NULL;
39 static Ecore_Event_Handler *bl_sys_exit_handler = NULL;
40 static Ecore_Exe *bl_sys_set_exe = NULL;
41 static Eina_Bool bl_sys_pending_set = EINA_FALSE;
42 static Eina_Bool bl_sys_set_exe_ready = EINA_TRUE;
44 static void _bl_sys_find(void);
45 static void _bl_sys_level_get(void);
46 static Eina_Bool _e_bl_cb_exit(void *data __UNUSED__, int type __UNUSED__, void *event);
47 static void _bl_sys_level_set(double val);
51 e_backlight_init(void)
56 // why did someone do this? this makes it ONLY work if xrandr has bl support.
58 // bl_avail = ecore_x_randr_output_backlight_available();
61 _e_backlight_handler_config_mode = ecore_event_handler_add
62 (E_EVENT_CONFIG_MODE_CHANGED, _e_backlight_handler, NULL);
64 _e_backlight_handler_border_fullscreen = ecore_event_handler_add
65 (E_EVENT_BORDER_FULLSCREEN, _e_backlight_handler, NULL);
67 _e_backlight_handler_border_unfullscreen = ecore_event_handler_add
68 (E_EVENT_BORDER_UNFULLSCREEN, _e_backlight_handler, NULL);
70 _e_backlight_handler_border_remove = ecore_event_handler_add
71 (E_EVENT_BORDER_REMOVE, _e_backlight_handler, NULL);
73 _e_backlight_handler_border_iconify = ecore_event_handler_add
74 (E_EVENT_BORDER_ICONIFY, _e_backlight_handler, NULL);
76 _e_backlight_handler_border_uniconify = ecore_event_handler_add
77 (E_EVENT_BORDER_UNICONIFY, _e_backlight_handler, NULL);
79 _e_backlight_handler_border_desk_set = ecore_event_handler_add
80 (E_EVENT_BORDER_DESK_SET, _e_backlight_handler, NULL);
82 _e_backlight_handler_desk_show = ecore_event_handler_add
83 (E_EVENT_DESK_SHOW, _e_backlight_handler, NULL);
88 if (!getenv("E_RESTART"))
90 e_backlight_level_set(NULL, 0.0, 0.0);
91 e_backlight_level_set(NULL, e_config->backlight.normal, 1.0);
98 e_backlight_shutdown(void)
100 if (bl_anim) ecore_animator_del(bl_anim);
103 if (bl_sysval) eina_stringshare_del(bl_sysval);
105 if (bl_sys_exit_handler) ecore_event_handler_del(bl_sys_exit_handler);
106 bl_sys_exit_handler = NULL;
107 bl_sys_set_exe = NULL;
108 bl_sys_pending_set = EINA_FALSE;
111 if (_e_backlight_handler_config_mode)
113 ecore_event_handler_del(_e_backlight_handler_config_mode);
114 _e_backlight_handler_config_mode = NULL;
117 if (_e_backlight_handler_border_fullscreen)
119 ecore_event_handler_del(_e_backlight_handler_border_fullscreen);
120 _e_backlight_handler_border_fullscreen = NULL;
123 if (_e_backlight_handler_border_unfullscreen)
125 ecore_event_handler_del(_e_backlight_handler_border_unfullscreen);
126 _e_backlight_handler_border_unfullscreen = NULL;
129 if (_e_backlight_handler_border_remove)
131 ecore_event_handler_del(_e_backlight_handler_border_remove);
132 _e_backlight_handler_border_remove = NULL;
135 if (_e_backlight_handler_border_iconify)
137 ecore_event_handler_del(_e_backlight_handler_border_iconify);
138 _e_backlight_handler_border_iconify = NULL;
141 if (_e_backlight_handler_border_uniconify)
143 ecore_event_handler_del(_e_backlight_handler_border_uniconify);
144 _e_backlight_handler_border_uniconify = NULL;
147 if (_e_backlight_handler_border_desk_set)
149 ecore_event_handler_del(_e_backlight_handler_border_desk_set);
150 _e_backlight_handler_border_desk_set = NULL;
153 if (_e_backlight_handler_desk_show)
155 ecore_event_handler_del(_e_backlight_handler_desk_show);
156 _e_backlight_handler_desk_show = NULL;
162 e_backlight_exists(void)
164 if (sysmode == MODE_NONE) return EINA_FALSE;
169 e_backlight_update(void)
171 Eina_List *m, *c, *z;
176 if (bl_avail == EINA_FALSE) return;
178 EINA_LIST_FOREACH(e_manager_list(), m, man)
180 EINA_LIST_FOREACH(man->containers, c, con)
182 EINA_LIST_FOREACH(con->zones, z, zone)
184 _e_backlight_update(zone);
189 /* idle dimming disabled: clear timer */
190 if (!e_config->backlight.idle_dim)
192 if (_e_backlight_timer)
193 ecore_timer_del(_e_backlight_timer);
194 _e_backlight_timer = NULL;
197 /* dimming enabled, timer active: update interval and reset */
198 if (_e_backlight_timer)
200 if (e_config->backlight.timer != ecore_timer_interval_get(_e_backlight_timer))
201 ecore_timer_interval_set(_e_backlight_timer, e_config->backlight.timer);
202 ecore_timer_reset(_e_backlight_timer);
205 /* dimming enabled, timer inactive: */
207 /* timer is 0 seconds: return */
208 if (!e_config->backlight.timer) return;
209 /* current mode is dimmed: undim */
210 if (bl_mode == E_BACKLIGHT_MODE_DIM)
211 e_backlight_mode_set(NULL, E_BACKLIGHT_MODE_NORMAL);
212 _e_backlight_timer = ecore_timer_add(e_config->backlight.timer, _e_backlight_timer_cb, NULL);
216 e_backlight_level_set(E_Zone *zone, double val, double tim)
219 // zone == NULL == everything
220 // set backlight associated with zone to val over period of tim
221 // if tim == 0.0 - then do it instantnly, if time == -1 use some default
223 if (val < 0.0) val = 0.0;
224 else if (val > 1.0) val = 1.0;
225 if (val == bl_val) return;
226 if (!zone) zone = e_util_zone_current_get(e_manager_current_get());
229 if (bl_mode != E_BACKLIGHT_MODE_NORMAL) return;
230 if (tim < 0.0) tim = e_config->backlight.transition;
235 ecore_animator_del(bl_anim);
238 _e_backlight_set(zone, val);
241 if (bl_anim) ecore_animator_del(bl_anim);
242 bl_anim = ecore_animator_timeline_add(tim, _bl_anim, zone);
247 e_backlight_level_get(E_Zone *zone __UNUSED__)
249 // zone == NULL == everything
254 e_backlight_mode_set(E_Zone *zone, E_Backlight_Mode mode)
256 // zone == NULL == everything
257 if (bl_mode == mode) return;
259 if (bl_mode == E_BACKLIGHT_MODE_NORMAL)
260 e_backlight_level_set(zone, bl_val, -1.0);
261 else if (bl_mode == E_BACKLIGHT_MODE_OFF)
262 e_backlight_level_set(zone, 0.0, -1.0);
263 else if (bl_mode == E_BACKLIGHT_MODE_DIM)
264 e_backlight_level_set(zone, e_config->backlight.dim, -1.0);
265 else if (bl_mode == E_BACKLIGHT_MODE_MAX)
266 e_backlight_level_set(zone, 1.0, -1.0);
269 EAPI E_Backlight_Mode
270 e_backlight_mode_get(E_Zone *zone __UNUSED__)
272 // zone == NULL == everything
276 /* local subsystem functions */
279 _e_backlight_handler(void *d __UNUSED__, int type __UNUSED__, void *ev __UNUSED__)
281 e_backlight_update();
282 return ECORE_CALLBACK_PASS_ON;
286 _e_backlight_timer_cb(void *d __UNUSED__)
288 e_backlight_mode_set(NULL, E_BACKLIGHT_MODE_DIM);
289 _e_backlight_timer = NULL;
294 _e_backlight_update(E_Zone *zone)
298 Ecore_X_Randr_Output *out;
301 root = zone->container->manager->root;
303 out = ecore_x_randr_window_outputs_get(root, &num);
304 if ((out) && (num > 0) && (ecore_x_randr_output_backlight_available()))
305 x_bl = ecore_x_randr_output_backlight_level_get(root, out[0]);
310 sysmode = MODE_RANDR;
326 _e_backlight_set(E_Zone *zone, double val)
328 if (sysmode == MODE_RANDR)
331 Ecore_X_Randr_Output *out;
334 root = zone->container->manager->root;
335 out = ecore_x_randr_window_outputs_get(root, &num);
336 if ((out) && (num > 0))
338 ecore_x_randr_output_backlight_level_set(root, out[0], val);
343 else if (sysmode == MODE_SYS)
347 _bl_sys_level_set(val);
354 _bl_anim(void *data, double pos)
359 // FIXME: if zone is deleted while anim going... bad things.
360 pos = ecore_animator_pos_map(pos, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
361 v = (bl_animval * (1.0 - pos)) + (bl_val *pos);
362 _e_backlight_set(zone, v);
378 devs = eeze_udev_find_by_filter("backlight", NULL, NULL);
381 /* FIXME: need to make this more precise so we don't set keyboard LEDs or something */
382 devs = eeze_udev_find_by_filter("leds", NULL, NULL);
385 if (eina_list_count(devs) > 1)
387 const char *s = NULL;
389 Eina_Bool use = EINA_FALSE;
391 /* prefer backlights of type "firmware" where available */
392 EINA_LIST_FOREACH(devs, l, f)
394 s = eeze_udev_syspath_get_sysattr(f, "type");
395 use = (s && (!strcmp(s, "firmware")));
396 eina_stringshare_del(s);
399 eina_stringshare_del(bl_sysval);
401 EINA_LIST_FREE(devs, f)
402 eina_stringshare_del(f);
406 EINA_LIST_FREE(devs, f)
408 eina_stringshare_replace(&bl_sysval, NULL);
414 _bl_sys_level_get(void)
419 str = eeze_udev_syspath_get_sysattr(bl_sysval, "max_brightness");
423 eina_stringshare_del(str);
424 if (maxval <= 0) maxval = 255;
425 str = eeze_udev_syspath_get_sysattr(bl_sysval, "brightness");
429 eina_stringshare_del(str);
430 if ((val >= 0) && (val <= maxval))
431 bl_val = (double)val / (double)maxval;
432 // printf("GET: %i/%i (%1.3f)\n", val, maxval, bl_val);
436 _e_bl_cb_ext_delay(void *data __UNUSED__)
438 bl_sys_set_exe_ready = EINA_TRUE;
439 if (bl_sys_pending_set)
441 bl_sys_pending_set = EINA_FALSE;
442 _bl_sys_level_set(bl_val);
448 _e_bl_cb_exit(void *data __UNUSED__, int type __UNUSED__, void *event)
450 Ecore_Exe_Event_Del *ev;
453 if (ev->exe == bl_sys_set_exe)
455 bl_sys_set_exe_ready = EINA_FALSE;
456 bl_sys_set_exe = NULL;
457 ecore_timer_add(0.1, _e_bl_cb_ext_delay, NULL);
459 return ECORE_CALLBACK_RENEW;
463 _bl_sys_level_set(double val)
467 if (!bl_sys_exit_handler)
468 bl_sys_exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
469 _e_bl_cb_exit, NULL);
470 if ((bl_sys_set_exe) || (!bl_sys_set_exe_ready))
472 bl_sys_pending_set = EINA_TRUE;
475 // printf("SET: %1.3f\n", val);
476 snprintf(buf, sizeof(buf),
477 "%s/enlightenment/utils/enlightenment_backlight %i",
478 e_prefix_lib_get(), (int)(val * 1000.0));
479 bl_sys_set_exe = ecore_exe_run(buf, NULL);