4 #include <Elementary.h>
10 typedef struct _Callscreen
21 static void _call_in_use_update(Callscreen *ctx)
24 OFono_Call *c, *found = NULL;
25 OFono_Call_State found_state = OFONO_CALL_STATE_DISCONNECTED;
26 static const int state_priority[] = {
27 [OFONO_CALL_STATE_DISCONNECTED] = 0,
28 [OFONO_CALL_STATE_ACTIVE] = 6,
29 [OFONO_CALL_STATE_HELD] = 1,
30 [OFONO_CALL_STATE_DIALING] = 5,
31 [OFONO_CALL_STATE_ALERTING] = 4,
32 [OFONO_CALL_STATE_INCOMING] = 3,
33 [OFONO_CALL_STATE_WAITING] = 2
39 EINA_LIST_FOREACH(ctx->calls, n, c) {
40 OFono_Call_State state = ofono_call_state_get(c);
42 DBG("compare %p (%d) to %p (%d)", found, found_state,
44 if (state_priority[state] > state_priority[found_state]) {
51 DBG("No calls usable");
55 DBG("found=%p, state=%d", found, found_state);
60 static void _call_disconnected_done(Callscreen *ctx)
65 _call_in_use_update(ctx);
68 static void _popup_close(void *data, Evas_Object *o __UNUSED__, void *event __UNUSED__)
70 Callscreen *ctx = data;
72 evas_object_del(ctx->disconnected.popup);
73 ctx->disconnected.popup = NULL;
75 eina_stringshare_replace(&ctx->disconnected.number, NULL);
77 _call_disconnected_done(ctx);
80 static void _popup_redial(void *data, Evas_Object *o __UNUSED__, void *event __UNUSED__)
82 Callscreen *ctx = data;
84 ofono_dial(ctx->disconnected.number, NULL, NULL, NULL);
85 _popup_close(ctx, NULL, NULL);
88 static void _call_disconnected_show(Callscreen *ctx, OFono_Call *c,
92 const char *number, *title;
95 DBG("ctx=%p, call=%p, previous=%s, disconnected=%p (%s)",
96 ctx, ctx->in_use, ctx->disconnected.number, c, reason);
98 if ((ctx->in_use) && (ctx->in_use != c))
102 if ((strcmp(reason, "local") == 0) || (strcmp(reason, "remote") == 0)) {
103 _call_disconnected_done(ctx);
107 number = ofono_call_line_id_get(c);
108 if ((!number) || (number[0] == '\0')) {
109 _call_disconnected_done(ctx);
113 if (ctx->disconnected.number)
116 if (strcmp(reason, "network") == 0)
117 title = "Network Disconnected!";
119 title = "Disconnected!";
121 snprintf(msg, sizeof(msg), "Try to redial %s", number);
123 eina_stringshare_replace(&ctx->disconnected.number, number);
125 ctx->disconnected.popup = p = elm_popup_add(ctx->self);
126 evas_object_size_hint_weight_set(p, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
127 elm_object_part_text_set(p, "title,text", title);
128 elm_object_text_set(p, msg);
130 bt = elm_button_add(p);
131 elm_object_text_set(bt, "Close");
132 elm_object_part_content_set(p, "button1", bt);
133 evas_object_smart_callback_add(bt, "clicked", _popup_close, ctx);
135 bt = elm_button_add(p);
136 elm_object_text_set(bt, "Redial");
137 elm_object_part_content_set(p, "button2", bt);
138 evas_object_smart_callback_add(bt, "clicked", _popup_redial, ctx);
143 static void _on_pressed(void *data, Evas_Object *obj __UNUSED__,
144 const char *emission, const char *source __UNUSED__)
146 Callscreen *ctx = data;
147 DBG("ctx=%p, call=%p, signal: %s", ctx, ctx->in_use, emission);
149 EINA_SAFETY_ON_FALSE_RETURN(eina_str_has_prefix(emission, "pressed,"));
150 emission += strlen("pressed,");
154 static void _on_released(void *data, Evas_Object *obj __UNUSED__,
155 const char *emission,
156 const char *source __UNUSED__)
158 Callscreen *ctx = data;
159 DBG("ctx=%p, call=%p, signal: %s", ctx, ctx->in_use, emission);
161 EINA_SAFETY_ON_FALSE_RETURN(eina_str_has_prefix(emission, "released,"));
162 emission += strlen("released,");
166 static void _on_clicked(void *data, Evas_Object *obj __UNUSED__,
167 const char *emission, const char *source __UNUSED__)
169 Callscreen *ctx = data;
170 DBG("ctx=%p, call=%p, signal: %s", ctx, ctx->in_use, emission);
172 EINA_SAFETY_ON_FALSE_RETURN(eina_str_has_prefix(emission, "clicked,"));
173 emission += strlen("clicked,");
175 if (strcmp(emission, "hangup") == 0) {
177 ofono_call_hangup(ctx->in_use, NULL, NULL);
178 } else if (strcmp(emission, "answer") == 0) {
180 ofono_call_answer(ctx->in_use, NULL, NULL);
184 static void _call_added(void *data, OFono_Call *c)
186 Callscreen *ctx = data;
187 DBG("ctx=%p, call=%p, added=%p", ctx, ctx->in_use, c);
188 ctx->calls = eina_list_append(ctx->calls, c);
189 if ((!ctx->in_use) && (ofono_call_state_valid_check(c))) {
195 static void _call_removed(void *data, OFono_Call *c)
197 Callscreen *ctx = data;
198 DBG("ctx=%p, call=%p, removed=%p", ctx, ctx->in_use, c);
199 ctx->calls = eina_list_remove(ctx->calls, c);
200 _call_disconnected_show(ctx, c, "local");
203 static void _call_changed(void *data, OFono_Call *c)
205 Callscreen *ctx = data;
206 OFono_Call_State state;
207 const char *contact, *status, *sig = "hide,answer";
209 DBG("ctx=%p, call=%p, changed=%p", ctx, ctx->in_use, c);
211 _call_in_use_update(ctx);
212 if (ctx->in_use != c)
215 contact = ofono_call_name_get(c);
216 if ((!contact) || (contact[0] == '\0'))
217 contact = ofono_call_line_id_get(c);
219 state = ofono_call_state_get(c);
221 case OFONO_CALL_STATE_DISCONNECTED:
222 status = "Disconnected";
224 case OFONO_CALL_STATE_ACTIVE:
227 case OFONO_CALL_STATE_HELD:
230 case OFONO_CALL_STATE_DIALING:
231 status = "Dialing...";
233 case OFONO_CALL_STATE_ALERTING:
234 status = "Alerting...";
236 case OFONO_CALL_STATE_INCOMING:
237 status = "Incoming...";
240 case OFONO_CALL_STATE_WAITING:
241 status = "Waiting...";
247 elm_object_part_text_set(ctx->self, "elm.text.name", contact);
248 elm_object_part_text_set(ctx->self, "elm.text.status", status);
249 elm_object_signal_emit(ctx->self, sig, "call");
251 if (state == OFONO_CALL_STATE_DISCONNECTED)
252 _call_disconnected_show(ctx, c, "local");
255 static void _call_disconnected(void *data, OFono_Call *c, const char *reason)
257 Callscreen *ctx = data;
258 DBG("ctx=%p, call=%p, disconnected=%p (%s)",
259 ctx, ctx->in_use, c, reason);
261 EINA_SAFETY_ON_NULL_RETURN(reason);
262 _call_disconnected_show(ctx, c, reason);
265 static void _on_del(void *data, Evas *e __UNUSED__,
266 Evas_Object *obj __UNUSED__, void *event __UNUSED__)
268 Callscreen *ctx = data;
270 ofono_call_added_cb_set(NULL, NULL);
271 ofono_call_removed_cb_set(NULL, NULL);
272 ofono_call_changed_cb_set(NULL, NULL);
273 ofono_call_disconnected_cb_set(NULL, NULL);
275 eina_stringshare_del(ctx->disconnected.number);
277 eina_list_free(ctx->calls);
281 Evas_Object *callscreen_add(Evas_Object *parent) {
283 Evas_Object *obj = gui_layout_add(parent, "call");
284 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
286 ctx = calloc(1, sizeof(Callscreen));
289 evas_object_data_set(obj, "callscreen.ctx", ctx);
291 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
293 elm_object_signal_callback_add(obj, "pressed,*", "call",
295 elm_object_signal_callback_add(obj, "released,*", "call",
297 elm_object_signal_callback_add(obj, "clicked,*", "call",
300 elm_object_part_text_set(obj, "elm.text.name", "");
301 elm_object_part_text_set(obj, "elm.text.status", "");
303 ofono_call_added_cb_set(_call_added, ctx);
304 ofono_call_removed_cb_set(_call_removed, ctx);
305 ofono_call_changed_cb_set(_call_changed, ctx);
306 ofono_call_disconnected_cb_set(_call_disconnected, ctx);