f332be1c162f98a7733abfe17a7052524a36ddb9
[apps/core/preloaded/calendar.git] / src / view-ring.c
1 /*
2
3 Copyright (c) 2000-2012 Samsung Electronics Co., Ltd All Rights Reserved
4
5 This file is part of org.tizen.efl-calendar
6 Written by Taeho Kang <taeho84.kang@samsung.com>
7
8 PROPRIETARY/CONFIDENTIAL
9
10 This software is the confidential and proprietary information of
11 SAMSUNG ELECTRONICS ("Confidential Information"). You shall not
12 disclose such Confidential Information and shall use it only in
13 accordance with the terms of the license agreement you entered
14 into with SAMSUNG ELECTRONICS.
15
16 SAMSUNG make no representations or warranties about the suitability
17 of the software, either express or implied, including but not limited
18 to the implied warranties of merchantability, fitness for a particular
19 purpose, or non-infringement. SAMSUNG shall not be liable for any
20 damages suffered by licensee as a result of using, modifying or
21 distributing this software or its derivatives.
22
23 */
24
25
26 #include <Ecore_X.h>
27 #include <utilX.h>
28 #include <mm_error.h>
29 #include <pmapi.h>
30 #include <wav_player.h>
31
32 #include "view.h"
33 #include "alm-mgr.h"
34 #include "view-ring.h"
35
36 #define DEFAULT_TONE RESDIR "/sounds/On_time.wav"
37
38 static const char *_name = "ring";
39
40 typedef struct {
41         const char *name;
42         struct appdata *ad;
43         Evas_Object *win;
44         Evas_Object *ly;
45
46         Eina_List *cslist;
47
48         Ecore_Timer *tmr;
49         int mm_id;
50
51         int cid;
52
53         int handle;
54         char *ring_path;
55
56         int is_stop;
57         int is_wav_stop;
58 }cal_ring_data;
59
60 static void __cal_ring_set_window_property(Evas_Object *win)
61 {
62         Ecore_X_Window w;
63
64         w = elm_win_xwindow_get(win);
65
66         ecore_x_netwm_window_type_set(w, ECORE_X_WINDOW_TYPE_NOTIFICATION);
67         utilx_set_system_notification_level(ecore_x_display_get(), w, UTILX_NOTIFICATION_LEVEL_NORMAL);
68 }
69
70 static void __cal_ring_stop_alarm(cal_ring_data *p)
71 {
72         CAL_FN_START;
73
74         if (p->mm_id != -1) {
75                 wav_player_stop(p->mm_id);
76                 p->mm_id = -1;
77                 p->is_wav_stop = 1;
78         }
79
80         if (p->ring_path) {
81                 free(p->ring_path);
82                 p->ring_path = NULL;
83         }
84 }
85
86 static void __cal_ring_window_delete_callback(void *data, Evas *e, Evas_Object *obj, void *event)
87 {
88         CAL_FN_START;
89
90         c_retm_if(!data, "data is null");
91
92         cal_ring_data *p = data;
93
94         if (p->tmr)
95                 ecore_timer_del(p->tmr);
96
97         if (p->cslist)
98                 CALENDAR_SVC_FREE_CS_LIST(&p->cslist);
99
100         free(p);
101 }
102
103 static void __cal_ring__cal_ring_fill_cs(cal_struct *cs, Evas_Object *ly)
104 {
105         const char *str;
106         time_t now;
107         struct tm tm;
108         int hour;
109         const char *ampm;
110
111         str = CALENDAR_SVC_STRUCT_GET_STR(cs, CAL_VALUE_TXT_SUMMARY);
112         if (!str)
113                 str = C_("IDS_CLD_BODY_NO_TITLE");
114
115         edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly), "text/title", str);
116
117         now = time(NULL);
118         localtime_r(&now, &tm);
119
120         cal_util_set_time_text(CAL_UTIL_GET_EDJ_DATA(ly), "text/ampm", NULL, CAL_UTIL_TIME_FORMAT_4, &tm);
121         cal_util_set_time_text(CAL_UTIL_GET_EDJ_DATA(ly), "text/currenttime", NULL, CAL_UTIL_TIME_FORMAT_2, &tm);
122
123         cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "min,%02d", tm.tm_min);
124
125         if (tm.tm_hour < 12)
126         {
127                 ampm = "go,am";
128                 hour = tm.tm_hour;
129         }
130         else
131         {
132                 ampm = "go,pm";
133                 hour = tm.tm_hour - 12;
134         }
135
136         cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "hour,%02d", hour * 5 + (tm.tm_min / 12));
137         edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(ly), ampm, "prog");
138 }
139
140
141 static void __cal_ring_play_alarm_completed_cb(int id, void *user_data)
142 {
143         CAL_FN_START;
144
145         c_retm_if(NULL == user_data, "user_data is NULL");
146         cal_ring_data *p = user_data;
147         int mm_id;
148         if (0 == p->is_stop) {
149                 wav_player_start(p->ring_path, SOUND_TYPE_RINGTONE, __cal_ring_play_alarm_completed_cb, p, &mm_id);
150                 p->mm_id = mm_id;
151         } else {
152                 evas_object_del(p->win);
153         }
154
155 }
156
157 static void __cal_ring_play_alarm(cal_ring_data *p, const char *path)
158 {
159         c_retm_if(NULL == p, "p is NULL.");
160         c_retm_if(NULL == path, "path is NULL.");
161
162         int r;
163         int mm_id = 0;
164
165         __cal_ring_stop_alarm(p);
166
167         p->ring_path = strdup(path);
168
169         r = wav_player_start(path, SOUND_TYPE_RINGTONE, __cal_ring_play_alarm_completed_cb, p, &mm_id);
170         c_retm_if(r!= WAV_PLAYER_ERROR_NONE, "wav_player_start is failed.");
171
172         p->is_wav_stop = 0;
173
174         p->mm_id = mm_id;
175 }
176
177 static void __cal_ring_fill(cal_ring_data *p)
178 {
179         cal_struct *cs;
180         const char *tone = NULL;
181         GList *al = NULL;
182         cal_value *val;
183         int cnt;
184
185         if (p->cid)
186                 return; // aleady exist
187
188         if (!p->cslist)
189                 return; // TODO: exit??
190
191         cs = eina_list_data_get(p->cslist);
192         if (!cs)
193                 return; // TODO: exit??
194
195         __cal_ring__cal_ring_fill_cs(cs, p->ly);
196         p->cid = CALENDAR_SVC_STRUCT_GET_INT(cs, CAL_VALUE_INT_INDEX);
197         DBG("Current event id: %d", p->cid);
198
199         CALENDAR_SVC_STRUCT_GET_LIST(cs, CAL_VALUE_LST_ALARM, &al);
200         if (al)
201         {
202                 cnt = g_list_length(al);
203                 c_retm_if(!cnt, "length of alarm list is 0");
204
205                 val = al->data;
206                 c_retm_if(!val, "data of alarm list is null");
207
208                 tone = CALENDAR_SVC_VALUE_GET_STR(val, CAL_VALUE_TXT_ALARMS_TONE);
209         }
210
211         if (!tone || tone[0] == '\0')
212                 tone = DEFAULT_TONE;
213
214         DBG("Ring tone: %s", tone);
215         __cal_ring_play_alarm(p, tone);
216
217         p->cslist = eina_list_remove(p->cslist, cs);
218         CALENDAR_SVC_STRUCT_FREE(&cs);
219 }
220
221 static void __cal_ring_stop_button_callback(void *data, Evas_Object *eo, const char *e, const char *s)
222 {
223         CAL_FN_START;
224
225         c_retm_if(!data, "data is null");
226
227         cal_ring_data *p = data;
228
229         p->cid = 0;
230
231         if (p->cslist) {
232                 __cal_ring_fill(p);
233                 return;
234         }
235
236         if (p->is_wav_stop)
237                 evas_object_del(p->win);
238         else
239                 p->is_stop = 1;
240 }
241
242 static Evas_Object* __cal_ring_create_view(struct appdata *ad)
243 {
244         c_retvm_if(!ad, NULL, "ad is null");
245
246         cal_ring_data *p = calloc(1, sizeof(cal_ring_data));
247         c_retvm_if(!p, NULL, "p is null");
248
249         p->name = _name;
250         p->ad = ad;
251         p->mm_id = -1;
252         p->is_wav_stop = 1;
253
254         p->win = cal_util_add_window(CALENDAR_RING , NULL, NULL);
255         if (!p->win)
256         {
257                 ERR("cal_util_add_window(CALENDAR_RING, NULL, NULL) is failed");
258                 free(p);
259                 return NULL;
260         }
261
262         __cal_ring_set_window_property(p->win);
263         evas_object_data_set(p->win, "priv", p);
264
265         p->ly = cal_util_add_layout(p->win, p->name);
266         if (!p->ly)
267         {
268                 ERR("cal_util_add_layout() is failed");
269                 evas_object_del(p->win);
270                 free(p);
271                 return NULL;
272         }
273
274         elm_win_resize_object_add(p->win, p->ly);
275
276         edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(p->ly), "text/stop", _("Stop"));
277         edje_object_signal_callback_add(CAL_UTIL_GET_EDJ_DATA(p->ly), "stop", "edj", __cal_ring_stop_button_callback, p);
278
279         evas_object_event_callback_add(p->win, EVAS_CALLBACK_DEL, __cal_ring_window_delete_callback, p);
280
281         pm_change_state(LCD_NORMAL);
282
283         evas_object_show(p->win);
284
285         return p->win;
286 }
287
288 static Eina_Bool __cal_ring_timer_callback(void *data)
289 {
290         CAL_FN_START;
291
292         cal_ring_data *p = data;
293
294         // TODO: add quickpanel noti??
295         DBG("Alarm ring timeout!");
296
297         __cal_ring_stop_alarm(p);
298
299         evas_object_del(p->win);
300
301         // TODO: exit??
302
303         p->tmr = NULL;
304         return ECORE_CALLBACK_CANCEL;
305 }
306
307 static int __cal_ring_append_alarm(Evas_Object *win, Eina_List *cslist)
308 {
309         cal_ring_data *p = CAL_UTIL_GET_PRIV_DATA(win);
310
311         if (!p || CAL_STRCMP(p->name, _name))
312         {
313                 ERR("Invalid object");
314                 return -1;
315         }
316
317         p->cslist = eina_list_merge(p->cslist, cslist);
318
319         __cal_ring_fill(p);
320
321         if (!p->tmr)
322         {
323                 p->tmr = ecore_timer_add(60.0, __cal_ring_timer_callback, p);
324                 DBG("Add timer");
325         }
326
327         return 0;
328 }
329
330 static int __cal_ring_create_alarm(struct appdata *ad, Eina_List *cslist)
331 {
332         c_retvm_if(!ad, -1, "ad is null");
333         c_retvm_if(!cslist, -1, "cslist is null");
334
335         Evas_Object *win = __cal_ring_create_view(ad);
336         c_retvm_if(!win, -1, "__cal_ring_create_view returned null");
337
338         return __cal_ring_append_alarm(win, cslist);
339 }
340
341 int cal_ring_add_alarm(struct appdata *ad, Eina_List *csl)
342 {
343         c_retvm_if(!ad, -1, "ad is null");
344         c_retvm_if(!csl, -1, "csl is null");
345
346         return __cal_ring_create_alarm(ad, csl);
347 }
348