fix crash when resume cb is called
[platform/core/location/ug-setting-location-efl.git] / libug-setting-location-efl.c
1 /*
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 #ifndef UG_MODULE_API
18 #define UG_MODULE_API __attribute__ ((visibility("default")))
19 #endif
20
21 #include <Elementary.h>
22 #include <ui-gadget-module.h>
23 #include <vconf.h>
24 #include <vconf-internal-location-keys.h>
25 #include <location-appman.h>
26
27 #include "libug-setting-location-efl.h"
28 #include "libug-setting-location-efl-mypos.h"
29 #include "libug-setting-location-efl-help.h"
30 #include "libug-setting-location-efl-appman.h"
31 #include "libug-setting-location-efl-log.h"
32
33 #define END_KEY_EVENT   FALSE
34
35 static char *menu[] = {
36         N_("IDS_LBS_BODY_GPS"),
37         N_("IDS_LBS_BODY_ADVANCED_GPS"),
38         N_("IDS_LBS_BODY_NETWORK_POSITION"),
39         N_("IDS_LBS_BODY_MY_POSITION")
40 };
41
42 #define LOCATION_MENU_ENABLE            0
43 #define LOCATION_MENU_AGPS              1
44 #define LOCATION_MENU_NET               2
45 #define LOCATION_MENU_MYPOS             3
46
47 int setting_location_set_int(const char *path, int val)
48 {
49         int ret = vconf_set_int(path, val);
50         if (ret == 0) {
51                 return TRUE;
52         }
53         return FALSE;
54 }
55
56 void setting_location_check_di(void *data)
57 {
58         LOC_LOG("setting_location_check_di");
59         struct ug_data *ugd = (struct ug_data *)data;
60         int i;
61
62         elm_check_state_set(ugd->tg_gps, ugd->is_gps);
63         elm_object_item_disabled_set(ugd->gi_agps, !ugd->is_gps);
64
65         elm_check_state_set(ugd->tg_net, ugd->is_net);
66
67         elm_object_item_disabled_set(ugd->gi_mypos, !(ugd->is_gps || ugd->is_net));
68
69         if (ugd->app_info == NULL) {
70                 return;
71         }
72
73         for (i = 0; i < ugd->app_count; i++) {
74                 elm_object_item_disabled_set(ugd->app_info[i].gi_app, !(ugd->is_gps || ugd->is_net));
75         }
76 }
77
78 static void setting_location_free_itc(Elm_Genlist_Item_Class *itc)
79 {
80         if (itc == NULL) {
81                 return;
82         }
83         elm_genlist_item_class_free(itc);
84 }
85
86
87 static void setting_location_back_cb(void *data, Evas_Object * obj, void *event_info)
88 {
89         struct ug_data *ugd = (struct ug_data *)data;
90         int i;
91
92         setting_location_free_itc(ugd->itc_sep);
93         setting_location_free_itc(ugd->itc_bot_sep);
94         setting_location_free_itc(ugd->itc_gps);
95         setting_location_free_itc(ugd->itc_agps);
96         setting_location_free_itc(ugd->itc_net);
97         setting_location_free_itc(ugd->itc_mypos);
98         setting_location_free_itc(ugd->itc_msg);
99         setting_location_free_itc(ugd->itc_line);
100          if (ugd->app_info != NULL) {
101                 for (i = 0; i < ugd->app_count; i++) {
102                         setting_location_free_itc(ugd->app_info[i].itc_app);
103                 }
104                 free(ugd->app_info);
105         }
106
107         ug_destroy_me(ugd->ug);
108 }
109
110 static void setting_location_help_cb(void *data, Evas_Object * obj, void *event_info)
111 {
112         struct ug_data *ugd = (struct ug_data *)data;
113
114         setting_location_help_view(ugd);
115 }
116
117 static void _setting_location_gps_cb(void *data, Evas_Object * obj, void *event_info)
118 {
119         struct ug_data *ugd = (struct ug_data *)data;
120
121         Eina_Bool state = elm_check_state_get(obj);
122
123         ugd->is_gps = (state == EINA_TRUE) ? KEY_ENABLED : KEY_DISABLED;
124         setting_location_set_int(VCONFKEY_LOCATION_ENABLED, ugd->is_gps);
125         setting_location_check_di(ugd);
126 }
127
128 static void _setting_location_agps_cb(void *data, Evas_Object * obj, void *event_info)
129 {
130         struct ug_data *ugd = (struct ug_data *)data;
131
132         Eina_Bool state = elm_check_state_get(obj);
133
134         if (ugd->is_gps == KEY_DISABLED) {
135                 elm_check_state_set(obj, !state);
136                 return;
137         }
138         ugd->is_agps = (state == EINA_TRUE) ? KEY_ENABLED : KEY_DISABLED;
139         setting_location_set_int(VCONFKEY_LOCATION_AGPS_ENABLED, ugd->is_agps);
140 }
141
142 static void _setting_location_net_cb(void *data, Evas_Object * obj, void *event_info)
143 {
144         struct ug_data *ugd = (struct ug_data *)data;
145
146         Eina_Bool state = elm_check_state_get(obj);
147
148         ugd->is_net = (state == EINA_TRUE) ? KEY_ENABLED : KEY_DISABLED;
149         setting_location_set_int(VCONFKEY_LOCATION_NETWORK_ENABLED, ugd->is_net);
150         setting_location_check_di(ugd);
151 }
152
153 static char *_setting_location_gl_gps_text_get(void *data, Evas_Object * obj, const char *part)
154 {
155         return strdup(_(menu[LOCATION_MENU_ENABLE]));
156 }
157
158 static Evas_Object *_setting_location_gl_gps_check_get(void *data, Evas_Object * obj, const char *part)
159 {
160         struct ug_data *ugd = (struct ug_data *)data;
161
162         Evas_Object *tg;
163
164         ugd->tg_gps = tg = elm_check_add(obj);
165
166         if (ugd->is_gps == KEY_ENABLED) {
167                 elm_check_state_set(tg, EINA_TRUE);
168         } else {
169                 elm_check_state_set(tg, EINA_FALSE);
170         }
171
172         elm_object_style_set(tg, "on&off");
173         evas_object_propagate_events_set(tg, EINA_FALSE);
174         evas_object_smart_callback_add(tg, "changed", _setting_location_gps_cb, ugd);
175
176         return tg;
177 }
178
179 static char *_setting_location_gl_agps_text_get(void *data, Evas_Object * obj, const char *part)
180 {
181         return strdup(_(menu[LOCATION_MENU_AGPS]));
182 }
183
184 static Evas_Object *_setting_location_gl_agps_check_get(void *data, Evas_Object * obj, const char *part)
185 {
186         struct ug_data *ugd = (struct ug_data *)data;
187
188         Evas_Object *tg;
189
190         ugd->tg_agps = tg = elm_check_add(obj);
191
192         if (ugd->is_agps == KEY_ENABLED) {
193                 elm_check_state_set(tg, EINA_TRUE);
194         } else {
195                 elm_check_state_set(tg, EINA_FALSE);
196         }
197
198         elm_object_style_set(tg, "on&off");
199         evas_object_propagate_events_set(tg, EINA_FALSE);
200         evas_object_smart_callback_add(tg, "changed", _setting_location_agps_cb, ugd);
201
202         return tg;
203 }
204
205 static char *_setting_location_gl_net_text_get(void *data, Evas_Object * obj, const char *part)
206 {
207         return strdup(_(menu[LOCATION_MENU_NET]));
208 }
209
210 static Evas_Object *_setting_location_gl_net_check_get(void *data, Evas_Object * obj, const char *part)
211 {
212         struct ug_data *ugd = (struct ug_data *)data;
213
214         Evas_Object *tg;
215
216         ugd->tg_net = tg = elm_check_add(obj);
217
218         if (ugd->is_net == KEY_ENABLED) {
219                 elm_check_state_set(tg, EINA_TRUE);
220         } else {
221                 elm_check_state_set(tg, EINA_FALSE);
222         }
223
224         elm_object_style_set(tg, "on&off");
225         evas_object_propagate_events_set(tg, EINA_FALSE);
226         evas_object_smart_callback_add(tg, "changed", _setting_location_net_cb, ugd);
227
228         return tg;
229 }
230
231 static char *_setting_location_gl_mypos_text_get(void *data, Evas_Object * obj, const char *part)
232 {
233         return strdup(_(menu[LOCATION_MENU_MYPOS]));
234 }
235
236 static Evas_Object *setting_location_create_layout(Evas_Object * parent)
237 {
238         Evas_Object *layout;
239         Evas_Object *bg;
240
241         layout = elm_layout_add(parent);
242         elm_layout_theme_set(layout, "layout", "application", "default");
243         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
244         elm_win_resize_object_add(parent, layout);
245
246         bg = elm_bg_add(layout);
247         evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
248         elm_object_part_content_set(layout, "elm.swallow.bg", bg);
249         elm_object_style_set(bg, "group_list");
250         
251         evas_object_show(layout);
252
253         return layout;
254 }
255
256 Evas_Object *setting_location_create_navibar(Evas_Object * parent)
257 {
258         Evas_Object *naviframe;
259
260         naviframe = elm_naviframe_add(parent);
261         //elm_object_style_set(navi_bar, "extended_fnbtn_top_style");
262         elm_object_part_content_set(parent, "elm.swallow.content", naviframe);
263
264         evas_object_show(naviframe);
265
266         return naviframe;
267 }
268
269 static void setting_location_gl_gps_sel(void *data, Evas_Object *obj, void *event_info)
270 {
271         LOC_LOG("setting_location_gl_gps_sel");
272         struct ug_data *ugd = (struct ug_data *)data;
273         Eina_Bool state = elm_check_state_get(ugd->tg_gps);
274
275         elm_check_state_set(ugd->tg_gps, !state);
276         ugd->is_gps = (!state == EINA_TRUE) ? KEY_ENABLED : KEY_DISABLED;
277         setting_location_set_int(VCONFKEY_LOCATION_ENABLED, ugd->is_gps);
278         elm_genlist_item_selected_set((Elm_Object_Item *)event_info, EINA_FALSE);
279 }
280
281 static void setting_location_gl_agps_sel(void *data, Evas_Object *obj, void *event_info)
282 {
283         LOC_LOG("setting_location_gl_agps_sel");
284         struct ug_data *ugd = (struct ug_data *)data;
285         Eina_Bool state = elm_check_state_get(ugd->tg_agps);
286
287         elm_check_state_set(ugd->tg_agps, !state);
288         ugd->is_agps = (!state == EINA_TRUE) ? KEY_ENABLED : KEY_DISABLED;
289         setting_location_set_int(VCONFKEY_LOCATION_AGPS_ENABLED, ugd->is_agps);
290         elm_genlist_item_selected_set((Elm_Object_Item *)event_info, EINA_FALSE);
291 }
292
293 static void setting_location_gl_net_sel(void *data, Evas_Object *obj, void *event_info)
294 {
295         LOC_LOG("setting_location_gl_net_sel");
296         struct ug_data *ugd = (struct ug_data *)data;
297         Eina_Bool state = elm_check_state_get(ugd->tg_net);
298
299         elm_check_state_set(ugd->tg_net, !state);
300         ugd->is_net = (!state == EINA_TRUE) ? KEY_ENABLED : KEY_DISABLED;
301         setting_location_set_int(VCONFKEY_LOCATION_NETWORK_ENABLED, ugd->is_net);
302         elm_genlist_item_selected_set((Elm_Object_Item *)event_info, EINA_FALSE);
303 }
304
305 static void setting_location_mypos_sel(void *data, Evas_Object *obj, void *event_info)
306 {
307         struct ug_data *ugd = (struct ug_data *)data;
308
309         elm_genlist_select_mode_set(ugd->genlist, ELM_OBJECT_SELECT_MODE_NONE);
310
311         elm_genlist_item_selected_set((Elm_Object_Item *)event_info, EINA_FALSE);
312         setting_location_mypos_view(data);
313         return;
314 }
315
316 Evas_Object *setting_location_create_gl(Evas_Object * parent, void *data)
317 {
318         LOC_LOG("setting_location_create_gl");
319         struct ug_data *ugd = (struct ug_data *)data;
320
321         Evas_Object *genlist;
322         Elm_Object_Item *item;
323
324         genlist = elm_genlist_add(parent);
325         elm_object_style_set(genlist, "dialogue");
326         elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
327
328         ugd->itc_sep = elm_genlist_item_class_new();
329         ugd->itc_sep->item_style = "dialogue/separator/21/with_line";
330         ugd->itc_sep->func.text_get = NULL;
331         ugd->itc_sep->func.content_get = NULL;
332         ugd->itc_sep->func.state_get = NULL;
333         ugd->itc_sep->func.del = NULL;
334
335         item = elm_genlist_item_append(genlist, ugd->itc_sep, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
336         elm_genlist_item_select_mode_set(item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
337
338         ugd->itc_gps = elm_genlist_item_class_new();
339         ugd->itc_gps->item_style = "dialogue/1text.1icon";
340         ugd->itc_gps->func.text_get = _setting_location_gl_gps_text_get;
341         ugd->itc_gps->func.content_get = _setting_location_gl_gps_check_get;
342         ugd->itc_gps->func.state_get = NULL;
343         ugd->itc_gps->func.del = NULL;
344
345         ugd->gi_gps = elm_genlist_item_append(genlist, ugd->itc_gps, (void *)ugd, NULL, ELM_GENLIST_ITEM_NONE, setting_location_gl_gps_sel, ugd);
346
347         ugd->itc_agps = elm_genlist_item_class_new();
348         ugd->itc_agps->item_style = "dialogue/1text.1icon";
349         ugd->itc_agps->func.text_get = _setting_location_gl_agps_text_get;
350         ugd->itc_agps->func.content_get = _setting_location_gl_agps_check_get;
351         ugd->itc_agps->func.state_get = NULL;
352         ugd->itc_agps->func.del = NULL;
353
354         ugd->gi_agps = elm_genlist_item_append(genlist, ugd->itc_agps, (void *)ugd, NULL, ELM_GENLIST_ITEM_NONE, setting_location_gl_agps_sel, ugd);
355
356         ugd->itc_net = elm_genlist_item_class_new();
357         ugd->itc_net->item_style = "dialogue/1text.1icon";
358         ugd->itc_net->func.text_get = _setting_location_gl_net_text_get;
359         ugd->itc_net->func.content_get = _setting_location_gl_net_check_get;
360         ugd->itc_net->func.state_get = NULL;
361         ugd->itc_net->func.del = NULL;
362
363         ugd->gi_net = elm_genlist_item_append(genlist, ugd->itc_net, (void *)ugd, NULL, ELM_GENLIST_ITEM_NONE, setting_location_gl_net_sel, ugd);
364
365         ugd->itc_mypos = elm_genlist_item_class_new();
366         ugd->itc_mypos->item_style = "dialogue/1text.1icon";
367         ugd->itc_mypos->func.text_get = _setting_location_gl_mypos_text_get;
368         ugd->itc_mypos->func.content_get = NULL;
369         ugd->itc_mypos->func.state_get = NULL;
370         ugd->itc_mypos->func.del = NULL;
371
372         ugd->gi_mypos = elm_genlist_item_append(genlist, ugd->itc_mypos, (void *)ugd, NULL, ELM_GENLIST_ITEM_NONE, setting_location_mypos_sel, ugd);
373
374         return genlist;
375 }
376
377 void setting_location_add_bottom_sep(Evas_Object *genlist, struct ug_data *ugd)
378 {
379         Elm_Object_Item *item;
380
381         ugd->itc_bot_sep = elm_genlist_item_class_new();
382         ugd->itc_bot_sep->item_style = "dialogue/separator/20";
383         ugd->itc_bot_sep->func.text_get = NULL;
384         ugd->itc_bot_sep->func.content_get = NULL;
385         ugd->itc_bot_sep->func.state_get = NULL;
386         ugd->itc_bot_sep->func.del = NULL;
387
388         ugd->gi_bot_sep = elm_genlist_item_append(genlist, ugd->itc_bot_sep, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
389         elm_genlist_item_select_mode_set(item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
390 }
391
392 static Evas_Object *setting_location_create_view(Evas_Object * parent, struct ug_data *ugd)
393 {
394         Evas_Object *layout_main;
395         Elm_Object_Item* navi_it;
396         Evas_Object *l_button;
397         Evas_Object *help_button;
398         Evas_Object *toolbar;
399
400         layout_main = setting_location_create_layout(parent);
401
402         ugd->naviframe = setting_location_create_navibar(layout_main);
403
404         l_button = elm_button_add(ugd->naviframe);
405         elm_object_style_set(l_button, "naviframe/back_btn/default");
406         evas_object_smart_callback_add(l_button, "clicked", setting_location_back_cb, ugd);
407
408         ugd->genlist = setting_location_create_gl(ugd->naviframe, ugd);
409
410         setting_location_get_location_app_list(ugd->genlist, ugd);
411
412         setting_location_add_bottom_sep(ugd->genlist, ugd);
413
414         evas_object_show(ugd->genlist);
415
416         navi_it = elm_naviframe_item_push(ugd->naviframe, _("IDS_LBS_BODY_LOCATION"), l_button, NULL, ugd->genlist, NULL);
417
418         toolbar = elm_toolbar_add(ugd->naviframe);
419         elm_toolbar_shrink_mode_set(toolbar, ELM_TOOLBAR_SHRINK_EXPAND);
420
421         help_button = (Evas_Object *)elm_toolbar_item_append(toolbar, NULL, _("IDS_COM_BODY_HELP"), setting_location_help_cb, ugd);
422         elm_object_item_disabled_set(elm_toolbar_item_append(toolbar, NULL, "", NULL, NULL), EINA_TRUE);
423         elm_object_item_part_content_set(navi_it, "controlbar", toolbar);
424
425         return layout_main;
426 }
427
428 void gps_enabled_cb(keynode_t * key, void *data)
429 {
430         struct ug_data *ugd = (struct ug_data *)data;
431         vconf_get_int(VCONFKEY_LOCATION_ENABLED, &ugd->is_gps);
432         setting_location_check_di(ugd);
433 }
434
435 void net_enabled_cb(keynode_t * key, void *data)
436 {
437         struct ug_data *ugd = (struct ug_data *)data;
438         vconf_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &ugd->is_net);
439         setting_location_check_di(ugd);
440 }
441
442 int setting_location_init(struct ug_data *ugd)
443 {
444         LOC_LOG("setting_location_init");
445         int ret = TRUE;
446
447         ret &= vconf_get_int(VCONFKEY_LOCATION_ENABLED, &ugd->is_gps);
448         ret &= vconf_get_int(VCONFKEY_LOCATION_AGPS_ENABLED, &ugd->is_agps);
449         ret &= vconf_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &ugd->is_net);
450         ret &= vconf_notify_key_changed(VCONFKEY_LOCATION_ENABLED, gps_enabled_cb, (void *)ugd);
451         ret &= vconf_notify_key_changed(VCONFKEY_LOCATION_NETWORK_ENABLED, net_enabled_cb, (void *)ugd);
452
453         setting_location_check_di(ugd);
454
455         return ret;
456 }
457
458 int setting_location_deinit(struct ug_data *ugd)
459 {
460         int ret = TRUE;
461
462         ret = vconf_ignore_key_changed(VCONFKEY_LOCATION_ENABLED, gps_enabled_cb);
463         ret = vconf_ignore_key_changed(VCONFKEY_LOCATION_NETWORK_ENABLED, net_enabled_cb);
464
465         return ret;
466 }
467
468 UG_MODULE_API int setting_plugin_reset(service_h service, void *priv)
469 {
470         if (vconf_set_int(VCONFKEY_LOCATION_ENABLED, KEY_ENABLED) != 0) {
471                 return -1;
472         }
473         if (vconf_set_int(VCONFKEY_LOCATION_AGPS_ENABLED, KEY_DISABLED) != 0) {
474                 return -1;
475         }
476         if (vconf_set_int(VCONFKEY_LOCATION_NETWORK_ENABLED, KEY_DISABLED) != 0) {
477                 return -1;
478         }
479
480         return 0;
481 }
482
483 static void *on_create(ui_gadget_h ug, enum ug_mode mode, service_h service, void *priv)
484 {
485         Evas_Object *parent;
486         struct ug_data *ugd;
487
488         if (!ug || !priv)
489                 return NULL;
490
491         bindtextdomain("ug-setting-location-efl", "/opt/ug/res/locale");
492
493         ugd = priv;
494         ugd->ug = ug;
495
496         parent = ug_get_parent_layout(ug);
497         if (!parent) {
498                 return NULL;
499         }
500
501         if (mode == UG_MODE_FULLVIEW) {
502                 ugd->base = setting_location_create_view(parent, ugd);
503                 setting_location_init(ugd);
504         } else {
505                 return NULL;
506         }
507
508         return ugd->base;
509 }
510
511 static void on_start(ui_gadget_h ug, service_h service, void *priv)
512 {
513         LOC_LOG("on_start is called");
514 }
515
516 static void on_pause(ui_gadget_h ug, service_h service, void *priv)
517 {
518         LOC_LOG("on_pause is called");
519         struct ug_data *ugd = (struct ug_data *)priv;
520
521         elm_object_item_del(ugd->gi_bot_sep);
522         setting_location_free_itc(ugd->itc_bot_sep);
523 }
524
525 static void on_resume(ui_gadget_h ug, service_h service, void *priv)
526 {
527         LOC_LOG("on_resume is called");
528         struct ug_data *ugd = (struct ug_data *)priv;
529         setting_location_delete_app_list(ugd->genlist, ugd);
530         setting_location_get_location_app_list(ugd->genlist, ugd);
531         setting_location_add_bottom_sep(ugd->genlist, ugd);
532         setting_location_check_di(ugd);
533 }
534
535 static void on_destroy(ui_gadget_h ug, service_h service, void *priv)
536 {
537         struct ug_data *ugd = (struct ug_data *)priv;
538
539         if (!ug || !priv) {
540                 return;
541         }
542
543         service_h result;
544         char value[32] = {0,};
545
546         service_create(&result);
547         if (ugd->is_gps && ugd->is_net) strncpy(value, "GPSEnabled|WPSEnabled", sizeof(value));
548         else if (ugd->is_gps && !ugd->is_net) strncpy(value, "GPSEnabled|WPSDisabled", sizeof(value));
549         else if (!ugd->is_gps && ugd->is_net) strncpy(value, "GPSDisabled|WPSEnabled", sizeof(value));
550         else if (!ugd->is_gps && !ugd->is_net) strncpy(value, "GPSDisabled|WPSDisabled", sizeof(value));
551         service_add_extra_data(result, "State", value);
552
553         ug_send_result(ug, result);
554
555         setting_location_deinit(ugd);
556
557         if (ugd->base != NULL) {
558                 evas_object_del(ugd->base);
559         }
560
561         ugd->base = NULL;
562 }
563
564 static void on_message(ui_gadget_h ug, service_h msg, service_h data, void *priv)
565 {
566 }
567
568 static void on_event(ui_gadget_h ug, enum ug_event event, service_h data, void *priv)
569 {
570         switch (event) {
571         case UG_EVENT_LOW_MEMORY:
572                 break;
573         case UG_EVENT_LOW_BATTERY:
574                 break;
575         case UG_EVENT_LANG_CHANGE:
576                 break;
577         case UG_EVENT_ROTATE_PORTRAIT:
578                 break;
579         case UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN:
580                 break;
581         case UG_EVENT_ROTATE_LANDSCAPE:
582                 break;
583         case UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN:
584                 break;
585         default:
586                 break;
587         }
588 }
589
590 static void on_key_event(ui_gadget_h ug, enum ug_key_event event, service_h data, void *priv)
591 {
592         if (!ug) {
593                 return;
594         }
595
596         switch (event) {
597         case UG_KEY_EVENT_END:
598                 ug_destroy_me(ug);
599                 break;
600         default:
601                 break;
602         }
603 }
604
605 UG_MODULE_API int UG_MODULE_INIT(struct ug_module_ops *ops)
606 {
607         struct ug_data *ugd;
608
609         if (!ops) {
610                 return -1;
611         }
612
613         ugd = calloc(1, sizeof(struct ug_data));
614         if (!ugd) {
615                 return -1;
616         }
617
618         ops->create = on_create;
619         ops->start = on_start;
620         ops->pause = on_pause;
621         ops->resume = on_resume;
622         ops->destroy = on_destroy;
623         ops->message = on_message;
624         ops->event = on_event;
625         ops->key_event = on_key_event;
626         ops->priv = ugd;
627         ops->opt = UG_OPT_INDICATOR_ENABLE;
628
629         return 0;
630 }
631
632 UG_MODULE_API void UG_MODULE_EXIT(struct ug_module_ops *ops)
633 {
634         struct ug_data *ugd;
635
636         if (!ops) {
637                 return;
638         }
639
640         ugd = ops->priv;
641
642         if (ugd) {
643                 free(ugd);
644         }
645 }