From b8112af500b7006f7c17785c4f38fe83b7888702 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Mon, 27 Dec 2004 10:49:46 +0000 Subject: [PATCH] battery modules now... works... in theory. i have to test it on a real laptop... SVN revision: 12600 --- data/themes/default.edc | 119 +++++++++- data/themes/images/Makefile.am | 3 +- data/themes/images/e17_battery_ac.png | Bin 0 -> 2587 bytes src/modules/battery/e_mod_main.c | 327 ++++++++++++++++++++++++++ src/modules/battery/e_mod_main.h | 12 +- 5 files changed, 457 insertions(+), 4 deletions(-) create mode 100644 data/themes/images/e17_battery_ac.png diff --git a/data/themes/default.edc b/data/themes/default.edc index 832b2b1eb..77cca10d6 100644 --- a/data/themes/default.edc +++ b/data/themes/default.edc @@ -268,6 +268,7 @@ images { image: "e17_battery_080.png" COMP; image: "e17_battery_090.png" COMP; image: "e17_battery_100.png" COMP; + image: "e17_battery_ac.png" COMP; } collections { @@ -5204,9 +5205,19 @@ collections { group { name: "modules/battery/main"; max: 128 128; + script { + public message(Msg_Type:type, id, ...) { + if ((type == MSG_FLOAT) && (id == 1)) { + new Float:val; + val = getfarg(2); + set_state(PART:"battery", "default", val); + } + } + } parts { part { name: "battery"; + clip_to: "fade_clip"; description { state: "default" 0.0; aspect: 0.669291339 0.669291339; @@ -5297,6 +5308,7 @@ collections { name: "reading"; type: TEXT; effect: SOFT_SHADOW; + clip_to: "fade_clip"; description { state: "default" 0.0; align: 1.0 0.0; @@ -5305,7 +5317,7 @@ collections { to_x: "battery"; } rel2 { - relative: 1.0 1.0; + relative: 1.0 0.0; } color: 255 255 255 255; color3: 0 0 0 32; @@ -5314,10 +5326,113 @@ collections { font: "Edje Vera"; size: 7; min: 1 1; - align: 0.0 0.0; + align: 1.0 0.0; } } } + part { + name: "time"; + type: TEXT; + effect: SOFT_SHADOW; + clip_to: "fade_clip"; + description { + state: "default" 0.0; + align: 1.0 0.0; + rel1 { + relative: 1.0 1.0; + to_x: "battery"; + to_y: "reading"; + } + rel2 { + relative: 1.0 1.0; + to_y: "reading"; + } + color: 255 255 255 255; + color3: 0 0 0 32; + text { + text: "00:00"; + font: "Edje Vera"; + size: 7; + min: 1 1; + align: 1.0 0.0; + } + } + } + part { + name: "ac"; + clip_to: "fade_clip"; + description { + state: "default" 0.0; + aspect: 0.975609756 0.975609756; + align: 1.0 1.0; + max: 40 41; + visible: 0; + rel1 { + relative: 0.5 0.5; + } + rel2 { + relative: 1.0 1.0; + } + image { + normal: "e17_battery_ac.png"; + } + } + description { + state: "active" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { + name: "fade_clip"; + type: RECT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 255 255 255 255; + } + description { + state: "faded" 0.0; + color: 255 255 255 128; + } + } + } + programs { + program { + name: "charge"; + signal: "charge"; + source: ""; + action: STATE_SET "default" 0.0; + target: "fade_clip"; + } + program { + name: "charge2"; + signal: "charge"; + source: ""; + action: STATE_SET "active" 0.0; + target: "ac"; + } + program { + name: "discharge"; + signal: "discharge"; + source: ""; + action: STATE_SET "default" 0.0; + target: "fade_clip"; + } + program { + name: "discharge2"; + signal: "discharge"; + source: ""; + action: STATE_SET "default" 0.0; + target: "ac"; + } + program { + name: "unknown"; + signal: "unknown"; + source: ""; + action: STATE_SET "faded" 0.0; + target: "fade_clip"; + } } } } diff --git a/data/themes/images/Makefile.am b/data/themes/images/Makefile.am index a8d3fdea6..ec18d966d 100644 --- a/data/themes/images/Makefile.am +++ b/data/themes/images/Makefile.am @@ -242,4 +242,5 @@ e17_battery_060.png \ e17_battery_070.png \ e17_battery_080.png \ e17_battery_090.png \ -e17_battery_100.png +e17_battery_100.png \ +e17_battery_ac.png diff --git a/data/themes/images/e17_battery_ac.png b/data/themes/images/e17_battery_ac.png new file mode 100644 index 0000000000000000000000000000000000000000..2f498a7ee9eba55fdca70510e2231b8d04ed9502 GIT binary patch literal 2587 zcmV+$3gq>PP)WFU8GbZ8({Xk{QrNlj4iWF>9@011CdL_t(o!?l@hY*bYq z#(($DTPZDLX-A+;TPV^RsNe>uS%j?y7g8Znzm$YxVwya1F#tY|6q`>6crVTj*bqI?&|315Jg2rLV{F)#lV+0Zrn)rsjaOQz#o8Rz#PhDMIauMJ* zV8&rb-CZ`_1-l= zX+=Mf1N>(9?%hJuG;!(DCGq&;_f?XX@+g#lXOT*s^7d@cDenzCNE%6ciLhfnNi~zzVssy9Q~d8NSDJ=V$Wz4!HEz zTW?{v+bJk0pslSf`LeLEkf)!1+5!9?s0G#-vfFBMwUQ3tR8LROU1yZ+J0&^N=5RRj zpMU;&-hcmnDk>^Cb?VeD8``yN7u&XN%i6wu`%A#<_N3(>dgvh(Md8gi-{kP&!%qMeGFdWY!dUN= zG%0CDmZx+yQz0kMl399o&z?P^udh#h@WBV-!3Q4{r%#_2v$M0}>#x5SyLayvt*x!1 ztgKAu$%kd)tdNPLQ_yW7tw1YqxT>n^h{xlhyu3VR+X# z>q|>ZUDegqyzs&coH%iU^XJbqF)=}Tc{$N&6oEe(0U-n%H*RFZh7HWj%y8w(6~6iAn_-|wf-(ZsLEa)RloVp&CF%BDL#DO@4S?4$ zPL&>T$e1bt8usqp`?JlPH&a?#$|H|FLL?HQySqCXzaM`1;Tho1a^4$22$+_kqe;Me zh+#DW^aA@NPubFMd_&p-bhfU&VLVzF3qP+ndhvMy&xU^at1 zOUZ@mj}WN31@&OpxAOP*qu3`RL0pznooCQnF;xqD9$>L}E!i9$%~|iX$s4i>|J&)dvqAJk-+CvIF=X zFd`Qi1FqH9*52p$`@5FTyX>ffefHsTFmU?L^^;rV3XVJ{^h&xzUz4AnP*f@(^S9TZ|U#v zw{&-RtDT*l>fqp@(%ajs_Vx8y=jZ3u?CfmTu3bxSZ*Sq~=;##CE9aiLeEG6_aB#3_ z{rdIf0V7HSlj>-vx_aj`pU}6bw`dIiL73|+BQBuZW|sR zwsm)R+b>+WU>g`1u#b+8+Ei7w#$qvx%jHrYd+f2y+}vEXprC*kUwo0awzgjZ<3NY3 z7N^dgJGaK|cCS2o^e96^L#V2X)oRVuG|g$C9IMIQ2|zIdTv1U`asQ!1hayg=(>gpn zZ1eeij>g7D`?+)H9HXP70vMEm9S4>NgTbAus;=C#XV0RHj11+er=H@y_ug~X)YKf8 zRcRQ=16Ce5aDc^&7jx~}HKwMfh{xkGnH1I(q@AoNIzaofWy_og4;~E9&CS`y#>T8; zV`CY|j~}1Cc=4hDx`82CGmRx`u&=MLE))vo#bU9HNF>7k{rlOmV~4e+rDf}9pMAC! z;Mr%NW!tuGba!|2)mL8;3srnIs5kQqq@2}Dcyp>Am`7Yr?0P% z@$qpC!b435&X^=hb#=96>C&Z^P$*=%aN&Zbxw%;dx@0Z37!EjQvEc9N>6tru^5mM_ z++2&(>9hs{0j8&?iN#{f&dw4D1nBDOqOq}&&dyGP!QdCbza>e}EkM{w3u+@HBVo7O zZJnB$vU$B;yNr)%>CS{f2I+NI-}Rg%>8lM54F@h>yqI5HTx`q9$ssc{6Q|QjEEdD- z^>XIS8G^y!e}P6hzev-#EsNiI=bebnX0r+*to{A{HVIA_0=jZhO=4A*F=PkYLZQ%i zO-)Tt0A;cq>hsUbit(i+=!jvXdYdnT7;V z<)VrK@SKe8X;~sez>IvRb7I1pLgz(f2aCaS@f5LV3~ngoS>v#YF002ovPDHLkV1g*!4bT7p literal 0 HcmV?d00001 diff --git a/src/modules/battery/e_mod_main.c b/src/modules/battery/e_mod_main.c index 20038b53a..2a883b8d2 100644 --- a/src/modules/battery/e_mod_main.c +++ b/src/modules/battery/e_mod_main.c @@ -19,6 +19,10 @@ static void _battery_cb_face_down(void *data, Evas *e, Evas_Object *obj, voi static void _battery_cb_face_up(void *data, Evas *e, Evas_Object *obj, void *event_info); static void _battery_cb_face_move(void *data, Evas *e, Evas_Object *obj, void *event_info); static int _battery_cb_event_container_resize(void *data, int type, void *event); +static int _battery_cb_check(void *data); +static int _battery_linux_acpi_check(Battery_Face *ef); +static int _battery_linux_apm_check(Battery_Face *ef); +static void _battery_level_set(Battery_Face *ef, double level); /* public module routines. all modules must have these */ void * @@ -222,6 +226,14 @@ _battery_face_init(Battery_Face *ef) _battery_face_reconfigure(ef); + ef->battery_check_mode = CHECK_NONE; + ef->battery_prev_drain = 1; + ef->battery_prev_ac = -1; + ef->battery_prev_battery = -1; + ef->battery_check_timer = ecore_timer_add(5.0, _battery_cb_check, ef); + + _battery_cb_check(ef); + evas_event_thaw(ef->evas); } @@ -347,3 +359,318 @@ _battery_cb_event_container_resize(void *data, int type, void *event) _battery_face_reconfigure(ef); return 1; } + +static int +_battery_cb_check(void *data) +{ + Battery_Face *ef; + int ret = 0; + + ef = data; + if (ef->battery_check_mode == 0) + { + if (e_file_is_dir("/proc/acpi")) + ef->battery_check_mode = CHECK_LINUX_ACPI; + else if (e_file_is_dir("/proc/apm")) + ef->battery_check_mode = CHECK_LINUX_APM; + } + switch (ef->battery_check_mode) + { + case CHECK_LINUX_ACPI: + ret = _battery_linux_acpi_check(ef); + break; + case CHECK_LINUX_APM: + ret = _battery_linux_acpi_check(ef); + break; + default: + break; + } + if (!ret) + { + if (ef->battery_prev_battery != -2) + { + edje_object_signal_emit(ef->bat_object, "unknown", ""); + ef->battery_prev_battery = -2; + } + edje_object_part_text_set(ef->bat_object, "reading", "NO INFO"); + edje_object_part_text_set(ef->bat_object, "time", "--:--"); + ef->battery_check_mode = CHECK_NONE; + _battery_level_set(ef, (double)(rand() & 0xff) / 255.0); + } + return 1; +} + +static int +_battery_linux_acpi_check(Battery_Face *ef) +{ + Evas_List *bats; + char buf[4096], buf2[4096]; + + int bat_max = 0; + int bat_filled = 0; + int bat_level = 0; + int bat_drain = 1; + + int bat_val = 0; + + char current_status[256]; + int discharging = 0; + int charging = 0; + int battery = 0; + + int design_cap_unknown = 0; + int last_full_unknown = 0; + int rate_unknown = 0; + int level_unknown = 0; + + int hours, minutes; + + /* Read some information on first run. */ + bats = e_file_ls("/proc/acpi/battery"); + if (!bats) return 0; + while (bats) + { + FILE *f; + char *name; + + name = bats->data; + if ((!strcmp(name, ".")) || (!strcmp(name, ".."))) + { + bats = evas_list_remove_list(bats, bats); + free(name); + continue; + } + snprintf(buf, sizeof(buf), "/proc/acpi/battery/%s/info", name); + f = fopen(buf, "r"); + if (f) + { + int design_cap = 0; + int last_full = 0; + + fgets(buf2, sizeof(buf2), f); buf[sizeof(buf2) - 1] = 0; + fgets(buf2, sizeof(buf2), f); buf[sizeof(buf2) - 1] = 0; + sscanf(buf2, "%*[^:]: %250s %*s", buf); + if (!strcmp(buf, "unknown")) design_cap_unknown = 1; + else sscanf(buf2, "%*[^:]: %i %*s", &design_cap); + fgets(buf2, sizeof(buf2), f); buf[sizeof(buf2) - 1] = 0; + sscanf(buf2, "%*[^:]: %250s %*s", buf); + if (!strcmp(buf, "unknown")) last_full_unknown = 1; + else sscanf(buf2, "%*[^:]: %i %*s", &last_full); + fclose(f); + bat_max += design_cap; + bat_filled += last_full; + } + snprintf(buf, sizeof(buf), "/proc/acpi/battery/%s/state", name); + f = fopen(buf, "r"); + if (f) + { + char present[256]; + char capacity_state[256]; + char charging_state[256]; + int rate = 1; + int level = 0; + + fgets(buf2, sizeof(buf2), f); buf[sizeof(buf2) - 1] = 0; + sscanf(buf2, "%*[^:]: %250s", present); + fgets(buf2, sizeof(buf2), f); buf[sizeof(buf2) - 1] = 0; + sscanf(buf2, "%*[^:]: %250s", capacity_state); + fgets(buf2, sizeof(buf2), f); buf[sizeof(buf2) - 1] = 0; + sscanf(buf2, "%*[^:]: %250s", charging_state); + fgets(buf2, sizeof(buf2), f); buf[sizeof(buf2) - 1] = 0; + sscanf(buf2, "%*[^:]: %250s %*s", buf); + if (!strcmp(buf, "unknown")) rate_unknown = 1; + else sscanf(buf2, "%*[^:]: %i %*s", &rate); + fgets(buf2, sizeof(buf2), f); buf[sizeof(buf2) - 1] = 0; + sscanf(buf2, "%*[^:]: %250s %*s", buf); + if (!strcmp(buf, "unknown")) level_unknown = 1; + else sscanf(buf2, "%*[^:]: %i %*s", &level); + fclose(f); + if (!strcmp(present, "yes")) battery++; + if (!strcmp(charging_state, "discharging")) discharging++; + if (!strcmp(charging_state, "charging")) charging++; + bat_drain += rate; + bat_level += level; + } + bats = evas_list_remove_list(bats, bats); + free(name); + } + if (ef->battery_prev_drain < 1) ef->battery_prev_drain = 1; + if (bat_drain < 1) bat_drain = ef->battery_prev_drain; + ef->battery_prev_drain = bat_drain; + + if (bat_filled > 0) bat_val = (100 * bat_level) / bat_filled; + else bat_val = 100; + + if (discharging) minutes = (60 * bat_level) / bat_drain; + else + { + if (bat_filled > 0) + minutes = (60 * (bat_filled - bat_level)) / bat_drain; + else + minutes = 0; + } + hours = minutes / 60; + minutes -= (hours * 60); + + if ((charging) || (discharging)) + { + ef->battery_prev_battery = 1; + if ((charging ) && (ef->battery_prev_ac == 0)) + { + edje_object_signal_emit(ef->bat_object, "charge", ""); + ef->battery_prev_ac = 1; + } + else if ((discharging) && (ef->battery_prev_ac == 1)) + { + edje_object_signal_emit(ef->bat_object, "discharge", ""); + ef->battery_prev_ac = 0; + } + if (level_unknown) + { + edje_object_part_text_set(ef->bat_object, "reading", "BAD DIRVER"); + edje_object_part_text_set(ef->bat_object, "time", "--:--"); + _battery_level_set(ef, 0.0); + } + else if (rate_unknown) + { + snprintf(buf, sizeof(buf), "%i%%", bat_val); + edje_object_part_text_set(ef->bat_object, "reading", buf); + edje_object_part_text_set(ef->bat_object, "time", "--:--"); + _battery_level_set(ef, (double)bat_val / 100.0); + } + else + { + snprintf(buf, sizeof(buf), "%i%%", bat_val); + edje_object_part_text_set(ef->bat_object, "reading", buf); + snprintf(buf, sizeof(buf), "%i:%02i", hours, minutes); + edje_object_part_text_set(ef->bat_object, "time", buf); + _battery_level_set(ef, (double)bat_val / 100.0); + } + } + else if (!battery) + { + if (ef->battery_prev_battery != 0) + { + edje_object_signal_emit(ef->bat_object, "unknown", ""); + ef->battery_prev_battery = 0; + } + edje_object_part_text_set(ef->bat_object, "reading", "NO BAT"); + edje_object_part_text_set(ef->bat_object, "time", "--:--"); + _battery_level_set(ef, 1.0); + } + else + { + if (ef->battery_prev_battery == 0) + { + edje_object_signal_emit(ef->bat_object, "charge", ""); + ef->battery_prev_battery = 1; + } + edje_object_part_text_set(ef->bat_object, "reading", "FULL"); + edje_object_part_text_set(ef->bat_object, "time", "--:--"); + _battery_level_set(ef, 1.0); + } + return 1; +} + +static int +_battery_linux_apm_check(Battery_Face *ef) +{ + FILE *f; + char s[256], s1[32], s2[32], s3[32], buf[4096]; + int apm_flags, ac_stat, bat_stat, bat_flags, bat_val, time_val; + int hours, minutes; + + f = fopen("/proc/apm", "r"); + if (!f) return 0; + + fgets(s, sizeof(s), f); s[sizeof(s) - 1] = 0; + if (sscanf(s, "%*s %*s %x %x %x %x %s %s %s", + &apm_flags, &ac_stat, &bat_stat, &bat_flags, s1, s2, s3) != 7) + { + fclose(f); + return 0; + } + s1[strlen(s1) - 1] = 0; + bat_val = atoi(s1); + if (!strcmp(s3, "sec")) time_val = atoi(s2); + else if (!strcmp(s3, "min")) time_val = atoi(s2) * 60; + fclose(f); + + if ((bat_flags != 0xff) && (bat_flags & 0x80)) + { + if (ef->battery_prev_battery != 0) + { + edje_object_signal_emit(ef->bat_object, "unknown", ""); + ef->battery_prev_battery = 0; + } + edje_object_part_text_set(ef->bat_object, "reading", "NO BAT"); + edje_object_part_text_set(ef->bat_object, "time", "--:--"); + _battery_level_set(ef, 1.0); + } + else + { + ef->battery_prev_battery = 1; + if (bat_val > 0) + { + snprintf(buf, sizeof(buf), "%i%%", bat_val); + edje_object_part_text_set(ef->bat_object, "reading", buf); + _battery_level_set(ef, (double)bat_val / 100.0); + } + else + { + switch( bat_stat ) + { + case 0: + edje_object_part_text_set(ef->bat_object, "reading", "High"); + _battery_level_set(ef, 1.0); + break; + case 1: + edje_object_part_text_set(ef->bat_object, "reading", "Low"); + _battery_level_set(ef, 0.50); + break; + case 2: + edje_object_part_text_set(ef->bat_object, "reading", "Danger"); + _battery_level_set(ef, 0.25); + break; + case 3: + edje_object_part_text_set(ef->bat_object, "reading", "Charge"); + _battery_level_set(ef, 1.0); + break; + } + } + } + + if (ac_stat == 1) + { + if ((ac_stat == 1) && (ef->battery_prev_ac == 0)) + { + edje_object_signal_emit(ef->bat_object, "charge", ""); + ef->battery_prev_ac = 1; + } + else if ((ac_stat == 0) && (ef->battery_prev_ac == 1)) + { + edje_object_signal_emit(ef->bat_object, "discharge", ""); + ef->battery_prev_ac = 0; + } + edje_object_part_text_set(ef->bat_object, "time", "--:--"); + } + else + { + hours = time_val / 3600; + minutes = (time_val / 60) % 60; + snprintf(buf, sizeof(buf), "%i:%02i", hours, minutes); + edje_object_part_text_set(ef->bat_object, "time", buf); + } + return 1; +} + +static void +_battery_level_set(Battery_Face *ef, double level) +{ + Edje_Message_Float msg; + + if (level < 0.0) level = 0.0; + else if (level > 1.0) level = 1.0; + msg.val = level; + edje_object_message_send(ef->bat_object, EDJE_MESSAGE_FLOAT, 1, &msg); +} diff --git a/src/modules/battery/e_mod_main.h b/src/modules/battery/e_mod_main.h index e575b2506..8a4fce46d 100644 --- a/src/modules/battery/e_mod_main.h +++ b/src/modules/battery/e_mod_main.h @@ -5,6 +5,10 @@ typedef struct _Config Config; typedef struct _Battery Battery; typedef struct _Battery_Face Battery_Face; +#define CHECK_NONE 0 +#define CHECK_LINUX_ACPI 1 +#define CHECK_LINUX_APM 2 + struct _Config { int width; @@ -35,7 +39,13 @@ struct _Battery_Face unsigned char resize : 1; Evas_Coord xx, yy; Evas_Coord fx, fy, fw; - + + int battery_check_mode; + Ecore_Timer *battery_check_timer; + int battery_prev_drain; + int battery_prev_ac; + int battery_prev_battery; + Ecore_Event_Handler *ev_handler_container_resize; };