Default to hfp modem when no args are passed
[profile/ivi/lemolo.git] / dialer / gui.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4 #include <Elementary.h>
5
6 #include "log.h"
7 #include "gui.h"
8 #include "keypad.h"
9 #include "history.h"
10 #include "callscreen.h"
11 #include "ussd.h"
12 #include "util.h"
13 #include "simple-popup.h"
14
15 #ifdef HAVE_TIZEN
16 #include <appcore-efl.h>
17 #include <ui-gadget.h>
18 #include <Ecore_X.h>
19 #endif
20
21 static Evas_Object *win = NULL;
22 static Evas_Object *main_layout = NULL;
23 static Evas_Object *keypad = NULL;
24 static Evas_Object *contacts = NULL;
25 static Evas_Object *history = NULL;
26 static Evas_Object *cs = NULL;
27 static Evas_Object *flip = NULL;
28
29 static OFono_Callback_List_Modem_Node *callback_node_modem_changed = NULL;
30 static OFono_Callback_List_USSD_Notify_Node *callback_node_ussd_notify = NULL;
31
32 /* XXX elm_flip should just do the right thing, but it does not */
33 static Eina_Bool in_call = EINA_FALSE;
34 static Eina_Bool in_flip_anim = EINA_FALSE;
35
36 Contact_Info *gui_contact_search(const char *number, const char **type)
37 {
38         return contact_search(contacts, number, type);
39 }
40
41 static void _dial_reply(void *data, OFono_Error err,
42                         OFono_Call *call __UNUSED__)
43 {
44         char *number = data;
45
46         if (err != OFONO_ERROR_NONE) {
47                 char buf[1024];
48                 const char *msg = ofono_error_message_get(err);
49                 snprintf(buf, sizeof(buf), "Could not call %s: %s",
50                                 number, msg);
51                 gui_simple_popup("Error", buf);
52         }
53
54         free(number);
55 }
56
57 OFono_Pending *gui_dial(const char *number)
58 {
59         char *copy = strdup(number);
60         return ofono_dial(copy, NULL, _dial_reply, copy);
61 }
62
63 static void _gui_show(Evas_Object *o)
64 {
65         if (o == keypad)
66                 elm_object_signal_emit(main_layout, "show,keypad", "gui");
67         else if (o == contacts)
68                 elm_object_signal_emit(main_layout, "show,contacts", "gui");
69         else if (o == history)
70                 elm_object_signal_emit(main_layout, "show,history", "gui");
71         elm_object_focus_set(o, EINA_TRUE);
72 }
73
74 Evas_Object *gui_simple_popup(const char *title, const char *message)
75 {
76         return simple_popup_add(win, title, message);
77 }
78
79 void gui_activate(void)
80 {
81         elm_win_raise(win);
82         elm_win_activate(win);
83         evas_object_show(win);
84 }
85
86 void gui_number_set(const char *number, Eina_Bool auto_dial)
87 {
88         _gui_show(keypad);
89         keypad_number_set(keypad, number, auto_dial);
90 }
91
92 void gui_activecall_set(Evas_Object *o)
93 {
94         if (o) {
95                 elm_object_part_content_set(main_layout,
96                                                 "elm.swallow.activecall", o);
97                 elm_object_signal_emit(main_layout, "show,activecall", "gui");
98         } else {
99                 o = elm_object_part_content_unset(
100                         main_layout, "elm.swallow.activecall");
101                 elm_object_signal_emit(main_layout, "hide,activecall", "gui");
102                 evas_object_hide(o);
103         }
104 }
105
106 void gui_contacts_show(void)
107 {
108         _gui_show(contacts);
109         gui_call_exit();
110 }
111
112 void gui_call_enter(void)
113 {
114         gui_activate();
115         if (in_call)
116                 return;
117         in_call = EINA_TRUE;
118         if (in_flip_anim)
119                 return;
120         in_flip_anim = EINA_TRUE;
121         elm_flip_go(flip, ELM_FLIP_ROTATE_Y_CENTER_AXIS);
122         elm_object_focus_set(cs, EINA_TRUE);
123 }
124
125 void gui_call_exit(void)
126 {
127         if (!in_call)
128                 return;
129         in_call = EINA_FALSE;
130         if (in_flip_anim)
131                 return;
132         in_flip_anim = EINA_TRUE;
133         elm_flip_go(flip, ELM_FLIP_ROTATE_Y_CENTER_AXIS);
134         elm_object_focus_set(cs, EINA_FALSE);
135 }
136
137 static void _gui_call_sync(void *data __UNUSED__, Evas_Object *o __UNUSED__,
138                                 void *event_info __UNUSED__)
139 {
140         Eina_Bool showing_call = !elm_flip_front_visible_get(flip);
141
142         if (showing_call ^ in_call) {
143                 DBG("Flip back to sync");
144                 elm_flip_go(flip, ELM_FLIP_ROTATE_Y_CENTER_AXIS);
145                 elm_object_focus_set(cs, in_call);
146         }
147         in_flip_anim = EINA_FALSE;
148 }
149
150 static void _gui_voicemail(void)
151 {
152         const char *number = ofono_voicemail_number_get();
153         EINA_SAFETY_ON_NULL_RETURN(number);
154         EINA_SAFETY_ON_FALSE_RETURN(*number != '\0');
155
156         gui_dial(number);
157 }
158
159 static void _on_clicked(void *data __UNUSED__, Evas_Object *o __UNUSED__,
160                         const char *emission, const char *source __UNUSED__)
161 {
162         DBG("signal: %s", emission);
163
164         EINA_SAFETY_ON_FALSE_RETURN(eina_str_has_prefix(emission, "clicked,"));
165         emission += strlen("clicked,");
166
167         if (strcmp(emission, "keypad") == 0)
168                 _gui_show(keypad);
169         else if (strcmp(emission, "contacts") == 0)
170                 _gui_show(contacts);
171         else if (strcmp(emission, "history") == 0)
172                 _gui_show(history);
173         else if (strcmp(emission, "voicemail") == 0)
174                 _gui_voicemail();
175 }
176
177 static void _ofono_changed(void *data __UNUSED__)
178 {
179         const char *number;
180         Eina_Bool waiting;
181         unsigned char count;
182         char buf[32];
183
184         if ((ofono_modem_api_get() & OFONO_API_MSG_WAITING) == 0) {
185                 elm_object_signal_emit(main_layout, "disable,voicemail", "gui");
186                 elm_object_signal_emit(main_layout,
187                                         "toggle,off,voicemail", "gui");
188                 elm_object_part_text_set(main_layout, "elm.text.voicemail", "");
189                 return;
190         }
191
192         number = ofono_voicemail_number_get();
193         waiting = ofono_voicemail_waiting_get();
194         count = ofono_voicemail_count_get();
195
196         if (number)
197                 elm_object_signal_emit(main_layout, "enable,voicemail", "gui");
198         else
199                 elm_object_signal_emit(main_layout, "disable,voicemail", "gui");
200
201         if (waiting) {
202                 if (count == 0)
203                         snprintf(buf, sizeof(buf), "*");
204                 else if (count < 255)
205                         snprintf(buf, sizeof(buf), "%d", count);
206                 else
207                         snprintf(buf, sizeof(buf), "255+");
208
209                 elm_object_signal_emit(main_layout,
210                                         "toggle,on,voicemail", "gui");
211         } else {
212                 buf[0] = '\0';
213                 elm_object_signal_emit(main_layout,
214                                         "toggle,off,voicemail", "gui");
215         }
216
217         elm_object_part_text_set(main_layout, "elm.text.voicemail", buf);
218 }
219
220 static void _ofono_ussd_notify(void *data __UNUSED__, Eina_Bool needs_reply,
221                                 const char *message)
222 {
223         DBG("needs_reply=%d, message=%s", needs_reply, message);
224         ussd_start(message);
225 }
226
227 static void _on_contacts_selected(void *data __UNUSED__,
228                                         Evas_Object *obj __UNUSED__,
229                                         void *event_info)
230 {
231         const char *number = event_info;
232         DBG("Contact selected: %s", number);
233         gui_dial(number);
234 }
235
236 Eina_Bool gui_init(void)
237 {
238         Evas_Object *lay, *obj;
239         Evas_Coord w, h;
240
241         /* dialer should never, ever quit */
242         elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_NONE);
243
244         win = elm_win_util_standard_add("ofono-dialer", "oFono Dialer");
245         EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
246         elm_win_autodel_set(win, EINA_FALSE);
247
248 #ifdef HAVE_TIZEN
249         appcore_set_i18n("ofono-efl", "en-US");
250         UG_INIT_EFL(win, UG_OPT_INDICATOR_PORTRAIT_ONLY);
251 #endif
252
253         flip = elm_flip_add(win);
254         evas_object_size_hint_weight_set(flip,
255                                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
256         evas_object_size_hint_align_set(flip, EVAS_HINT_FILL, EVAS_HINT_FILL);
257         elm_win_resize_object_add(win, flip);
258         evas_object_smart_callback_add(flip, "animate,done",
259                                         _gui_call_sync, NULL);
260         evas_object_show(flip);
261
262         main_layout = lay = layout_add(win, "dialer");
263         EINA_SAFETY_ON_NULL_RETURN_VAL(lay, EINA_FALSE);
264         evas_object_size_hint_weight_set(lay,
265                                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
266         evas_object_size_hint_align_set(lay, EVAS_HINT_FILL, EVAS_HINT_FILL);
267         elm_object_part_content_set(flip, "front", lay);
268         evas_object_show(lay);
269
270         elm_object_signal_callback_add(lay, "clicked,*", "gui",
271                                         _on_clicked, NULL);
272
273         keypad = obj = keypad_add(win);
274         EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
275         elm_object_part_content_set(lay, "elm.swallow.keypad", obj);
276
277         contacts = obj = contacts_add(win);
278         evas_object_smart_callback_add(contacts, "selected",
279                                         _on_contacts_selected, NULL);
280         EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
281         elm_object_part_content_set(lay, "elm.swallow.contacts", obj);
282
283         history = obj = history_add(win);
284         EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
285         elm_object_part_content_set(lay, "elm.swallow.history", obj);
286
287         _gui_show(keypad);
288
289         cs = obj = callscreen_add(win);
290         EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
291         evas_object_size_hint_weight_set(obj,
292                                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
293         evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
294         elm_object_part_content_set(flip, "back", obj);
295         evas_object_show(obj);
296
297         callback_node_modem_changed =
298                 ofono_modem_changed_cb_add(_ofono_changed, NULL);
299         callback_node_ussd_notify =
300                 ofono_ussd_notify_cb_add(_ofono_ussd_notify, NULL);
301
302         /* TODO: make it match better with Tizen: icon and other properties */
303         obj = elm_layout_edje_get(lay);
304         edje_object_size_min_get(obj, &w, &h);
305         if ((w == 0) || (h == 0))
306                 edje_object_size_min_restricted_calc(obj, &w, &h, w, h);
307         if ((w == 0) || (h == 0))
308                 edje_object_parts_extends_calc(obj, NULL, NULL, &w, &h);
309         evas_object_resize(win, w, h);
310
311         /* do not show it yet, RC will check if it should be visible or not */
312         return EINA_TRUE;
313 }
314
315 void gui_shutdown(void)
316 {
317 }