diff --git a/edc/all.edc b/edc/all.edc index 0af1dcd..5d256ce 100644 --- a/edc/all.edc +++ b/edc/all.edc @@ -1,3 +1,4 @@ #include "macros.edc" #include "bryce.edc" #include "bryce_editor.edc" +#include "wireless.edc" diff --git a/edc/bt_base.png b/edc/bt_base.png new file mode 100644 index 0000000..a60b8d9 Binary files /dev/null and b/edc/bt_base.png differ diff --git a/edc/bt_sig_1.png b/edc/bt_sig_1.png new file mode 100644 index 0000000..b1f3a51 Binary files /dev/null and b/edc/bt_sig_1.png differ diff --git a/edc/bt_sig_2.png b/edc/bt_sig_2.png new file mode 100644 index 0000000..aa23c33 Binary files /dev/null and b/edc/bt_sig_2.png differ diff --git a/edc/eth.png b/edc/eth.png new file mode 100644 index 0000000..14cb9c1 Binary files /dev/null and b/edc/eth.png differ diff --git a/edc/exlclam.png b/edc/exlclam.png new file mode 100644 index 0000000..d4958c2 Binary files /dev/null and b/edc/exlclam.png differ diff --git a/edc/glow_lock_double.png b/edc/glow_lock_double.png new file mode 100644 index 0000000..87794bb Binary files /dev/null and b/edc/glow_lock_double.png differ diff --git a/edc/glow_lock_locked.png b/edc/glow_lock_locked.png new file mode 100644 index 0000000..693924e Binary files /dev/null and b/edc/glow_lock_locked.png differ diff --git a/edc/glow_lock_unlocked.png b/edc/glow_lock_unlocked.png new file mode 100644 index 0000000..6e13429 Binary files /dev/null and b/edc/glow_lock_unlocked.png differ diff --git a/edc/hole_tiny.png b/edc/hole_tiny.png new file mode 100644 index 0000000..49f7648 Binary files /dev/null and b/edc/hole_tiny.png differ diff --git a/edc/led_tiny_green.png b/edc/led_tiny_green.png new file mode 100644 index 0000000..a66ffd2 Binary files /dev/null and b/edc/led_tiny_green.png differ diff --git a/edc/led_tiny_orange.png b/edc/led_tiny_orange.png new file mode 100644 index 0000000..0bcb574 Binary files /dev/null and b/edc/led_tiny_orange.png differ diff --git a/edc/slot_horiz_bottom.png b/edc/slot_horiz_bottom.png new file mode 100644 index 0000000..a8c6fdc Binary files /dev/null and b/edc/slot_horiz_bottom.png differ diff --git a/edc/slot_horiz_top.png b/edc/slot_horiz_top.png new file mode 100644 index 0000000..e0dba5c Binary files /dev/null and b/edc/slot_horiz_top.png differ diff --git a/edc/wifi_base.png b/edc/wifi_base.png new file mode 100644 index 0000000..077b0a3 Binary files /dev/null and b/edc/wifi_base.png differ diff --git a/edc/wifi_sig_1.png b/edc/wifi_sig_1.png new file mode 100644 index 0000000..f7aebf2 Binary files /dev/null and b/edc/wifi_sig_1.png differ diff --git a/edc/wifi_sig_2.png b/edc/wifi_sig_2.png new file mode 100644 index 0000000..a723881 Binary files /dev/null and b/edc/wifi_sig_2.png differ diff --git a/edc/wifi_sig_3.png b/edc/wifi_sig_3.png new file mode 100644 index 0000000..1d40d81 Binary files /dev/null and b/edc/wifi_sig_3.png differ diff --git a/edc/wireless.edc b/edc/wireless.edc new file mode 100644 index 0000000..644c043 --- /dev/null +++ b/edc/wireless.edc @@ -0,0 +1,559 @@ +group { name: "e/modules/wireless/wifi"; nomouse; + images.image: "slot_horiz_top.png" COMP; + images.image: "slot_horiz_bottom.png" COMP; + images.image: "wifi_base.png" COMP; + images.image: "wifi_sig_1.png" COMP; + images.image: "wifi_sig_2.png" COMP; + images.image: "wifi_sig_3.png" COMP; + images.image: "eth.png" COMP; + images.image: "exlclam.png" COMP; + images.image: "hole_tiny.png" COMP; + images.image: "led_tiny_orange.png" COMP; + images.image: "led_tiny_green.png" COMP; + + script { + public message(Msg_Type:type, id, ...) { + if ((type == MSG_INT_SET) && (id == 1)) { + new state = getarg(2), signl = getarg(3); + if (signl <= 14) { + set_state(PART:"wifi_1", "default", 0.0); + set_state(PART:"wifi_2", "default", 0.0); + set_state(PART:"wifi_3", "default", 0.0); + } + else if (signl <= 28) { + set_state(PART:"wifi_1", "partly", 0.0); + set_state(PART:"wifi_2", "default", 0.0); + set_state(PART:"wifi_3", "default", 0.0); + } + else if (signl <= 42) { + set_state(PART:"wifi_1", "visible", 0.0); + set_state(PART:"wifi_2", "default", 0.0); + set_state(PART:"wifi_3", "default", 0.0); + } + else if (signl <= 57) { + set_state(PART:"wifi_1", "visible", 0.0); + set_state(PART:"wifi_2", "partly", 0.0); + set_state(PART:"wifi_3", "default", 0.0); + } + else if (signl <= 71) { + set_state(PART:"wifi_1", "visible", 0.0); + set_state(PART:"wifi_2", "visible", 0.0); + set_state(PART:"wifi_3", "default", 0.0); + } + else if (signl <= 85) { + set_state(PART:"wifi_1", "visible", 0.0); + set_state(PART:"wifi_2", "visible", 0.0); + set_state(PART:"wifi_3", "partly", 0.0); + } + else { + set_state(PART:"wifi_1", "visible", 0.0); + set_state(PART:"wifi_2", "visible", 0.0); + set_state(PART:"wifi_3", "visible", 0.0); + } + if ((state == 1)) { + set_state(PART:"led", "default", 0.0); + run_program(PROGRAM:"connecting"); + return; + } + else if ((state == 2)) { set_state(PART:"led", "connected", 0.0); } + else if ((state == 3)) { set_state(PART:"led", "online", 0.0); } + else { set_state(PART:"led", "default", 0.0); } + } + } + } + parts { + part { name: "slot_bottom"; + description { state: "default" 0.0; + rel1.to: "slot"; + rel2.relative: 1.0 0.5; + rel2.to: "slot"; + min: 0 3; + image.normal: "slot_horiz_bottom.png"; + fixed: 0 1; + } + } +/////////////////////// + part { name: "exclam_base"; + clip_to: "clip_exclam"; + description { state: "default" 0.0; + aspect: (71/144) (71/144); aspect_preference: BOTH; + align: 0.5 1.0; + rel2.relative: 1.0 0.5; + rel2.to_y: "slot"; + image.normal: "exlclam.png"; + } + } +/////////////////////// + part { name: "eth_base"; + clip_to: "clip_eth"; + description { state: "default" 0.0; + aspect: (60/144) (60/144); aspect_preference: BOTH; + align: 0.5 1.0; + rel2.relative: 1.0 0.5; + rel2.to_y: "slot"; + image.normal: "eth.png"; + } + } +/////////////////////// + part { name: "wifi_base"; + clip_to: "clip_wifi"; + description { state: "default" 0.0; + aspect: (160/144) (160/144); aspect_preference: BOTH; + align: 0.5 1.0; + rel2.relative: 1.0 0.5; + rel2.to_y: "slot"; + image.normal: "wifi_base.png"; + } + } + part { name: "wifi_1"; + clip_to: "clip_wifi"; + description { state: "default" 0.0; + rel1.to: "wifi_base"; + rel2.to: "wifi_base"; + image.normal: "wifi_sig_1.png"; + visible: 0; + } + description { state: "partly" 0.0; + inherit: "default" 0.0; + color: 255 255 255 128; + visible: 1; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "wifi_2"; + clip_to: "clip_wifi"; + description { state: "default" 0.0; + rel1.to: "wifi_base"; + rel2.to: "wifi_base"; + image.normal: "wifi_sig_2.png"; + visible: 0; + } + description { state: "partly" 0.0; + inherit: "default" 0.0; + color: 255 255 255 128; + visible: 1; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "wifi_3"; + clip_to: "clip_wifi"; + description { state: "default" 0.0; + rel1.to: "wifi_base"; + rel2.to: "wifi_base"; + image.normal: "wifi_sig_3.png"; + visible: 0; + } + description { state: "partly" 0.0; + inherit: "default" 0.0; + color: 255 255 255 128; + visible: 1; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } +////////////////////////// + part { name: "slot"; + description { state: "default" 0.0; + rel1.offset: 0 -1; + rel1.relative: (21/160) 1.0; + rel2.offset: -1 -1; + rel2.relative: (140/160) 1.0; + align: 0.5 1.0; + min: 0 6; + image.normal: "slot_horiz_top.png"; + fixed: 0 1; + } + } + part { name: "hole"; + description { state: "default" 0.0; + rel1.offset: -4 -4; + rel1.relative: 1.0 1.0; + rel2.offset: -4 -4; + align: 1.0 1.0; + min: 4 4; + max: 4 4; + image.normal: "hole_tiny.png"; + fixed: 1 1; + } + } + part { name: "clip_exclam"; type: RECT; + description { state: "default" 0.0; + visible: 1; + } + description { state: "wifi" 0.0; + visible: 0; + } + description { state: "eth" 0.0; + visible: 0; + } + } + part { name: "clip_wifi"; type: RECT; + description { state: "default" 0.0; + visible: 0; + } + description { state: "wifi" 0.0; + visible: 1; + } + description { state: "eth" 0.0; + visible: 0; + } + } + part { name: "clip_eth"; type: RECT; + description { state: "default" 0.0; + visible: 0; + } + description { state: "wifi" 0.0; + visible: 0; + } + description { state: "eth" 0.0; + visible: 1; + } + } + part { name: "led"; + description { state: "default" 0.0; + rel1.to: "hole"; + rel2.to: "hole"; + min: 10 10; + max: 10 10; + image.normal: "led_tiny_orange.png"; + fixed: 1 1; + visible: 0; + } + description { state: "connected" 0.0; + inherit: "default" 0.0; + image.normal: "led_tiny_orange.png"; + visible: 1; + } + description { state: "online" 0.0; + inherit: "default" 0.0; + image.normal: "led_tiny_green.png"; + visible: 1; + } + } + part { name: "event"; type: RECT; mouse; + description { state: "default" 0.0; + color: 0 0 0 0; + } + } + } + + programs { + program { name: "connecting"; + action: STATE_SET "connected" 0.0; + target: "led"; + in: 0.3 0.0; + after: "connecting2"; + } + program { name: "connecting2"; + action: STATE_SET "default" 0.0; + target: "led"; + in: 0.3 0.0; + after: "connecting"; + } +// program { +// signal: "e,available"; source: "e"; +// } +// program { +// signal: "e,unavailable"; source: "e"; +// } + program { + signal: "e,state,disconnected"; source: "e"; + action: STATE_SET "default" 0.0; + target: "clip_exclam"; + target: "clip_wifi"; + target: "clip_eth"; + } + program { + signal: "e,state,wifi"; source: "e"; + action: STATE_SET "wifi" 0.0; + target: "clip_exclam"; + target: "clip_wifi"; + target: "clip_eth"; + } + program { + signal: "e,state,ethernet"; source: "e"; + action: STATE_SET "eth" 0.0; + target: "clip_exclam"; + target: "clip_wifi"; + target: "clip_eth"; + } + } +} + +group { name: "e/modules/wireless/bluetooth"; nomouse; + images.image: "slot_horiz_top.png" COMP; + images.image: "slot_horiz_bottom.png" COMP; + images.image: "exlclam.png" COMP; + images.image: "hole_tiny.png" COMP; + images.image: "led_tiny_orange.png" COMP; + images.image: "led_tiny_green.png" COMP; + images.image: "bt_base.png" COMP; + images.image: "bt_sig_1.png" COMP; + images.image: "bt_sig_2.png" COMP; + script { + public message(Msg_Type:type, id, ...) { + if ((type == MSG_INT_SET) && (id == 1)) { + new state = getarg(2), signl = getarg(3); + if (signl <= 20) { + set_state(PART:"bt_1", "default", 0.0); + set_state(PART:"bt_2", "default", 0.0); + } + else if (signl <= 40) { + set_state(PART:"bt_1", "partly", 0.0); + set_state(PART:"bt_2", "default", 0.0); + } + else if (signl <= 60) { + set_state(PART:"bt_1", "visible", 0.0); + set_state(PART:"bt_2", "default", 0.0); + } + else if (signl <= 80) { + set_state(PART:"bt_1", "visible", 0.0); + set_state(PART:"bt_2", "partly", 0.0); + } + else { + set_state(PART:"bt_1", "visible", 0.0); + set_state(PART:"bt_2", "visible", 0.0); + } + if ((state == 2)) { + set_state(PART:"led", "default", 0.0); + run_program(PROGRAM:"connecting"); + return; + } + else if ((state == 3)) { return; } + else if ((state == 4)) { set_state(PART:"led", "connected", 0.0); } + else if ((state == 5)) { set_state(PART:"led", "online", 0.0); } + else { set_state(PART:"led", "default", 0.0); } + } + } + } + parts { + part { name: "slot_bottom"; + description { state: "default" 0.0; + rel1.to: "slot"; + rel2.relative: 1.0 0.5; + rel2.to: "slot"; + min: 0 3; + image.normal: "slot_horiz_bottom.png"; + fixed: 0 1; + } + } +/////////////////////// + part { name: "exclam_base"; + clip_to: "clip_exclam"; + description { state: "default" 0.0; + aspect: (71/144) (71/144); aspect_preference: BOTH; + align: 0.5 1.0; + rel2.relative: 1.0 0.5; + rel2.to_y: "slot"; + image.normal: "exlclam.png"; + } + } +/////////////////////// + part { name: "bt_base"; + clip_to: "clip_bt"; + description { state: "default" 0.0; + aspect: (160/144) (160/144); aspect_preference: BOTH; + align: 0.5 1.0; + rel2.relative: 1.0 0.5; + rel2.to_y: "slot"; + image.normal: "bt_base.png"; + } + } + part { name: "bt_1"; + clip_to: "clip_bt"; + description { state: "default" 0.0; + rel1.to: "bt_base"; + rel2.to: "bt_base"; + image.normal: "bt_sig_1.png"; + visible: 0; + } + description { state: "partly" 0.0; + inherit: "default" 0.0; + color: 255 255 255 128; + visible: 1; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "bt_2"; + clip_to: "clip_bt"; + description { state: "default" 0.0; + rel1.to: "bt_base"; + rel2.to: "bt_base"; + image.normal: "bt_sig_2.png"; + visible: 0; + } + description { state: "partly" 0.0; + inherit: "default" 0.0; + color: 255 255 255 128; + visible: 1; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } +/////////////////////// + part { name: "slot"; + description { state: "default" 0.0; + rel1.offset: 0 -1; + rel1.relative: (21/160) 1.0; + rel2.offset: -1 -1; + rel2.relative: (140/160) 1.0; + align: 0.5 1.0; + min: 0 6; + image.normal: "slot_horiz_top.png"; + fixed: 0 1; + } + } + part { name: "hole"; + description { state: "default" 0.0; + rel1.offset: -4 -4; + rel1.relative: 1.0 1.0; + rel2.offset: -4 -4; + align: 1.0 1.0; + min: 4 4; + max: 4 4; + image.normal: "hole_tiny.png"; + fixed: 1 1; + } + } + part { name: "clip_exclam"; type: RECT; + description { state: "default" 0.0; + visible: 1; + } + description { state: "bt" 0.0; + visible: 0; + } + } + part { name: "clip_bt"; type: RECT; + description { state: "default" 0.0; + visible: 0; + } + description { state: "bt" 0.0; + visible: 1; + } + } + part { name: "led"; + description { state: "default" 0.0; + rel1.to: "hole"; + rel2.to: "hole"; + min: 10 10; + max: 10 10; + image.normal: "led_tiny_orange.png"; + fixed: 1 1; + visible: 0; + } + description { state: "connected" 0.0; + inherit: "default" 0.0; + image.normal: "led_tiny_orange.png"; + visible: 1; + } + description { state: "online" 0.0; + inherit: "default" 0.0; + image.normal: "led_tiny_green.png"; + visible: 1; + } + } + part { name: "event"; type: RECT; mouse; + description { state: "default" 0.0; + color: 0 0 0 0; + } + } + } + programs { + program { name: "connecting"; + action: STATE_SET "connected" 0.0; + target: "led"; + in: 0.3 0.0; + after: "connecting2"; + } + program { name: "connecting2"; + action: STATE_SET "default" 0.0; + target: "led"; + in: 0.3 0.0; + after: "connecting"; + } +// program { +// signal: "e,available"; source: "e"; +// } +// program { +// signal: "e,unavailable"; source: "e"; +// } + program { + signal: "e,state,disconnected"; source: "e"; + action: STATE_SET "default" 0.0; + target: "clip_exclam"; + target: "clip_bt"; + } + program { + signal: "e,state,connected"; source: "e"; + action: STATE_SET "wifi" 0.0; + target: "clip_exclam"; + target: "clip_bt"; + } + } +} + +group { name: "e/modules/wireless/end"; + images.image: "glow_lock_locked.png" COMP; + images.image: "glow_lock_unlocked.png" COMP; + images.image: "glow_lock_double.png" COMP; + parts { + part { name: "base"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "glow_lock_locked.png"; + max: 16 16; + aspect: 1.0 1.0; aspect_preference: BOTH; + visible: 0; + } + description { state: "none" 0.0; + inherit: "default" 0.0; + image.normal: "glow_lock_unlocked.png"; + visible: 1; + } + description { state: "wep" 0.0; + inherit: "default" 0.0; + image.normal: "glow_lock_locked.png"; + visible: 1; + } + description { state: "psk" 0.0; + inherit: "default" 0.0; + image.normal: "glow_lock_double.png"; + visible: 1; + } + } + } + programs { + program { + signal: "e,security,off"; source: "e"; + action: STATE_SET "default" 0.0; + target: "base"; + } + program { + signal: "e,security,none"; source: "e"; + action: STATE_SET "none" 0.0; + target: "base"; + } + program { + signal: "e,security,wep"; source: "e"; + action: STATE_SET "wep" 0.0; + target: "base"; + } + program { + signal: "e,security,psk"; source: "e"; + action: STATE_SET "psk" 0.0; + target: "base"; + } + } +} diff --git a/src/gadgets/Makefile.mk b/src/gadgets/Makefile.mk index 4a770a7..c33f65f 100644 --- a/src/gadgets/Makefile.mk +++ b/src/gadgets/Makefile.mk @@ -16,4 +16,8 @@ src/gadgets/clock/clock.h \ src/gadgets/clock/mod.c \ src/gadgets/clock/time.c \ src/gadgets/ibar/ibar.c \ -src/gadgets/ibar/ibar.h +src/gadgets/ibar/ibar.h \ +src/gadgets/wireless/connman.c \ +src/gadgets/wireless/mod.c \ +src/gadgets/wireless/wireless.c \ +src/gadgets/wireless/wireless.h diff --git a/src/gadgets/bryce.c b/src/gadgets/bryce.c index f59cdfc..9dbce4a 100644 --- a/src/gadgets/bryce.c +++ b/src/gadgets/bryce.c @@ -408,17 +408,19 @@ _bryce_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event zone = e_comp_object_util_zone_get(obj); if (zone) { + Eina_Bool vertical = b->orient == Z_GADGET_SITE_ORIENT_VERTICAL; if (b->zone_obstacles) { Eina_List *l; E_Zone_Obstacle *obs; EINA_LIST_FOREACH(b->zone_obstacles, l, obs) - e_zone_obstacle_modify(obs, &(Eina_Rectangle){b->x, b->y, w, h}); + e_zone_obstacle_modify(obs, &(Eina_Rectangle){b->x, b->y, w, h}, vertical); } else b->zone_obstacles = eina_list_append(b->zone_obstacles, - e_zone_obstacle_add(e_comp_object_util_zone_get(obj), NULL, &(Eina_Rectangle){b->x, b->y, w, h})); + e_zone_obstacle_add(e_comp_object_util_zone_get(obj), NULL, + &(Eina_Rectangle){b->x, b->y, w, h}, vertical)); } else { diff --git a/src/gadgets/clock/clock.c b/src/gadgets/clock/clock.c index a4e82e6..a8d1349 100644 --- a/src/gadgets/clock/clock.c +++ b/src/gadgets/clock/clock.c @@ -178,34 +178,7 @@ clock_popup_new(Instance *inst) evas_object_show(oi); elm_object_content_set(inst->popup, inst->o_table); - elm_ctxpopup_hover_parent_set(inst->popup, e_comp->elm); - evas_object_layer_set(inst->popup, evas_object_layer_get(inst->o_clock)); - { - int x, y, w, h; - Z_Gadget_Site_Orient orient; - Z_Gadget_Site_Anchor an; - Evas_Object *site; - - evas_object_geometry_get(inst->o_clock, &x, &y, &w, &h); - site = z_gadget_site_get(inst->o_clock); - orient = z_gadget_site_orient_get(site); - an = z_gadget_site_anchor_get(site); - if (an & Z_GADGET_SITE_ANCHOR_TOP) - y += h; - if (an & Z_GADGET_SITE_ANCHOR_LEFT) - x += w; - if (orient == Z_GADGET_SITE_ORIENT_HORIZONTAL) - { - x += w / 2; - elm_ctxpopup_direction_priority_set(inst->popup, ELM_CTXPOPUP_DIRECTION_UP, ELM_CTXPOPUP_DIRECTION_DOWN, 0, 0); - } - else if (orient == Z_GADGET_SITE_ORIENT_VERTICAL) - { - y += h / 2; - elm_ctxpopup_direction_priority_set(inst->popup, ELM_CTXPOPUP_DIRECTION_RIGHT, ELM_CTXPOPUP_DIRECTION_LEFT, 0, 0); - } - evas_object_move(inst->popup, x, y); - } + z_gadget_util_ctxpopup_place(inst->o_clock, inst->popup); evas_object_show(inst->popup); } diff --git a/src/gadgets/core.c b/src/gadgets/core.c index 05a06ad..983394b 100644 --- a/src/gadgets/core.c +++ b/src/gadgets/core.c @@ -1573,6 +1573,37 @@ z_gadget_util_layout_style_init(Evas_Object *g, Evas_Object *style) return prev; } +Z_API void +z_gadget_util_ctxpopup_place(Evas_Object *g, Evas_Object *ctx) +{ + int x, y, w, h; + Z_Gadget_Config *zgc; + + EINA_SAFETY_ON_NULL_RETURN(g); + zgc = evas_object_data_get(g, "__z_gadget"); + EINA_SAFETY_ON_NULL_RETURN(zgc); + + elm_ctxpopup_hover_parent_set(ctx, e_comp->elm); + evas_object_layer_set(ctx, evas_object_layer_get(g)); + + evas_object_geometry_get(g, &x, &y, &w, &h); + if (zgc->site->anchor & Z_GADGET_SITE_ANCHOR_TOP) + y += h; + if (zgc->site->anchor & Z_GADGET_SITE_ANCHOR_LEFT) + x += w; + if (zgc->site->orient == Z_GADGET_SITE_ORIENT_HORIZONTAL) + { + x += w / 2; + elm_ctxpopup_direction_priority_set(ctx, ELM_CTXPOPUP_DIRECTION_UP, ELM_CTXPOPUP_DIRECTION_DOWN, 0, 0); + } + else if (zgc->site->orient == Z_GADGET_SITE_ORIENT_VERTICAL) + { + y += h / 2; + elm_ctxpopup_direction_priority_set(ctx, ELM_CTXPOPUP_DIRECTION_RIGHT, ELM_CTXPOPUP_DIRECTION_LEFT, 0, 0); + } + evas_object_move(ctx, x, y); +} + /* FIXME */ static void gadget_save(void) diff --git a/src/gadgets/gadget.h b/src/gadgets/gadget.h index abd81c9..12a2842 100644 --- a/src/gadgets/gadget.h +++ b/src/gadgets/gadget.h @@ -60,6 +60,7 @@ Z_API void z_gadget_type_del(const char *type); Z_API Eina_Iterator *z_gadget_type_iterator_get(void); Z_API Evas_Object *z_gadget_util_layout_style_init(Evas_Object *g, Evas_Object *style); +Z_API void z_gadget_util_ctxpopup_place(Evas_Object *g, Evas_Object *ctx); Z_API Evas_Object *z_gadget_editor_add(Evas_Object *parent, Evas_Object *site); diff --git a/src/gadgets/ibar/ibar.c b/src/gadgets/ibar/ibar.c index ed85191..cc27c6e 100644 --- a/src/gadgets/ibar/ibar.c +++ b/src/gadgets/ibar/ibar.c @@ -1,6 +1,13 @@ #include "gadget.h" #include "ibar.h" +#pragma GCC diagnostic ignored "-Wall" +#pragma GCC diagnostic ignored "-Wextra" +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" +#pragma GCC diagnostic ignored "-Wunused-parameter" + typedef struct _Instance Instance; typedef struct _IBar IBar; typedef struct _IBar_Icon IBar_Icon; diff --git a/src/gadgets/wireless/connman.c b/src/gadgets/wireless/connman.c new file mode 100644 index 0000000..96a0db5 --- /dev/null +++ b/src/gadgets/wireless/connman.c @@ -0,0 +1,816 @@ +#include "wireless.h" + +#define CONNMAN_BUS_NAME "net.connman" +#define CONNMAN_MANAGER_IFACE CONNMAN_BUS_NAME ".Manager" +#define CONNMAN_SERVICE_IFACE CONNMAN_BUS_NAME ".Service" +#define CONNMAN_TECHNOLOGY_IFACE CONNMAN_BUS_NAME ".Technology" +#define CONNMAN_TECHNOLOGY_PATH "/net/connman/technology/wifi" +#define CONNMAN_AGENT_IFACE "net.connman.Agent" +#define CONNMAN_AGENT_PATH "/org/enlightenment/connman/agent" + +#undef DBG +#undef INF +#undef WRN +#undef ERR + +#define DBG(...) EINA_LOG_DOM_DBG(_connman_log_dom, __VA_ARGS__) +#define INF(...) EINA_LOG_DOM_INFO(_connman_log_dom, __VA_ARGS__) +#define WRN(...) EINA_LOG_DOM_WARN(_connman_log_dom, __VA_ARGS__) +#define ERR(...) EINA_LOG_DOM_ERR(_connman_log_dom, __VA_ARGS__) + +typedef enum +{ + CONNMAN_STATE_NONE = -1, /* All unknown states */ + CONNMAN_STATE_OFFLINE, + CONNMAN_STATE_IDLE, + CONNMAN_STATE_ASSOCIATION, + CONNMAN_STATE_CONFIGURATION, + CONNMAN_STATE_READY, + CONNMAN_STATE_ONLINE, + CONNMAN_STATE_DISCONNECT, + CONNMAN_STATE_FAILURE, +} Connman_State; + +typedef enum +{ + CONNMAN_SERVICE_TYPE_NONE = -1, /* All non-supported types */ + CONNMAN_SERVICE_TYPE_ETHERNET, + CONNMAN_SERVICE_TYPE_WIFI, + CONNMAN_SERVICE_TYPE_BLUETOOTH, + CONNMAN_SERVICE_TYPE_CELLULAR, +} Connman_Service_Type; + +typedef struct +{ + EINA_INLIST; + const char *path; + Eldbus_Proxy *proxy; + + /* Properties */ + Eina_Stringshare *name; + Eina_Array *security; + Connman_State state; + Connman_Service_Type type; + uint8_t strength; + + /* Private */ + struct + { + Eldbus_Pending *connect; + Eldbus_Pending *disconnect; + Eldbus_Pending *remov; + void *data; + } pending; +} Connman_Service; + +typedef struct Connman_Field +{ + const char *name; + + const char *type; + const char *requirement; + const char *value; + Eina_Array *alternates; +} Connman_Field; + +static int _connman_log_dom = -1; + +static Eldbus_Proxy *proxy_manager; +static Eldbus_Proxy *proxy_technology; + +static Eldbus_Pending *pending_getservices; +static Eldbus_Pending *pending_getproperties_manager; + +static Eina_Inlist *connman_services; +static unsigned int connman_services_count; +static Eldbus_Service_Interface *agent_iface; + +static Connman_State connman_state; +static Eina_Bool connman_offline; +static Eina_Bool connman_powered; + +static void +connman_update_networks(void) +{ + Eina_Array *arr; + Connman_Service *cs; + + arr = eina_array_new(connman_services_count); + EINA_INLIST_FOREACH(connman_services, cs) + eina_array_push(arr, &cs->name); + arr = wireless_wifi_networks_set(arr); + eina_array_free(arr); +} + +static void +connman_update_airplane_mode(Eina_Bool offline) +{ + wireless_airplane_mode_set(offline); +} + +static void +connman_update_state(Connman_State state) +{ + Wifi_State wifi_state; + + if (connman_state == state) return; + connman_state = state; + switch (connman_state) + { + case CONNMAN_STATE_ASSOCIATION: + case CONNMAN_STATE_CONFIGURATION: + wifi_state = WIFI_NETWORK_STATE_CONFIGURING; + break; + case CONNMAN_STATE_READY: + wifi_state = WIFI_NETWORK_STATE_CONNECTED; + break; + case CONNMAN_STATE_ONLINE: + wifi_state = WIFI_NETWORK_STATE_ONLINE; + break; + case CONNMAN_STATE_FAILURE: + wifi_state = WIFI_NETWORK_STATE_FAILURE; + break; + case CONNMAN_STATE_NONE: + case CONNMAN_STATE_OFFLINE: + case CONNMAN_STATE_IDLE: + case CONNMAN_STATE_DISCONNECT: + default: + wifi_state = WIFI_NETWORK_STATE_NONE; + } + wireless_wifi_state_set(wifi_state); +} + +static Connman_State +str_to_state(const char *s) +{ + if (!strcmp(s, "offline")) + return CONNMAN_STATE_OFFLINE; + if (!strcmp(s, "idle")) + return CONNMAN_STATE_IDLE; + if (!strcmp(s, "association")) + return CONNMAN_STATE_ASSOCIATION; + if (!strcmp(s, "configuration")) + return CONNMAN_STATE_CONFIGURATION; + if (!strcmp(s, "ready")) + return CONNMAN_STATE_READY; + if (!strcmp(s, "online")) + return CONNMAN_STATE_ONLINE; + if (!strcmp(s, "disconnect")) + return CONNMAN_STATE_DISCONNECT; + if (!strcmp(s, "failure")) + return CONNMAN_STATE_FAILURE; + + ERR("Unknown state %s", s); + return CONNMAN_STATE_NONE; +} + +static Connman_Service_Type +str_to_type(const char *s) +{ + if (!strcmp(s, "ethernet")) + return CONNMAN_SERVICE_TYPE_ETHERNET; + else if (!strcmp(s, "wifi")) + return CONNMAN_SERVICE_TYPE_WIFI; + else if (!strcmp(s, "bluetooth")) + return CONNMAN_SERVICE_TYPE_BLUETOOTH; + else if (!strcmp(s, "cellular")) + return CONNMAN_SERVICE_TYPE_CELLULAR; + + DBG("Unknown type %s", s); + return CONNMAN_SERVICE_TYPE_NONE; +} + +static void +_connman_service_security_array_clean(Connman_Service *cs) +{ + const char *item; + Eina_Array_Iterator itr; + unsigned int i; + + EINA_ARRAY_ITER_NEXT(cs->security, i, item, itr) + eina_stringshare_del(item); + + eina_array_clean(cs->security); +} + +static void +_connman_service_free(Connman_Service *cs) +{ + Eldbus_Object *obj; + + if (!cs) return; + + if (cs->pending.connect) + { + eldbus_pending_cancel(cs->pending.connect); + free(cs->pending.data); + } + else if (cs->pending.disconnect) + { + eldbus_pending_cancel(cs->pending.disconnect); + free(cs->pending.data); + } + else if (cs->pending.remov) + { + eldbus_pending_cancel(cs->pending.remov); + free(cs->pending.data); + } + + eina_stringshare_del(cs->name); + _connman_service_security_array_clean(cs); + eina_array_free(cs->security); + eina_stringshare_del(cs->path); + obj = eldbus_proxy_object_get(cs->proxy); + eldbus_proxy_unref(cs->proxy); + eldbus_object_unref(obj); + + free(cs); +} + +static void +_connman_service_parse_prop_changed(Connman_Service *cs, const char *prop_name, Eldbus_Message_Iter *value) +{ + DBG("service %p %s prop %s", cs, cs->path, prop_name); + + if (!strcmp(prop_name, "State")) + { + const char *state; + EINA_SAFETY_ON_FALSE_RETURN(eldbus_message_iter_arguments_get(value, + "s", + &state)); + cs->state = str_to_state(state); + DBG("New state: %s %d", state, cs->state); + } + else if (!strcmp(prop_name, "Name")) + { + const char *name; + EINA_SAFETY_ON_FALSE_RETURN(eldbus_message_iter_arguments_get(value, + "s", + &name)); + eina_stringshare_replace(&cs->name, name); + DBG("New name: %s", cs->name); + } + else if (!strcmp(prop_name, "Type")) + { + const char *type; + EINA_SAFETY_ON_FALSE_RETURN(eldbus_message_iter_arguments_get(value, + "s", + &type)); + cs->type = str_to_type(type); + DBG("New type: %s %d", type, cs->type); + } + else if (!strcmp(prop_name, "Strength")) + { + uint8_t strength; + EINA_SAFETY_ON_FALSE_RETURN(eldbus_message_iter_arguments_get(value, + "y", + &strength)); + cs->strength = strength; + DBG("New strength: %d", strength); + } + else if (!strcmp(prop_name, "Security")) + { + const char *s; + + DBG("Old security count: %d", + cs->security ? eina_array_count(cs->security) : 0); + if (cs->security) + _connman_service_security_array_clean(cs); + else + cs->security = eina_array_new(5); + + while (eldbus_message_iter_get_and_next(value, 's', &s)) + { + eina_array_push(cs->security, eina_stringshare_add(s)); + DBG("Push %s", s); + } + DBG("New security count: %d", eina_array_count(cs->security)); + } +} + +static void +_connman_service_prop_dict_changed(Connman_Service *cs, Eldbus_Message_Iter *props) +{ + Eldbus_Message_Iter *dict; + + while (eldbus_message_iter_get_and_next(props, 'e', &dict)) + { + char *name; + Eldbus_Message_Iter *var; + + if (eldbus_message_iter_arguments_get(dict, "sv", &name, &var)) + _connman_service_parse_prop_changed(cs, name, var); + } +} + +static void +_connman_service_property(void *data, const Eldbus_Message *msg) +{ + Connman_Service *cs = data; + Eldbus_Message_Iter *var; + const char *name; + + if (eldbus_message_arguments_get(msg, "sv", &name, &var)) + _connman_service_parse_prop_changed(cs, name, var); +} + +static void +_connman_service_new(const char *path, Eldbus_Message_Iter *props) +{ + Connman_Service *cs; + Eldbus_Object *obj; + + cs = E_NEW(Connman_Service, 1); + cs->path = eina_stringshare_add(path); + + obj = eldbus_object_get(dbus_conn, CONNMAN_BUS_NAME, path); + cs->proxy = eldbus_proxy_get(obj, CONNMAN_SERVICE_IFACE); + eldbus_proxy_signal_handler_add(cs->proxy, "PropertyChanged", + _connman_service_property, cs); + + _connman_service_prop_dict_changed(cs, props); + connman_services = eina_inlist_append(connman_services, EINA_INLIST_GET(cs)); + connman_services_count++; + DBG("Added service: %p %s", cs, path); +} + +static void +_connman_manager_agent_register(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED) +{ + +} + +static void +_connman_technology_parse_wifi_prop_changed(const char *name, Eldbus_Message_Iter *value) +{ + if (!strcmp(name, "Powered")) + { + Eina_Bool powered; + + eldbus_message_iter_arguments_get(value, "b", &powered); + //connman_update_ + } +} + +static void +_connman_technology_event_property(void *data EINA_UNUSED, const Eldbus_Message *msg) +{ + Eldbus_Message_Iter *var; + const char *name; + + if (!eldbus_message_arguments_get(msg, "sv", &name, &var)) + ERR("Could not parse message %p", msg); + else + _connman_technology_parse_wifi_prop_changed(name, var); +} + +static Eina_Bool +_connman_manager_parse_prop_changed(const char *name, Eldbus_Message_Iter *value) +{ + if (!strcmp(name, "State")) + { + const char *state; + + if (!eldbus_message_iter_arguments_get(value, "s", &state)) + return EINA_FALSE; + DBG("New state: %s", state); + connman_update_state(str_to_state(state)); + } + else if (!strcmp(name, "OfflineMode")) + { + Eina_Bool offline; + if (!eldbus_message_iter_arguments_get(value, "b", &offline)) + return EINA_FALSE; + connman_update_airplane_mode(offline); + } + else + return EINA_FALSE; + + return EINA_TRUE; +} + +static void +_connman_manager_getproperties(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED) +{ + Eldbus_Message_Iter *array, *dict; + const char *name, *text; + + pending_getproperties_manager = NULL; + if (eldbus_message_error_get(msg, &name, &text)) + { + ERR("Could not get properties. %s: %s", name, text); + return; + } + + if (!eldbus_message_arguments_get(msg, "a{sv}", &array)) + { + ERR("Error getting arguments."); + return; + } + + while (eldbus_message_iter_get_and_next(array, 'e', &dict)) + { + const char *key; + Eldbus_Message_Iter *var; + + if (eldbus_message_iter_arguments_get(dict, "sv", &key, &var)) + _connman_manager_parse_prop_changed(key, var); + } +} + +static void +_connman_manager_getservices(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED) +{ + Eldbus_Message_Iter *array, *s; + const char *name, *text; + + pending_getservices = NULL; + if (eldbus_message_error_get(msg, &name, &text)) + { + ERR("Could not get services. %s: %s", name, text); + return; + } + + if (!eldbus_message_arguments_get(msg, "a(oa{sv})", &array)) + { + ERR("Error getting array"); + return; + } + + while (eldbus_message_iter_get_and_next(array, 'r', &s)) + { + const char *path; + Eldbus_Message_Iter *inner_array; + + if (!eldbus_message_iter_arguments_get(s, "oa{sv}", &path, &inner_array)) + continue; + + _connman_service_new(path, inner_array); + } + connman_update_networks(); +} + +static void +_connman_manager_event_services(void *data EINA_UNUSED, const Eldbus_Message *msg) +{ + Eldbus_Message_Iter *changed, *removed, *s; + const char *path; + Eina_Bool update = EINA_FALSE; + + if (pending_getservices) return; + + if (!eldbus_message_arguments_get(msg, "a(oa{sv})ao", &changed, &removed)) + { + ERR("Error getting arguments"); + return; + } + + while (eldbus_message_iter_get_and_next(removed, 'o', &path)) + { + Connman_Service *cs; + + EINA_INLIST_FOREACH(connman_services, cs) + { + if (!eina_streq(cs->path, path)) continue; + connman_services = eina_inlist_remove(connman_services, EINA_INLIST_GET(cs)); + DBG("Removed service: %p %s", cs, path); + connman_services_count--; + _connman_service_free(cs); + update = EINA_TRUE; + break; + } + } + + while (eldbus_message_iter_get_and_next(changed, 'r', &s)) + { + Connman_Service *cs; + Eldbus_Message_Iter *array; + Eina_Bool found = EINA_FALSE; + + if (!eldbus_message_iter_arguments_get(s, "oa{sv}", &path, &array)) + continue; + + update = EINA_TRUE; + EINA_INLIST_FOREACH(connman_services, cs) + { + if (!eina_streq(path, cs->path)) continue; + _connman_service_prop_dict_changed(cs, array); + DBG("Changed service: %p %s", cs, path); + break; + } + if (!found) + _connman_service_new(path, array); + } + if (update) + connman_update_networks(); +} + +static void +_connman_manager_event_property(void *data EINA_UNUSED, const Eldbus_Message *msg) +{ + Eldbus_Message_Iter *var; + const char *name; + + if (pending_getproperties_manager) return; + if (!eldbus_message_arguments_get(msg, "sv", &name, &var)) + { + ERR("Could not parse message %p", msg); + return; + } + + _connman_manager_parse_prop_changed(name, var); +} + +static Eldbus_Message * +_connman_agent_release(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) +{ + Eldbus_Message *reply; + + DBG("Agent released"); + + reply = eldbus_message_method_return_new(msg); +#warning FIXME + //if (agent->dialog) + //e_object_del(E_OBJECT(agent->dialog)); + + return reply; +} + +static Eldbus_Message * +_connman_agent_report_error(const Eldbus_Service_Interface *iface EINA_UNUSED, + const Eldbus_Message *msg EINA_UNUSED) +{ +#warning FIXME + return NULL; +} + +static Eldbus_Message * +_connman_agent_request_browser(const Eldbus_Service_Interface *iface EINA_UNUSED, + const Eldbus_Message *msg EINA_UNUSED) +{ +#warning FIXME + return NULL; +} + +static Eina_Bool +_parse_field_value(Connman_Field *field, const char *key, + Eldbus_Message_Iter *value, const char *signature) +{ + if (!strcmp(key, "Type")) + { + EINA_SAFETY_ON_FALSE_RETURN_VAL(signature[0] == 's', EINA_FALSE); + eldbus_message_iter_basic_get(value, &field->type); + return EINA_TRUE; + } + + if (!strcmp(key, "Requirement")) + { + EINA_SAFETY_ON_FALSE_RETURN_VAL(signature[0] == 's', EINA_FALSE); + eldbus_message_iter_basic_get(value, &field->requirement); + return EINA_TRUE; + } + + if (!strcmp(key, "Alternates")) + { + EINA_SAFETY_ON_FALSE_RETURN_VAL(signature[0] == 'a', EINA_FALSE); + /* ignore alternates */ + return EINA_TRUE; + } + + if (!strcmp(key, "Value")) + { + EINA_SAFETY_ON_FALSE_RETURN_VAL(signature[0] == 's', EINA_FALSE); + eldbus_message_iter_basic_get(value, &field->value); + return EINA_TRUE; + } + + DBG("Ignored unknown argument: %s", key); + return EINA_FALSE; +} + +static Eina_Bool +_parse_field(Connman_Field *field, Eldbus_Message_Iter *value, + const char *signature EINA_UNUSED) +{ + Eldbus_Message_Iter *array, *dict; + + eldbus_message_iter_arguments_get(value, "a{sv}", &array); + EINA_SAFETY_ON_NULL_RETURN_VAL(array, EINA_FALSE); + + while (eldbus_message_iter_get_and_next(array, 'e', &dict)) + { + Eldbus_Message_Iter *var; + const char *key; + char *sig2; + + if (!eldbus_message_iter_arguments_get(dict, "sv", &key, &var)) + return EINA_FALSE; + sig2 = eldbus_message_iter_signature_get(var); + if (!sig2) + return EINA_FALSE; + + if (!_parse_field_value(field, key, var, sig2)) + { + free(sig2); + return EINA_FALSE; + } + free(sig2); + } + + return EINA_TRUE; +} + +static Eldbus_Message * +_connman_agent_request_input(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) +{ +#warning FIXME +#if 0 + const Eina_List *l; + Eldbus_Message_Iter *array, *dict; + const char *path; + /* Discard previous requests */ + // if msg is the current agent msg? eek. + if (agent->msg == msg) return NULL; + + if (agent->msg) + eldbus_message_unref(agent->msg); + agent->msg = eldbus_message_ref((Eldbus_Message *)msg); + + EINA_LIST_FOREACH(ctxt->instances, l, inst) + econnman_popup_del(inst); + + if (agent->dialog) + e_object_del(E_OBJECT(agent->dialog)); + agent->dialog = _dialog_new(agent); + EINA_SAFETY_ON_NULL_GOTO(agent->dialog, err); + + if (!eldbus_message_arguments_get(msg, "oa{sv}", &path, &array)) + goto err; + + while (eldbus_message_iter_get_and_next(array, 'e', &dict)) + { + Eldbus_Message_Iter *var; + char *signature; + Connman_Field field = { NULL }; + + if (!eldbus_message_iter_arguments_get(dict, "sv", &field.name, &var)) + goto err; + signature = eldbus_message_iter_signature_get(var); + if (!signature) goto err; + + if (!_parse_field(&field, var, signature)) + { + free(signature); + goto err; + } + free(signature); + + DBG("AGENT Got field:\n" + "\tName: %s\n" + "\tType: %s\n" + "\tRequirement: %s\n" + "\tAlternates: (omit array)\n" + "\tValue: %s", + field.name, field.type, field.requirement, field.value); + + _dialog_field_add(agent, &field); + } + + return NULL; + +err: + eldbus_message_unref((Eldbus_Message *)msg); + agent->msg = NULL; + WRN("Failed to parse msg"); +#endif + return eldbus_message_method_return_new(msg); +} + +static Eldbus_Message * +_connman_agent_cancel(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) +{ + Eldbus_Message *reply = eldbus_message_method_return_new(msg); + + DBG("Agent canceled"); +#warning FIXME + //if (agent->dialog) + //e_object_del(E_OBJECT(agent->dialog)); + + return reply; +} + +static const Eldbus_Method methods[] = { + { "Release", NULL, NULL, _connman_agent_release, 0 }, + { + "ReportError", ELDBUS_ARGS({"o", "service"}, {"s", "error"}), NULL, + _connman_agent_report_error, 0 + }, + //{ + //"ReportPeerError", ELDBUS_ARGS({"o", "peer"}, {"s", "error"}), NULL, + //_connman_agent_report_peer_error, 0 + //}, + { + "RequestBrowser", ELDBUS_ARGS({"o", "service"}, {"s", "url"}), NULL, + _connman_agent_request_browser, 0 + }, + { + "RequestInput", ELDBUS_ARGS({"o", "service"}, {"a{sv}", "fields"}), + ELDBUS_ARGS({"a{sv}", ""}), _connman_agent_request_input, 0 + }, + //{ + //"RequestPeerAuthorization", ELDBUS_ARGS({"o", "peer"}, {"a{sv}", "fields"}), + //ELDBUS_ARGS({"a{sv}", ""}), _connman_agent_request_peer_auth, 0 + //}, + { "Cancel", NULL, NULL, _connman_agent_cancel, 0 }, + { NULL, NULL, NULL, NULL, 0 } +}; + +static const Eldbus_Service_Interface_Desc desc = { + CONNMAN_AGENT_IFACE, methods, NULL, NULL, NULL, NULL +}; + +static void +_connman_start(void) +{ + Eldbus_Object *obj; + + obj = eldbus_object_get(dbus_conn, CONNMAN_BUS_NAME, "/"); + proxy_manager = eldbus_proxy_get(obj, CONNMAN_MANAGER_IFACE); + obj = eldbus_object_get(dbus_conn, CONNMAN_BUS_NAME, CONNMAN_TECHNOLOGY_PATH); + proxy_technology = eldbus_proxy_get(obj, CONNMAN_TECHNOLOGY_IFACE); + + eldbus_proxy_signal_handler_add(proxy_manager, "PropertyChanged", + _connman_manager_event_property, NULL); + eldbus_proxy_signal_handler_add(proxy_manager, "ServicesChanged", + _connman_manager_event_services, NULL); + eldbus_proxy_signal_handler_add(proxy_technology, "PropertyChanged", + _connman_technology_event_property, NULL); + + /* + * PropertyChanged signal in service's path is guaranteed to arrive only + * after ServicesChanged above. So we only add the handler later, in a per + * service manner. + */ + pending_getservices = eldbus_proxy_call(proxy_manager, "GetServices", _connman_manager_getservices, + NULL, -1, ""); + pending_getproperties_manager = eldbus_proxy_call(proxy_manager, "GetProperties", _connman_manager_getproperties, + NULL, -1, ""); + eldbus_proxy_call(proxy_technology, "Scan", NULL, NULL, -1, ""); + + agent_iface = eldbus_service_interface_register(dbus_conn, CONNMAN_AGENT_PATH, &desc); +} + +static void +_connman_end(void) +{ + Eldbus_Object *obj; + + eldbus_proxy_call(proxy_manager, "UnregisterAgent", NULL, NULL, -1, "o", CONNMAN_AGENT_PATH); + + while (connman_services) + { + Connman_Service *cs = EINA_INLIST_CONTAINER_GET(connman_services, + Connman_Service); + connman_services = eina_inlist_remove(connman_services, connman_services); + _connman_service_free(cs); + } + + E_FREE_FUNC(pending_getservices, eldbus_pending_cancel); + E_FREE_FUNC(pending_getproperties_manager, eldbus_pending_cancel); + + obj = eldbus_proxy_object_get(proxy_manager); + E_FREE_FUNC(proxy_manager, eldbus_proxy_unref); + eldbus_object_unref(obj); + obj = eldbus_proxy_object_get(proxy_technology); + E_FREE_FUNC(proxy_technology, eldbus_proxy_unref); + eldbus_object_unref(obj); +} + +static void +_connman_name_owner_changed(void *data EINA_UNUSED, const char *bus EINA_UNUSED, const char *from EINA_UNUSED, const char *to) +{ + if (to[0]) + _connman_start(); + else + _connman_end(); +} + +EINTERN void +connman_init(void) +{ + if (_connman_log_dom > -1) return; + eldbus_name_owner_changed_callback_add(dbus_conn, CONNMAN_BUS_NAME, + _connman_name_owner_changed, + NULL, EINA_TRUE); + _connman_log_dom = eina_log_domain_register("wireless.connman", EINA_COLOR_ORANGE); +} + +EINTERN void +connman_shutdown(void) +{ + E_FREE_FUNC(agent_iface, eldbus_service_object_unregister); + _connman_end(); + eldbus_name_owner_changed_callback_del(dbus_conn, CONNMAN_BUS_NAME, _connman_name_owner_changed, NULL); + eina_log_domain_unregister(_connman_log_dom); + _connman_log_dom = -1; +} diff --git a/src/gadgets/wireless/mod.c b/src/gadgets/wireless/mod.c new file mode 100644 index 0000000..e3687b6 --- /dev/null +++ b/src/gadgets/wireless/mod.c @@ -0,0 +1,16 @@ +#include "e.h" + +EINTERN Eldbus_Connection *dbus_conn; + +EINTERN void +wireless_init(void) +{ + dbus_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM); + connman_init(); +} + +EINTERN void +wireless_shutdown(void) +{ + connman_shutdown(); +} diff --git a/src/gadgets/wireless/wireless.c b/src/gadgets/wireless/wireless.c new file mode 100644 index 0000000..fb33093 --- /dev/null +++ b/src/gadgets/wireless/wireless.c @@ -0,0 +1,237 @@ +#include "wireless.h" + +typedef struct Instance +{ + Evas_Object *box; + Evas_Object *wifi; + Evas_Object *popup; + Evas_Object *popup_list; + Eina_Hash *popup_items; +} Instance; + +static Wifi_State wifi_state; + +static Eina_Array *wifi_networks; +static Wifi_Network *wifi_current; +static Eina_Bool wifi_enabled; +static Eina_List *instances; + +static void +_wifi_icon_init(Evas_Object *icon, Wifi_Network *wn) +{ + Edje_Message_Int_Set *msg; + + msg = alloca(sizeof(Edje_Message_Int_Set) + sizeof(int)); + msg->count = 2; + msg->val[0] = wn->state; + msg->val[1] = wn->strength; + edje_object_message_send(elm_layout_edje_get(icon), EDJE_MESSAGE_INT_SET, 1, msg); +} + +static void +_wifi_state_update(Evas_Object *g) +{ + switch (wifi_state) + { + case WIFI_STATE_NONE: break; + case WIFI_STATE_ETHERNET: + elm_object_signal_emit(g, "e,state,ethernet", "e"); + break; + case WIFI_STATE_WIFI: + elm_object_signal_emit(g, "e,state,wifi", "e"); + break; + } +} + +static void +_wifi_popup_network_click(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + +} + +static void +_wifi_popup_list_populate(Instance *inst) +{ + Eina_Iterator *it; + Wifi_Network *wn; + + it = eina_array_iterator_new(wifi_networks); + EINA_ITERATOR_FOREACH(it, wn) + { + Evas_Object *icon; + Elm_Object_Item *item; + + icon = elm_layout_add(inst->popup_list); + e_theme_edje_object_set(icon, NULL, "e/modules/wireless/wifi"); + _wifi_icon_init(icon, wn); + item = elm_list_item_append(inst->popup_list, wn->name, icon, NULL, _wifi_popup_network_click, inst); + eina_hash_add(inst->popup_items, &wn, item); + } + eina_iterator_free(it); +} + +static void +_wifi_popup_wifi_toggle(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Instance *inst = data; +} + +static void +_wifi_popup_dismissed(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + evas_object_del(obj); +} + +static void +_wifi_popup_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Instance *inst = data; + E_FREE_FUNC(inst->popup_items, eina_hash_free); + inst->popup_list = NULL; + inst->popup = NULL; +} + +static void +_wifi_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Evas_Event_Mouse_Down *ev = event_info; + Instance *inst = data; + Evas_Object *ctx, *box, *list, *toggle; + + if (ev->button != 1) return; + inst->popup_items = eina_hash_pointer_new(NULL); + inst->popup = ctx = elm_ctxpopup_add(e_comp->elm); + elm_object_style_set(inst->popup, "noblock"); + evas_object_smart_callback_add(inst->popup, "dismissed", _wifi_popup_dismissed, inst); + evas_object_event_callback_add(inst->popup, EVAS_CALLBACK_DEL, _wifi_popup_del, inst); + + box = elm_box_add(ctx); + E_EXPAND(box); + E_FILL(box); + + inst->popup_list = list = elm_list_add(ctx); + E_EXPAND(list); + E_FILL(list); + _wifi_popup_list_populate(inst); + elm_list_go(list); + elm_box_pack_end(box, list); + toggle = elm_check_add(ctx); + elm_object_style_set(toggle, "toggle"); + elm_object_text_set(toggle, "Wifi State"); + elm_object_part_text_set(toggle, "on", "On"); + elm_object_part_text_set(toggle, "off", "Off"); + elm_check_state_pointer_set(toggle, &wifi_enabled); + evas_object_smart_callback_add(toggle, "changed", _wifi_popup_wifi_toggle, inst); + elm_box_pack_end(box, toggle); + elm_object_content_set(ctx, box); + z_gadget_util_ctxpopup_place(inst->box, ctx); + evas_object_show(ctx); +} + +static void +wireless_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Instance *inst = data; + + instances = eina_list_remove(instances, inst); + evas_object_del(inst->popup); + free(inst); +} + +static Evas_Object * +wireless_create(Evas_Object *parent, int *id, Z_Gadget_Site_Orient orient) +{ + Evas_Object *g; + Instance *inst; + + inst = E_NEW(Instance, 1); + inst->box = elm_box_add(parent); + elm_box_horizontal_set(inst->box, orient != Z_GADGET_SITE_ORIENT_VERTICAL); + elm_box_homogeneous_set(inst->box, 1); + + inst->wifi = g = elm_layout_add(parent); + E_EXPAND(g); + E_FILL(g); + e_theme_edje_object_set(g, NULL, "e/modules/wireless/wifi"); + elm_box_pack_end(inst->box, g); + + evas_object_size_hint_aspect_set(inst->box, EVAS_ASPECT_CONTROL_BOTH, 1, 1); + evas_object_event_callback_add(inst->box, EVAS_CALLBACK_DEL, wireless_del, inst); + evas_object_event_callback_add(g, EVAS_CALLBACK_MOUSE_DOWN, _wifi_mouse_down, inst); + + if (*id < 0) + elm_object_signal_emit(g, "e,state,wifi", "e"); + else + { + _wifi_state_update(g); + if (wifi_current) + _wifi_icon_init(g, wifi_current); + } + instances = eina_list_append(instances, inst); + + return inst->box; +} + +static void +wireless_init(void) +{ + z_gadget_type_add("Wireless", wireless_create); +} + + +EINTERN void +wireless_wifi_state_set(Wifi_State state) +{ + Eina_List *l; + Instance *inst; + + if (wifi_state == state) return; + + wifi_state = state; + EINA_LIST_FOREACH(instances, l, inst) + _wifi_state_update(inst->wifi); +} + +EINTERN void +wireless_wifi_current_network_set(Wifi_Network *wn) +{ + Eina_List *l; + Instance *inst; + + wifi_current = wn; + EINA_LIST_FOREACH(instances, l, inst) + if (inst->popup) + { + Elm_Object_Item *it; + Evas_Object *icon; + + it = eina_hash_find(inst->popup_items, &wn); + icon = elm_object_item_content_get(it); + _wifi_icon_init(icon, wn); + } +} + +EINTERN Eina_Array * +wireless_wifi_networks_set(Eina_Array *networks) +{ + Eina_Array *prev = wifi_networks; + Eina_List *l; + Instance *inst; + + wifi_networks = networks; + EINA_LIST_FOREACH(instances, l, inst) + if (inst->popup) + { + elm_list_clear(inst->popup_list); + eina_hash_free_buckets(inst->popup_items); + _wifi_popup_list_populate(inst); + } + + return prev; +} + +EINTERN void +wireless_airplane_mode_set(Eina_Bool enabled) +{ + +} diff --git a/src/gadgets/wireless/wireless.h b/src/gadgets/wireless/wireless.h new file mode 100644 index 0000000..2ac701f --- /dev/null +++ b/src/gadgets/wireless/wireless.h @@ -0,0 +1,38 @@ +#ifndef E_WIRELESS_H +# define E_WIRELESS_H + +#include "e.h" +#include "gadget.h" + +typedef enum Wifi_State +{ + WIFI_STATE_NONE, + WIFI_STATE_ETHERNET, + WIFI_STATE_WIFI, +} Wifi_State; + +typedef enum +{ + WIFI_NETWORK_STATE_NONE, + WIFI_NETWORK_STATE_CONFIGURING, + WIFI_NETWORK_STATE_CONNECTED, + WIFI_NETWORK_STATE_ONLINE, + WIFI_NETWORK_STATE_FAILURE, +} Wifi_Network_State; + +typedef struct Wifi_Network +{ + Eina_Stringshare *name; + Eina_Array *security; + Wifi_Network_State state; + uint8_t strength; +} Wifi_Network; + +extern Eldbus_Connection *dbus_conn; + +EINTERN void wireless_wifi_state_set(Wifi_State state); +EINTERN void wireless_wifi_current_network_set(Wifi_Network *wn); +EINTERN Eina_Array *wireless_wifi_networks_set(Eina_Array *networks); +EINTERN void wireless_airplane_mode_set(Eina_Bool enabled); + +#endif