Sync magnolia to RSA.
[apps/home/volume-app.git] / src / _logic.c
1 /* test
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.tizenopensource.org/license
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include <math.h>
19
20 #include <Ecore.h>
21 #include <Ecore_X.h>
22 #include <utilX.h>
23 #include <vconf.h>
24 #include <ui-gadget.h>
25 #include <X11/Xatom.h>
26 #include <X11/Xutil.h>
27 #include <system_info.h>
28
29 #include"_logic.h"
30 #include "volume.h"
31 #include "_util_log.h"
32 #include "_util_efl.h"
33 #include "_sound.h"
34
35 #define STRBUF_SIZE 128
36 #define PATHBUF_SIZE 256
37
38 enum {
39         IDLELOCK_OFF = 0x0,
40         IDLELOCK_ON,
41         IDLELOCK_MAX,
42 };
43
44 /* _check_status() return value */
45 enum{
46         LOCK_AND_NOT_MEDIA = -0x1,
47         UNLOCK_STATUS,
48         LOCK_AND_MEIDA,
49 };
50
51 #ifndef VCONFKEY_SETAPPL_ACCESSIBILITY_TURN_OFF_ALL_SOUNDS
52 #define VCONFKEY_SETAPPL_ACCESSIBILITY_TURN_OFF_ALL_SOUNDS              VCONFKEY_SETAPPL_PREFIX"/accessibility/turn_off_all_sounds"
53 #endif
54
55 int _close_volume(void *data)
56 {
57         struct appdata *ad = (struct appdata *)data;
58         retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
59         retvm_if(ad->flag_deleting == EINA_TRUE, -1, "Closing volume\n");
60
61         _D("start closing volume\n");
62         ad->flag_deleting = EINA_TRUE;
63
64         _ungrab_key_new(ad);
65         _grab_key_new(ad, ad->input_win, SHARED_GRAB);
66
67         DEL_TIMER(ad->sutimer)
68         DEL_TIMER(ad->lutimer)
69         DEL_TIMER(ad->sdtimer)
70         DEL_TIMER(ad->ldtimer)
71         DEL_TIMER(ad->ptimer)
72
73         if (ad->win){
74                 evas_object_hide(ad->win);
75         }
76         appcore_flush_memory();
77
78         ad->flag_deleting = EINA_FALSE;
79         ad->flag_launching = EINA_FALSE;
80         _D("end closing volume\n");
81         return 0;
82 }
83
84 Eina_Bool popup_timer_cb(void *data)
85 {
86         _D("%s\n", __func__);
87         _close_volume(data);
88         return ECORE_CALLBACK_CANCEL;
89 }
90
91 Eina_Bool _lu_timer_cb(void *data)
92 {
93         int val = -1;
94         struct appdata *ad = (struct appdata *)data;
95         retvm_if(ad == NULL, 0, "Invalid argument: appdata is NULL\n");
96         if (ad->win == NULL || evas_object_visible_get(ad->win) == EINA_FALSE){
97                 _D("win is NULL or hide state, so long press pass\n");
98                 return ECORE_CALLBACK_CANCEL;
99         }
100         DEL_TIMER(ad->stimer)
101
102         _get_sound_level(ad->type, &val);
103         _set_sound_level(ad->type, val +1 > ad->step ? ad->step : val + 1);
104         _D("down, type(%d), step(%d) val[%d]\n", ad->type, ad->step, val+1);
105         return ECORE_CALLBACK_RENEW;
106 }
107
108 Eina_Bool _su_timer_cb(void *data)
109 {
110         struct appdata *ad = (struct appdata *)data;
111         retvm_if(ad == NULL, 0, "Invalid argument: appdata is NULL\n");
112         ADD_TIMER(ad->lutimer, 0.0, _lu_timer_cb, ad)
113         return ECORE_CALLBACK_CANCEL;
114 }
115
116 Eina_Bool _ld_timer_cb(void *data)
117 {
118         int val = 0;
119         struct appdata *ad = (struct appdata *)data;
120         retvm_if(ad == NULL, 0, "Invalid argument: appdata is NULL\n");
121         if (ad->win == NULL || evas_object_visible_get(ad->win) == EINA_FALSE){
122                 _D("win is NULL or hide state, so long press pass\n");
123                 return ECORE_CALLBACK_CANCEL;
124         }
125         DEL_TIMER(ad->stimer)
126
127         _get_sound_level(ad->type, &val);
128         _set_sound_level(ad->type, val -1 <= 0 ? 0 : val - 1);
129         _D("down, type(%d), step(%d) val[%d]\n", ad->type, ad->step, val+1);
130         return ECORE_CALLBACK_RENEW;
131 }
132
133 Eina_Bool _sd_timer_cb(void *data)
134 {
135         struct appdata *ad = (struct appdata *)data;
136         retvm_if(ad == NULL, 0, "Invalid argument: appdata is NULL\n");
137         _D("add long down timer\n");
138         ADD_TIMER(ad->ldtimer, 0.0, _ld_timer_cb, ad)
139         return ECORE_CALLBACK_CANCEL;
140 }
141
142 Eina_Bool _volume_show(void *data)
143 {
144         _D("%s\n", __func__);
145         int status = -1;
146         int type = MM_ERROR_SOUND_VOLUME_CAPTURE_ONLY;
147         int lock = IDLELOCK_ON;
148         struct appdata *ad = (struct appdata *)data;
149         retvm_if(ad == NULL, EINA_FALSE, "Invalid argument: appdata is NULL\n");
150
151         status = _check_status(&lock, &type);
152         if(status != LOCK_AND_NOT_MEDIA && ad->win)
153         {
154                 _init_mm_sound(ad);
155                 /* ungrab SHARED_GRAB */
156                 _ungrab_key_new(ad);
157
158                 if(status == UNLOCK_STATUS)
159                 {
160                         _grab_key_new(ad, -1, TOP_POSITION_GRAB);
161
162                         _rotate_func(ad);
163                         elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_HIDE);
164                         evas_object_show(ad->win);
165                         if(syspopup_has_popup(ad->volume_bundle))
166                                 syspopup_reset(ad->volume_bundle);
167                 }
168                 else if(status == LOCK_AND_MEIDA)
169                 {
170                         _grab_key_new(ad, ad->input_win, EXCLUSIVE_GRAB);
171                 }
172                 ad->flag_launching = EINA_TRUE;
173                 _mm_func(ad);
174                 return EINA_TRUE;
175         }
176         else if(!ad->win)
177         {
178                 /* recreate window */
179         }
180
181         _D("status == LOCK_AND_NOT_MEDIA\n");
182         return EINA_FALSE;
183 }
184
185 static Eina_Bool _key_press_cb(void *data, int type, void *event)
186 {
187         _D("%s\n", __func__);
188         int val=0, snd=0, vib=0;
189         Ecore_Event_Key *ev = event;
190         int status = -1;
191         int mtype = MM_ERROR_SOUND_VOLUME_CAPTURE_ONLY;
192         int lock = IDLELOCK_ON;
193         int is_turn_off_all_sounds = 0;
194         int ret = -1;
195         struct appdata *ad = (struct appdata *)data;
196
197         status = _check_status(&lock, &mtype);
198
199         retvm_if(ev == NULL, ECORE_CALLBACK_CANCEL, "Invalid arguemnt: event is NULL\n");
200         retvm_if(ad == NULL, ECORE_CALLBACK_CANCEL, "Invalid argument: appdata is NULL\n");
201         retvm_if(ad->win == NULL, ECORE_CALLBACK_CANCEL, "Invalid argument: window is NULL\n");
202
203         ret = vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TURN_OFF_ALL_SOUNDS, &is_turn_off_all_sounds);
204         if(ret == 0)
205         {
206                 retvm_if(is_turn_off_all_sounds == EINA_TRUE, ECORE_CALLBACK_CANCEL,
207                         "VCONFKEY_SETAPPL_ACCESSIBILITY_TURN_OFF_ALL_SOUNDS is set, all sound is mute\n");
208         }
209
210         if(!ad->flag_launching)
211         {
212                 if(_volume_show(data) != EINA_TRUE)
213                 {
214                         return ECORE_CALLBACK_CANCEL;
215                 }
216         }
217
218         if(ad->flag_touching == EINA_TRUE) {
219                 return ECORE_CALLBACK_CANCEL;
220         }
221
222         ad->flag_pressing = EINA_TRUE;
223
224         DEL_TIMER(ad->ptimer)
225         vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &snd);
226         vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vib);
227
228         /* If sound is set off, only RINGTONE, MEDIA types are able to change. */
229         if(!snd && ad->type != VOLUME_TYPE_MEDIA && ad->type != VOLUME_TYPE_RINGTONE){
230                 if(vib)_play_vib(ad->sh);
231                 return ECORE_CALLBACK_CANCEL;
232         }
233
234         if (!strcmp(ev->keyname, KEY_VOLUMEUP)) {
235                 _get_sound_level(ad->type, &val);
236                 if (val == ad->step) {
237                         _set_sound_level(ad->type, ad->step);
238                         if(snd)_play_sound(ad->type, ad->sh);
239                         return ECORE_CALLBACK_CANCEL;
240                 }
241                 _set_sound_level(ad->type, val + 1);
242                 if(snd)_play_sound(ad->type, ad->sh);
243                 DEL_TIMER(ad->sutimer)
244                 ADD_TIMER(ad->sutimer, 0.5, _su_timer_cb, ad)
245
246                 _D("set volume %d -> [%d]\n", val, val+1);
247
248         } else if (!strcmp(ev->keyname, KEY_VOLUMEDOWN)) {
249                 _get_sound_level(ad->type, &val);
250                 if (val == 0) {
251                         if(vib)_play_vib(ad->sh);
252                         return ECORE_CALLBACK_CANCEL;
253                 }
254                 _set_sound_level(ad->type, val - 1);
255                 if(snd)_play_sound(ad->type, ad->sh);
256                 DEL_TIMER(ad->sdtimer)
257                 ADD_TIMER(ad->sdtimer, 0.5, _sd_timer_cb, ad)
258
259                 _D("type (%d) set volume %d -> [%d]\n", ad->type, val, val-1);
260
261         }
262         return ECORE_CALLBACK_CANCEL;
263 }
264
265 static Eina_Bool _key_release_cb(void *data, int type, void *event)
266 {
267         Ecore_Event_Key *ev = event;
268         struct appdata *ad = (struct appdata *)data;
269
270         retvm_if(ev == NULL, ECORE_CALLBACK_CANCEL, "Invalid arguemnt: event is NULL\n");
271         retvm_if(ad == NULL, ECORE_CALLBACK_CANCEL, "Invalid argument:appdata is NULL\n");
272         retvm_if(ad->win == NULL, ECORE_CALLBACK_CANCEL, "Invalid argument: window is NULL\n");
273
274         if (ad->flag_touching == EINA_TRUE) {
275                 return ECORE_CALLBACK_CANCEL;
276         }
277
278         if (!strcmp(ev->keyname, KEY_VOLUMEUP)) {
279                 _D("up key released and del timer\n");
280                 DEL_TIMER(ad->sutimer)
281                 DEL_TIMER(ad->lutimer)
282                 DEL_TIMER(ad->luwarmtimer)
283         } else if (!strcmp(ev->keyname, KEY_VOLUMEDOWN)) {
284                 _D("down key released and del timer\n");
285                 DEL_TIMER(ad->sdtimer)
286                 DEL_TIMER(ad->ldtimer)
287                 DEL_TIMER(ad->ldwarmtimer)
288         }
289
290         ad->flag_pressing = EINA_FALSE;
291
292         DEL_TIMER(ad->ptimer)
293
294         ADD_TIMER(ad->ptimer, 3.0, popup_timer_cb, ad)
295
296         return ECORE_CALLBACK_CANCEL;
297 }
298
299 int _grab_key_new(struct appdata *ad, Ecore_X_Window _xwin, int grab_mode)
300 {
301         _D("%s\n", __func__);
302         Ecore_X_Display *disp = NULL;
303         Ecore_X_Window xwin = 0;
304         int ret = -1;
305
306         /* ALREADY GRAB check */
307         switch(grab_mode)
308         {
309                 case SHARED_GRAB : if(ad->flag_shared_grabed)return -1;
310                         break;
311                 case EXCLUSIVE_GRAB : if(ad->flag_exclusive_grabed)return -1;
312                         break;
313                 case TOP_POSITION_GRAB : if(ad->flag_top_positioni_grabed)return -1;
314                         break;
315         }
316
317         disp = ecore_x_display_get();
318         retvm_if(disp == NULL, -1, "Failed to get display\n");
319
320         if(_xwin == -1)
321         {
322                 /* TOP_POSITION_GRAB */
323                 xwin = elm_win_xwindow_get(ad->win);
324                 retvm_if(xwin == 0, -1, "elm_win_xwindow_get() failed\n");
325         }
326         else
327                 xwin = _xwin;
328
329         ret = utilx_grab_key(disp, xwin, KEY_VOLUMEDOWN, grab_mode);
330         retvm_if(ret < 0, -1, "Failed to grab key down\n");
331         retvm_if(ret == 1, -1, "Already grab\n");
332
333         ret = utilx_grab_key(disp, xwin, KEY_VOLUMEUP, grab_mode);
334         retvm_if(ret < 0, -1, "Failed to grab key up\n");
335         retvm_if(ret == 1, -1, "Already grab\n");
336
337         switch(grab_mode)
338         {
339                 case SHARED_GRAB :
340                         ad->flag_shared_grabed = EINA_TRUE;
341                         break;
342                 case EXCLUSIVE_GRAB :
343                         ad->flag_exclusive_grabed = EINA_TRUE;
344                         break;
345                 case TOP_POSITION_GRAB :
346                         ad->flag_top_positioni_grabed = EINA_TRUE;
347                         break;
348         }
349
350         return 0;
351 }
352
353 int _ungrab_key_new(struct appdata *ad)
354 {
355         Ecore_X_Window xwin = 0;
356         Ecore_X_Display *disp = NULL;
357
358         retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
359         retvm_if(ad->input_win == 0, -1, "Invalid argument: ad->win is NULL\n");
360
361         xwin = elm_win_xwindow_get(ad->win);
362         retvm_if(xwin == 0, -1, "Failed to get xwindow\n");
363
364         disp = ecore_x_display_get();
365         retvm_if(disp == NULL, -1, "Failed to get display\n");
366
367         utilx_ungrab_key(disp, ad->input_win, KEY_VOLUMEUP);
368         utilx_ungrab_key(disp, ad->input_win, KEY_VOLUMEDOWN);
369         _D("key ungrabed\n");
370
371         if(ad->flag_exclusive_grabed)
372                 ad->flag_exclusive_grabed = EINA_FALSE;
373         else if(ad->flag_top_positioni_grabed)
374                 ad->flag_top_positioni_grabed = EINA_FALSE;
375         else if(ad->flag_shared_grabed)
376                 ad->flag_shared_grabed = EINA_FALSE;
377
378         return 0;
379 }
380
381 int _get_vconf_idlelock(void)
382 {
383         int ret = -1;
384         int lock = IDLELOCK_OFF;
385
386         ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock);
387         retvm_if(ret < 0, -1, "Failed to get vconf %s\n",
388                  VCONFKEY_IDLE_LOCK_STATE);
389         _D("idlelock vconf:%d\n", lock);
390
391         return lock == VCONFKEY_IDLE_LOCK ? IDLELOCK_ON : IDLELOCK_OFF;
392 }
393
394 volume_type_t _get_volume_type(void)
395 {
396         int ret = MM_ERROR_NONE;
397         volume_type_t type = -1;
398
399         ret = mm_sound_volume_get_current_playing_type(&type);
400         switch (ret) {
401                 case MM_ERROR_NONE:
402                         break;
403                 case MM_ERROR_SOUND_VOLUME_NO_INSTANCE:
404                 case MM_ERROR_SOUND_VOLUME_CAPTURE_ONLY:
405                         type = VOLUME_TYPE_RINGTONE;
406                         break;
407                 default:
408                         _D("Failed to get sound type(errno:%x)\n", ret);
409                         return -1;
410         }
411         if(type == VOLUME_TYPE_NOTIFICATION || type == VOLUME_TYPE_SYSTEM)
412                 type = VOLUME_TYPE_RINGTONE;
413         return type;
414 }
415
416 int _check_status(int *lock, int *type)
417 {
418         *lock = _get_vconf_idlelock();
419         *type = _get_volume_type();
420         _D("lock(%d) type(%d)\n", *lock, *type);
421
422         if (*type == MM_ERROR_SOUND_VOLUME_CAPTURE_ONLY
423                         || *type == MM_ERROR_SOUND_INTERNAL) {
424                 _D("Do not show by type\n");
425                 return -1;
426         }
427
428         if (*lock == IDLELOCK_ON && *type != VOLUME_TYPE_MEDIA) {
429                 _D("lock is set, not in media\n");
430                 return -1;
431         }
432
433         if (*lock == IDLELOCK_ON && *type == VOLUME_TYPE_MEDIA) {
434                 _D("lock is set, in media\n");
435                 return 1;
436         }
437         _D("unlock status, normal case\n");
438         return 0;
439 }
440
441 void _starter_user_volume_key_vconf_changed_cb(keynode_t *key, void *data){
442         _D("%s\n", __func__);
443         int ret = EINA_FALSE;
444         vconf_get_int(VCONFKEY_STARTER_USE_VOLUME_KEY, &ret);
445         if(ret != 0)
446         {
447                 _D("any other App grab volume hard key\n", __func__);
448                 _close_volume(data);
449                 vconf_set_int(VCONFKEY_STARTER_USE_VOLUME_KEY, 0);
450         }
451 }
452
453 void _idle_lock_state_vconf_chnaged_cb(keynode_t *key, void *data){
454         _close_volume(data);
455 }
456
457 int _app_create(struct appdata *ad)
458 {
459         _D("%s\n", __func__);
460         int ret = 0;
461         _init_svi(ad);
462
463         /* create input_window */
464         ad->input_win = _add_input_window();
465         retvm_if(ad->input_win == 0, -1, "Failed to create input window\n");
466
467         /* vconf changed callback */
468         vconf_notify_key_changed(VCONFKEY_STARTER_USE_VOLUME_KEY,
469                                  _starter_user_volume_key_vconf_changed_cb, ad);
470
471         /* Lock screen status vconf changed callback */
472         vconf_notify_key_changed(VCONFKEY_IDLE_LOCK_STATE,
473                                 _idle_lock_state_vconf_chnaged_cb, ad);
474
475         /* grab volume shared grab */
476         ret = _grab_key_new(ad, ad->input_win, SHARED_GRAB);
477
478         /* ecore event handler add once */
479         if(ad->event_volume_down == NULL)
480                 ad->event_volume_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, ad);
481         if(ad->event_volume_up == NULL)
482                 ad->event_volume_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, ad);
483
484         _init_mm_sound(ad);
485
486         return ret;
487 }
488
489 int __utilx_ss_get_window_property(Display *dpy, Window win, Atom atom,
490                                           Atom type, unsigned int *val,
491                                           unsigned int len)
492 {
493         unsigned char *prop_ret = NULL;
494         Atom type_ret = -1;
495         unsigned long bytes_after = 0;
496         unsigned long  num_ret = -1;
497         int format_ret = -1;
498         unsigned int i = 0;
499         int num = 0;
500
501         prop_ret = NULL;
502         if (XGetWindowProperty(dpy, win, atom, 0, 0x7fffffff, False,
503                                type, &type_ret, &format_ret, &num_ret,
504                                &bytes_after, &prop_ret) != Success)
505                 return -1;
506
507         if (type_ret != type || format_ret != 32)
508                 num = -1;
509         else if (num_ret == 0 || !prop_ret)
510                 num = 0;
511         else {
512                 if (num_ret < len)
513                         len = num_ret;
514                 for (i = 0; i < len; i++) {
515                         val[i] = ((unsigned long *)prop_ret)[i];
516                 }
517                 num = len;
518         }
519
520         if (prop_ret)
521                 XFree(prop_ret);
522
523         return num;
524 }
525
526 int _x_rotation_get(Display *dpy, void *data)
527 {
528         Window active_win = 0;
529         Window root_win = 0;
530         int rotation = -1;
531         int ret = -1;
532
533         Atom atom_active_win;
534         Atom atom_win_rotate_angle;
535
536         retvm_if(dpy == NULL, -1, "dpy is NULL\n");
537         root_win = XDefaultRootWindow(dpy);
538
539         atom_active_win = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
540         ret = __utilx_ss_get_window_property(dpy, root_win, atom_active_win,
541                                              XA_WINDOW,
542                                              (unsigned int *)&active_win, 1);
543
544         if(ret < 0)
545                 return ret;
546
547         atom_win_rotate_angle = XInternAtom(dpy, "_E_ILLUME_ROTATE_ROOT_ANGLE", False);
548         ret = __utilx_ss_get_window_property(dpy, root_win,
549                                           atom_win_rotate_angle, XA_CARDINAL,
550                                           (unsigned int *)&rotation, 1);
551
552         if(ret != -1)
553                 return rotation;
554
555         return -1;
556 }
557
558 int _volume_popup_resize(void *data, int angle)
559 {
560         int rotation = 0;
561         int offx=0, offy=0;
562         Evas_Coord minw = -1, minh = -1;
563         Evas_Coord w = 0, h = 0;
564         struct appdata *ad = (struct appdata *)data;
565         retvm_if(ad->win == NULL, -1, "Invalid argument: window is NULL\n");
566         retvm_if(ad->block_events == NULL, -1, "Invalid argument: notify is NULL\n");
567
568         if(angle == -1)
569                 rotation = ad->angle;
570         else
571                 rotation = angle;
572
573         system_info_get_value_int(SYSTEM_INFO_KEY_SCREEN_WIDTH, &w);
574         system_info_get_value_int(SYSTEM_INFO_KEY_SCREEN_HEIGHT, &h);
575
576         switch(rotation){
577                 case 90 :
578                 case 270 :
579                         evas_object_resize(ad->block_events, h, w);
580                         edje_object_size_min_get(ad->block_events, &minw, &minh);
581                         edje_object_size_min_restricted_calc(ad->block_events, &minw, &minh, minw, minh);
582                         offx = (h - minw) / 2;
583                         offy = (w - minh) / 5;
584                         break;
585                 case 0 :
586                 case 180 :
587                 default :
588                         evas_object_resize(ad->block_events, w, h);
589                         edje_object_size_min_get(ad->block_events, &minw, &minh);
590                         edje_object_size_min_restricted_calc(ad->block_events, &minw, &minh, minw, minh);
591                         offx = (w - minw) / 2;
592                         offy = (h - minh) / 5;
593                         break;
594         }
595         _D("w(%d) h(%d) offx(%d) offy(%d)\n", w, h, offx, offy);
596         evas_object_move(ad->ly, offx, offy);
597         return 1;
598 }
599
600 int _efl_rotate(Display *dpy, void *data)
601 {
602         int rotation = -1;
603         struct appdata *ad = (struct appdata *)data;
604
605         rotation = _x_rotation_get(dpy, ad);
606
607         if(rotation == -1)
608                 rotation = 0;
609
610         if(rotation >= 0){
611                 elm_win_rotation_set(ad->win, rotation);
612                 ad->angle = rotation;
613                 return _volume_popup_resize(data, rotation);
614         }
615
616         return 0;
617 }
618
619 int _rotate_func(void *data)
620 {
621         _D("%s\n", __func__);
622         struct appdata *ad = (struct appdata *)data;
623         Display *d = NULL;
624         int ret = 0;
625
626         retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
627
628         d = XOpenDisplay(NULL);
629         ret = _efl_rotate(d, ad);
630         XCloseDisplay(d);
631
632         return ret;
633 }
634
635 int myterm(bundle *b, void *data)
636 {
637         return 0;
638 }
639
640 int mytimeout(bundle *b, void *data)
641 {
642         return 0;
643 }
644
645 syspopup_handler handler = {
646         .def_term_fn = myterm,
647         .def_timeout_fn = mytimeout
648 };
649
650 void _set_level(int type)
651 {
652         int val = 0;
653         _get_sound_level(type, &val);
654         _set_sound_level(type, val);
655         _D("type(%d) val(%d)\n", type, val);
656 }
657
658 static void _block_clicked_cb(void *data, Evas_Object *o, const char *emission, const char *source)
659 {
660         _close_volume(data);
661 }
662
663 Eina_Bool _slider_timer_cb(void *data)
664 {
665         double val = 0;
666         struct appdata *ad = (struct appdata *)data;
667         retvm_if(ad == NULL, 0, "Invalid argument: appdata is NULL\n");
668         if (ad->sl) {
669                 val = elm_slider_value_get(ad->sl);
670                 val += 0.5;
671                 if ((int)val != 0) {
672                         _set_sound_level(ad->type, (int)val);
673                 }
674                 if (val <= 0.5) {
675                         elm_slider_value_set(ad->sl, 0);
676                         _set_sound_level(ad->type, 0);
677                 }
678                 return ECORE_CALLBACK_RENEW;
679         }
680         return ECORE_CALLBACK_CANCEL;
681 }
682
683 static void _slider_start_cb(void *data, Evas_Object *obj, void *event_info)
684 {
685         _D("%s\n", __func__);
686         int snd= 0 ;
687         struct appdata *ad = (struct appdata *)data;
688         retm_if(ad == NULL, "Invalid argument: appdata is NULL\n");
689
690         if (ad->flag_pressing == EINA_TRUE) {
691                 return;
692         }
693         ad->flag_touching = EINA_TRUE;
694
695         DEL_TIMER(ad->ptimer)
696
697         vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &snd);
698         if(!snd){
699                 vconf_set_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, EINA_TRUE);
700                 _set_icon(data, -1);
701         }
702
703         if (ad->lutimer || ad->ldtimer) {
704                 _D("return when long press is working\n");
705                 return;
706         }
707
708         ADD_TIMER(ad->stimer, 0.2, _slider_timer_cb, data)
709 }
710
711 static void _slider_changed_cb(void *data, Evas_Object *obj, void *event_info)
712 {
713         struct appdata *ad = (struct appdata *)data;
714         retm_if(ad == NULL, "Invalid argument: appdata is NULL\n");
715
716         if (ad->flag_pressing == EINA_TRUE) {
717                 return;
718         }
719         if (ad->lutimer || ad->ldtimer) {
720                 _D("return when long press is working\n");
721                 return;
722         }
723 }
724 static void _slider_stop_cb(void *data, Evas_Object *obj, void *event_info)
725 {
726         _D("func\n");
727         double val = 0;
728         struct appdata *ad = (struct appdata *)data;
729         retm_if(ad == NULL, "Invalid argument: appdata is NULL\n");
730
731         if (ad->flag_pressing == EINA_TRUE) {
732                 return;
733         }
734         if (ad->lutimer || ad->ldtimer) {
735                 _D("return when long press is working\n");
736                 return;
737         }
738         DEL_TIMER(ad->stimer)
739         if (ad->sl) {
740                 val = elm_slider_value_get(ad->sl);
741                 val += 0.5;
742                 _set_sound_level(ad->type, (int)val);
743         }
744         _play_sound(ad->type, ad->sh);
745         ad->flag_touching = EINA_FALSE;
746         ADD_TIMER(ad->ptimer, 3.0, popup_timer_cb, ad)
747 }
748
749 Eina_Bool _lu_warmup_timer_cb(void *data)
750 {
751         struct appdata *ad = (struct appdata *)data;
752         retvm_if(ad == NULL, ECORE_CALLBACK_CANCEL, "Invalid argument: appdata is NULL\n");
753         ADD_TIMER(ad->lutimer, 0.0, _lu_timer_cb, ad)
754         return ECORE_CALLBACK_CANCEL;
755 }
756
757 Eina_Bool _ld_warmup_timer_cb(void *data)
758 {
759         struct appdata *ad = (struct appdata *)data;
760         retvm_if(ad == NULL, ECORE_CALLBACK_CANCEL, "Invalid argument: appdata is NULL\n");
761         ADD_TIMER(ad->ldtimer, 0.0, _ld_timer_cb, ad)
762         return ECORE_CALLBACK_CANCEL;
763 }
764
765 void _init_press_timers(void *data)
766 {
767         struct appdata *ad = (struct appdata *)data;
768         retm_if(ad == NULL, "Invalid argument: appdata is NULL\n");
769         DEL_TIMER(ad->sdtimer)
770         DEL_TIMER(ad->ldtimer)
771         DEL_TIMER(ad->ldwarmtimer)
772         DEL_TIMER(ad->sutimer)
773         DEL_TIMER(ad->lutimer)
774         DEL_TIMER(ad->luwarmtimer)
775 }
776
777 int _handle_bundle(bundle *b, struct appdata *ad)
778 {
779         const char *bval = NULL;
780         retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
781
782         bval = bundle_get_val(b, "LONG_PRESS");
783         if (bval) {
784                 _D("val(%s)\n", bval);
785
786                 if (!strncmp(bval, "VOLUME_UP", strlen("LONG_PRESS"))) {
787                         _D("volume up long press\n");
788                         DEL_TIMER(ad->ptimer)
789                         ADD_TIMER(ad->luwarmtimer, 0.5, _lu_warmup_timer_cb, ad);
790                 } else if (!strncmp(bval, "VOLUME_DOWN", strlen("LONG_PRESS"))) {
791                         _D("volume down long press\n");
792                         DEL_TIMER(ad->ptimer)
793                         ADD_TIMER(ad->ldwarmtimer, 0.5, _ld_warmup_timer_cb, ad);
794                 } else {
795                         ADD_TIMER(ad->ptimer, 3.0, popup_timer_cb, ad)
796                 }
797         } else {
798                 ADD_TIMER(ad->ptimer, 3.0, popup_timer_cb, ad)
799                 _init_press_timers(ad);
800         }
801         return 0;
802 }
803
804 static void _button_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
805 {
806         _D("%s\n", __func__);
807         struct appdata *ad = (struct appdata *)data;
808         retm_if(ad == NULL, "Invalid argument: appdata is NULL\n");
809         char buf[PATHBUF_SIZE] = {0, };
810         snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR, IMG_VOLUME_ICON_SETTINGS_PRESSED);
811         elm_image_file_set(obj, buf, NULL);
812 }
813
814 static void _button_cb(void *data, Evas_Object *obj, void *event_info)
815 {
816         _D("%s\n", __func__);
817         struct appdata *ad = (struct appdata *)data;
818         retm_if(ad == NULL, "Invalid argument: appdata is NULL\n");
819         char buf[PATHBUF_SIZE] = {0, };
820         snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR, IMG_VOLUME_ICON_SETTINGS);
821         elm_image_file_set(obj, buf, NULL);
822         if(evas_object_visible_get(ad->win)){
823                 DEL_TIMER(ad->ptimer)
824                 if(ecore_x_e_illume_quickpanel_state_get(
825                         ecore_x_e_illume_zone_get(elm_win_xwindow_get(ad->win))) != ECORE_X_ILLUME_QUICKPANEL_STATE_OFF)
826                 {
827                         _D("Quickpanel is hide\n");
828                         ecore_x_e_illume_quickpanel_state_send(
829                                 ecore_x_e_illume_zone_get(elm_win_xwindow_get(ad->win)), ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
830                 }
831                 service_h svc;
832                 service_create(&svc);
833                 service_set_package(svc, "setting-profile-efl");
834                 service_send_launch_request(svc, NULL, NULL);
835                 _app_pause(ad);
836
837                 service_destroy(svc);
838         }
839 }
840
841 int _app_reset(bundle *b, void *data)
842 {
843         _D("%s\n", __func__);
844         int ret = -1, status = -1, val = 0;
845         int type = MM_ERROR_SOUND_VOLUME_CAPTURE_ONLY;
846         int lock = IDLELOCK_ON;
847         Evas_Object *win, *sl, *ic, *ic_settings;
848         /* volume-app layout */
849         Elm_Theme *th;
850         Evas_Object *outer, *inner, *block;
851         char buf[PATHBUF_SIZE] = {0, };
852         struct appdata *ad = (struct appdata *)data;
853         retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
854
855         ad->noti_seen = EINA_FALSE;
856         ad->flag_launching = EINA_FALSE;
857         ad->flag_pressing = EINA_FALSE;
858         ad->flag_touching = EINA_FALSE;
859
860         status = _check_status(&lock, &type);
861         ad->type = type;
862         mm_sound_volume_get_value(type, (unsigned int*)(&val));
863
864         win = _add_window(PACKAGE);
865         retvm_if(win == NULL, -1, "Failed add window\n");
866         ad->win = win;
867
868         th = elm_theme_new();
869         elm_theme_ref_set(th, NULL);
870         elm_theme_extension_add(th, EDJ_APP);
871
872         block = _add_layout(win, EDJ_APP, GRP_VOLUME_BLOCKEVENTS);
873         edje_object_signal_callback_add(elm_layout_edje_get(block), "clicked", "*", _block_clicked_cb, ad);
874         outer = _add_layout(win, EDJ_APP, GRP_VOLUME_LAYOUT);
875         inner = _add_layout(win, EDJ_APP, "popup_volumebar");
876         ad->block_events = block;
877         ad->ly = outer;
878
879         elm_object_part_content_set(outer, "elm.swallow.content", inner);
880
881         sl = _add_slider(win, 0, ad->step, val);
882         elm_object_theme_set(sl, th);
883         evas_object_smart_callback_add(sl, "slider,drag,start", _slider_start_cb, ad);
884         evas_object_smart_callback_add(sl, "changed", _slider_changed_cb, ad);
885         evas_object_smart_callback_add(sl, "slider,drag,stop", _slider_stop_cb, ad);
886
887         ic_settings = elm_icon_add(win);
888         evas_object_size_hint_aspect_set(ic_settings, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
889         elm_image_resizable_set(ic_settings, EINA_FALSE, EINA_FALSE);
890         snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR, IMG_VOLUME_ICON_SETTINGS);
891         _D("%s\n", buf);
892         elm_image_file_set(ic_settings, buf, NULL);
893         elm_object_part_content_set(inner, "elm.swallow.icon", ic_settings);
894         evas_object_event_callback_add(ic_settings, EVAS_CALLBACK_MOUSE_DOWN, _button_mouse_down_cb, ad);
895         evas_object_smart_callback_add(ic_settings, "clicked", _button_cb, ad);
896         evas_object_show(ic_settings);
897         ad->ic_settings = ic_settings;
898
899         ad->sl = sl;
900         elm_object_part_content_set(inner, "elm.swallow.content", sl);
901
902         ic = elm_icon_add(win);
903         evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
904         elm_image_resizable_set(ic, EINA_FALSE, EINA_FALSE);
905         elm_object_part_content_set(ad->sl, "icon", ic);
906         ad->ic = ic;
907         _set_icon(ad, val);
908
909         ret = syspopup_create(b, &handler, ad->win, ad);
910         retvm_if(ret < 0, -1, "Failed to create syspopup\n");
911         ad->volume_bundle = bundle_dup(b);
912
913         return 0;
914 }
915
916 int _app_pause(struct appdata *ad)
917 {
918         _D("%s\n", __func__);
919         _close_volume(ad);
920         return 0;
921 }