if ug create fail, call elm_exit. code cleanup
[framework/appfw/ui-gadget-1.git] / client / ug-client.c
1 /*
2  *  UI Gadget
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <appcore-efl.h>
24 #include <ui-gadget.h>
25 #include <Ecore_X.h>
26 #include <dlog.h>
27 #include <aul.h>
28 #include <appsvc.h>
29
30 #include "ug-client.h"
31
32 #ifdef LOG_TAG
33 #undef LOG_TAG
34 #endif
35
36 #define LOG_TAG "UGClient"
37
38 static void prt_usage(const char *cmd)
39 {
40         fprintf(stderr, "Usage: %s [-f] [-F] -n <UG NAME> [-d <Arguments>]\n",
41                 cmd);
42         fprintf(stderr, "   Options:\n");
43         fprintf(stderr, "            -d argument\n");
44         fprintf(stderr, "            -F Fullview mode (Default)\n");
45         fprintf(stderr, "            -f Frameview mode\n");
46         fprintf(stderr, "   Example:\n");
47         fprintf(stderr,
48                 "            %s -F -n helloUG-efl -d \"name,John Doe\" -d \"age,30\"\n",
49                 cmd);
50
51 }
52
53 static void win_del(void *data, Evas_Object *obj, void *event)
54 {
55         elm_exit();
56 }
57
58 static void main_quit_cb(void *data, Evas_Object *obj,
59                          const char *emission, const char *source)
60 {
61         elm_exit();
62 }
63
64 static int rotate(enum appcore_rm m, void *data)
65 {
66         struct appdata *ad = data;
67         int r;
68
69         if (ad == NULL || ad->win == NULL)
70                 return 0;
71
72         switch (m) {
73         case APPCORE_RM_PORTRAIT_NORMAL:
74                 ug_send_event(UG_EVENT_ROTATE_PORTRAIT);
75                 r = 0;
76                 break;
77         case APPCORE_RM_PORTRAIT_REVERSE:
78                 r = 180;
79                 ug_send_event(UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN);
80                 break;
81         case APPCORE_RM_LANDSCAPE_NORMAL:
82                 ug_send_event(UG_EVENT_ROTATE_LANDSCAPE);
83                 r = 270;
84                 break;
85         case APPCORE_RM_LANDSCAPE_REVERSE:
86                 ug_send_event(UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN);
87                 r = 90;
88                 break;
89         default:
90                 r = -1;
91                 break;
92         }
93
94         if (r >= 0)
95                 elm_win_rotation_with_resize_set(ad->win, r);
96
97         return 0;
98 }
99
100 void layout_cb(ui_gadget_h ug, enum ug_mode mode, void *priv)
101 {
102         struct appdata *ad;
103         Evas_Object *base;
104
105         if (!ug || !priv)
106                 return;
107
108         ad = priv;
109
110         base = ug_get_layout(ug);
111         if (!base)
112                 return;
113
114         switch (mode) {
115         case UG_MODE_FULLVIEW:
116                 evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND,
117                                                  EVAS_HINT_EXPAND);
118                 elm_win_resize_object_add(ad->win, base);
119                 ug_disable_effect(ug);
120                 evas_object_show(base);
121                 break;
122         case UG_MODE_FRAMEVIEW:
123                 elm_object_part_content_set(ad->ly_main, "content", base);
124                 break;
125         default:
126                 break;
127         }
128 }
129
130 void result_cb(ui_gadget_h ug, service_h result, void *priv)
131 {
132         struct appdata *ad;
133         int ret;
134
135         if (!ug || !priv)
136                 return;
137         ad = priv;
138
139         ret = service_reply_to_launch_request(result, ad->request, SERVICE_RESULT_SUCCEEDED);
140         if (ret != SERVICE_ERROR_NONE)
141                 LOGE("service_reply_to_launch_request failed, %d\n", ret);
142 }
143
144 void destroy_cb(ui_gadget_h ug, void *priv)
145 {
146         if (!ug)
147                 return;
148
149         ug_destroy(ug);
150         elm_exit();
151 }
152
153 static Evas_Object *create_win(const char *name)
154 {
155         Evas_Object *eo;
156         int w, h;
157
158         eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
159         if (eo) {
160                 elm_win_title_set(eo, name);
161                 elm_win_borderless_set(eo, EINA_TRUE);
162                 evas_object_smart_callback_add(eo, "delete,request",
163                                                win_del, NULL);
164                 ecore_x_window_size_get(ecore_x_window_root_first_get(),
165                                         &w, &h);
166                 evas_object_resize(eo, w, h);
167         }
168
169         return eo;
170 }
171
172 static Evas_Object *load_edj(Evas_Object *parent, const char *file,
173                              const char *group)
174 {
175         Evas_Object *eo;
176         int r;
177
178         eo = elm_layout_add(parent);
179         if (eo) {
180                 r = elm_layout_file_set(eo, file, group);
181                 if (!r) {
182                         evas_object_del(eo);
183                         return NULL;
184                 }
185
186                 evas_object_size_hint_weight_set(eo,
187                                                  EVAS_HINT_EXPAND,
188                                                  EVAS_HINT_EXPAND);
189         }
190
191         return eo;
192 }
193
194 static int low_memory(void *data)
195 {
196         return ug_send_event(UG_EVENT_LOW_MEMORY);
197 }
198
199 static int low_battery(void *data)
200 {
201         return ug_send_event(UG_EVENT_LOW_BATTERY);
202 }
203
204 static int lang_changed(void *data)
205 {
206         return ug_send_event(UG_EVENT_LANG_CHANGE);
207 }
208
209 static int app_create(void *data)
210 {
211         struct appdata *ad = data;
212         Evas_Object *win;
213         Evas_Object *ly;
214
215         /* create window */
216         win = create_win(PACKAGE);
217         if (win == NULL)
218                 return -1;
219         ad->win = win;
220         UG_INIT_EFL(ad->win, UG_OPT_INDICATOR_ENABLE);
221
222         /* load edje */
223         ly = load_edj(win, EDJ_FILE, GRP_MAIN);
224         if (ly == NULL)
225                 return -1;
226         elm_win_resize_object_add(win, ly);
227         edje_object_signal_callback_add(elm_layout_edje_get(ly),
228                                         "EXIT", "*", main_quit_cb, NULL);
229         ad->ly_main = ly;
230
231         lang_changed(ad);
232
233         appcore_set_rotation_cb(rotate, ad);
234         appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, low_memory, ad);
235         appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, low_battery, ad);
236         appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, lang_changed, ad);
237
238         return 0;
239 }
240
241 static int app_terminate(void *data)
242 {
243         struct appdata *ad = data;
244
245         ug_destroy_all();
246         if (ad->ly_main)
247                 evas_object_del(ad->ly_main);
248
249         if (ad->win)
250                 evas_object_del(ad->win);
251
252         return 0;
253 }
254
255 static int app_pause(void *data)
256 {
257         ug_pause();
258         return 0;
259 }
260
261 static int app_resume(void *data)
262 {
263         ug_resume();
264         return 0;
265 }
266
267 static int svc_cb(void *data)
268 {
269         LOGD("svc_cb called\n");
270         return 0;
271 }
272
273 extern int service_create_event(bundle *data, service_h *service);
274 extern int appsvc_request_transient_app(bundle *b, Ecore_X_Window callee_id, appsvc_host_res_fn cbfunc, void *data);
275
276 static int app_reset(bundle *b, void *data)
277 {
278         struct appdata *ad = data;
279         struct ug_cbs cbs = { 0, };
280         service_h service;
281         enum ug_mode mode = UG_MODE_FULLVIEW;
282
283         Ecore_X_Window id2 = elm_win_xwindow_get(ad->win);
284         appsvc_request_transient_app(b, id2, svc_cb, "svc test");
285
286         if (ad->win) {
287                 elm_win_activate(ad->win);
288                 evas_object_show(ad->win);
289         }
290
291         if (ad->data)   /* ug-launcher */
292                 service_create_event(ad->data, &service);
293         else
294                 service_create_event(b, &service);
295
296         service_clone(&ad->request, service);
297
298         cbs.layout_cb = layout_cb;
299         cbs.destroy_cb = destroy_cb;
300         cbs.result_cb = result_cb;
301         cbs.priv = ad;
302
303         ad->ug = ug_create(NULL, ad->name, mode, service, &cbs);
304         if (ad->ug == NULL) {
305                 LOGE("ug_create fail: %s\n", ad->name);
306                 elm_exit();
307         }
308
309         return 0;
310 }
311
312 static int update_argument(const char *optarg, struct appdata *ad)
313 {
314         const char *key;
315         const char *val;
316         key = strtok((char *)optarg, ",");
317         if (!key)
318                 return -1;
319
320         val = optarg + strlen(key) + 1;
321         if (!val)
322                 return -1;
323
324         if (!ad->data)
325                 ad->data = bundle_create();
326         if (!ad->data)
327                 return -1;
328         bundle_add(ad->data, key, val);
329         return 0;
330 }
331
332 int main(int argc, char *argv[])
333 {
334         int opt;
335         struct appdata ad;
336         struct appcore_ops ops = {
337                 .create = app_create,
338                 .terminate = app_terminate,
339                 .pause = app_pause,
340                 .resume = app_resume,
341                 .reset = app_reset,
342         };
343         int cmdlen = 0;
344
345         setenv("ELM_ENGINE", "gl", 1); //enabling the OpenGL as the backend of the EFL.
346
347         memset(&ad, 0x0, sizeof(struct appdata));
348         ops.data = &ad;
349
350         cmdlen = strlen(argv[0]);
351         if (strncmp(argv[0], "ug-launcher", cmdlen) == 0
352                 || strncmp(argv[0], "/usr/bin/ug-launcher", cmdlen) == 0) {
353                 while ((opt = getopt(argc, argv, "n:d:")) != -1) {
354                         switch (opt) {
355                         case 'n':
356                                 if (optarg)
357                                         ad.name = strdup(optarg);
358                                 break;
359                         case 'd':
360                                 if (update_argument(optarg, &ad)) {
361                                         if (ad.data)
362                                                 bundle_free(ad.data);
363                                         prt_usage(argv[0]);
364                                         return -1;
365                                 }
366                                 break;
367                         default:
368                                 prt_usage(argv[0]);
369                                 return -1;
370                         }
371                 }
372
373                 if (!ad.name) {
374                         prt_usage(argv[0]);
375                         return -1;
376                 }
377                 argc = 1; // remove appsvc bundle
378         } else {        /* ug-client */
379                 char *name = NULL;
380                 name = strrchr(argv[0], '/');
381                 if (name == NULL)
382                         return -1;
383                 /* .../bin/{name} */
384                 ad.name = strdup(&name[1]);
385         }
386         return appcore_efl_main(PACKAGE, &argc, &argv, &ops);
387 }