Upload Tizen2.0 beta source
[apps/home/app-selector.git] / app-selector.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
18
19 #include <stdio.h>
20 #include <appcore-efl.h>
21 #include <Ecore_X.h>
22 #include <utilX.h>
23 #include <aul.h>
24 #include <appsvc.h>
25 #include <X11/Xatom.h>
26 #include <X11/Xutil.h>
27 #include <Ecore.h>
28 #include <Ecore_Input.h>
29
30 #include "app-selector.h"
31 #include "app-selector-view.h"
32 #include "app-selector-util.h"
33
34 int is_reset = 0;
35
36
37 static void __win_del(void *data, Evas_Object * obj, void *event);
38 static Evas_Object *__create_win(const char *name);
39 static Evas_Object *__create_layout_main(Evas_Object * parent);
40 static int __app_create(void *data);
41 static int __app_init_with_bundle(void *data);
42 static int __app_terminate(void *data);
43 static int __app_pause(void *data);
44 static int __app_resume(void *data);
45 static int __app_reset(bundle *b, void *data);
46
47
48 static void __win_del(void *data, Evas_Object * obj, void *event)
49 {
50         elm_exit();
51 }
52
53 static Evas_Object *__create_win(const char *name)
54 {
55         Evas_Object *eo;
56         int w;
57         int h;
58
59         eo = elm_win_add(NULL, name, ELM_WIN_DIALOG_BASIC);
60         if (eo) {
61                 elm_win_title_set(eo, name);
62                 elm_win_borderless_set(eo, EINA_TRUE);
63
64                 elm_win_alpha_set(eo, EINA_TRUE);
65
66                 evas_object_smart_callback_add(eo, "delete,request",
67                                                __win_del, NULL);
68                 ecore_x_window_size_get(ecore_x_window_root_first_get(),
69                                         &w, &h);
70                 evas_object_resize(eo, w, h);
71         }
72
73         return eo;
74 }
75
76 static Evas_Object *__create_layout_main(Evas_Object * parent)
77 {
78         Evas_Object *layout;
79
80         if (!parent)
81                 return NULL;
82
83         layout = elm_layout_add(parent);
84         if (!layout)
85                 return NULL;
86
87         elm_layout_theme_set(layout, "standard", "window", "integration");
88         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND,
89                                          EVAS_HINT_EXPAND);
90
91         edje_object_signal_emit(_EDJ(layout), "elm,state,show,indicator",
92                                 "elm");
93         edje_object_signal_emit(_EDJ(layout), "elm,state,show,content", "elm");
94
95         evas_object_show(layout);
96
97         return layout;
98 }
99
100 static int __get_window_property(Display *dpy, Window win, Atom atom,
101                                           Atom type, unsigned int *val,
102                                           unsigned int len)
103 {
104         unsigned char *prop_ret;
105         Atom type_ret;
106         unsigned long bytes_after;
107         unsigned long  num_ret;
108         int format_ret;
109         unsigned int i;
110         int num;
111
112         prop_ret = NULL;
113         if (XGetWindowProperty(dpy, win, atom, 0, 0x7fffffff, False,
114                                type, &type_ret, &format_ret, &num_ret,
115                                &bytes_after, &prop_ret) != Success)
116                 return -1;
117
118         if (type_ret != type || format_ret != 32)
119                 num = -1;
120         else if (num_ret == 0 || !prop_ret)
121                 num = 0;
122         else {
123                 if (num_ret < len)
124                         len = num_ret;
125                 for (i = 0; i < len; i++) {
126                         val[i] = ((unsigned long *)prop_ret)[i];
127                 }
128                 num = len;
129         }
130
131         if (prop_ret)
132                 XFree(prop_ret);
133
134         return num;
135 }
136
137
138 static int __x_rotation_get(Display *dpy, Window win)
139 {
140         Window active_win;
141         Window root_win;
142         int rotation = -1;
143         int ret;
144
145         int angles[2];
146
147         Atom atom_active_win;
148         Atom atom_win_rotate_angle;
149
150         root_win = XDefaultRootWindow(dpy);
151
152         atom_active_win = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
153         ret = __get_window_property(dpy, root_win, atom_active_win,
154                                              XA_WINDOW,
155                                              (unsigned int *)&active_win, 1);
156
157         /*printf("[SYSPOPUP] Active win : %x, Window %x\n", active_win, win);*/
158
159         /*active_win = get_active_win(dpy, root_win, atom_active_win);*/
160         if (ret < 0)
161                 return ret;
162
163         atom_win_rotate_angle =
164                 XInternAtom(dpy, "_E_ILLUME_ROTATE_WINDOW_ANGLE", False);
165         ret = __get_window_property(dpy, active_win,
166                                           atom_win_rotate_angle, XA_CARDINAL,
167                                           (unsigned int *)&rotation, 1);
168
169         /*printf("[SYSPOPUP] Rotation %d\n", rotation);*/
170
171         if (ret != -1)
172                 return rotation;
173
174         return -1;
175 }
176
177 static int __as_rotate(Display *dpy, Window xwin, Evas_Object *win, void *data)
178 {
179         int rotation;   
180         struct appdata *ad = data;
181
182         ecore_x_icccm_hints_set(xwin, 0, 0, 0, 0, 0, 0, 0);
183
184         rotation = __x_rotation_get(dpy, xwin);
185
186         if (rotation == -1) {
187                 rotation = 0;
188         }
189
190         if (rotation >= 0 && ad->rotate != NULL)
191                 elm_win_rotation_with_resize_set(win, rotation);
192
193         return 0;
194 }
195
196 static Eina_Bool __rotate(void *data, int type, void *event)
197 {
198         struct appdata *ad = data;
199
200         Ecore_X_Event_Client_Message *ev = event;
201
202         if (!event)
203                 return ECORE_CALLBACK_RENEW;
204
205         if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE)
206                 __as_rotate(ad->dpy, ad->xwin, ad->win, ad);    
207
208         return 0;
209 }
210
211 static Eina_Bool s_key_registered;
212
213 static
214 Eina_Bool __key_press_cb(void *data, int type, void *event)
215 {
216         Evas_Event_Key_Down *ev = event;
217         struct appdata *ad = (struct appdata *)data;
218
219         if (!s_key_registered) {
220                 _E("Key is not registered");
221                 return ECORE_CALLBACK_RENEW;
222         }
223
224         if (!ev) {
225                 _E("Invalid event object");
226                 return ECORE_CALLBACK_RENEW;
227         }
228         
229                 ecore_event_handler_del(ad->rotate);
230                 ad->rotate = NULL;
231                 elm_exit();
232
233         return ECORE_CALLBACK_RENEW;
234 }
235
236 static void __register_key_handler(void *data)
237 {
238         Ecore_X_Window win;
239         struct appdata *ad = (struct appdata *)data;
240         win = elm_win_xwindow_get(ad->win);
241
242         ad->key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, 
243                                                                                          __key_press_cb, ad);
244         if (!ad->key_up) {
245                 _E("Failed to register a key down event handler");
246         }
247
248         _D("Key handler is registered");
249         s_key_registered = EINA_TRUE;
250 }
251
252 static void __unregister_key_handler(void *data)
253 {
254         Ecore_X_Window win;
255         struct appdata *ad = (struct appdata *)data;
256
257         if (ad->key_up) {
258                 ecore_event_handler_del(ad->key_up);
259                 ad->key_up = NULL;
260                                 ad->rotate = NULL;
261         }
262
263         _D("Unregister key handler is invoked");
264         s_key_registered = EINA_FALSE;
265 }
266
267 static void __grab_home_key(void *data)
268 {
269         Ecore_X_Window win;
270         struct appdata *ad = (struct appdata *)data;
271
272         win = elm_win_xwindow_get(ad->win);
273         utilx_grab_key(ecore_x_display_get(), win, KEY_HOME, SHARED_GRAB);
274
275         _D("Grab home key.");
276
277                 __register_key_handler(ad);
278 }
279
280 static void __ungrab_home_key(void *data)
281 {
282         Ecore_X_Window win;
283         struct appdata *ad = (struct appdata *)data;
284
285                 __unregister_key_handler(ad);
286
287         win = elm_win_xwindow_get(ad->win);
288         utilx_ungrab_key(ecore_x_display_get(), win, KEY_HOME);
289
290         _D("Ungrab home key.");
291 }
292
293
294
295 static int __app_create(void *data)
296 {
297         struct appdata *ad = (struct appdata *)data;
298         Evas_Object *win;
299         Evas_Object *ly;
300         int r;
301         Display *dpy;
302         Ecore_X_Window xwin;
303         
304
305         /* create window */
306         win = __create_win(PACKAGE);
307         if (win == NULL)
308                 return -1;
309         ad->win = win;
310
311         /* Base Layout */
312         ly = __create_layout_main(ad->win);
313         if (!ly)
314                 return -1;
315
316         edje_object_signal_emit(_EDJ(ly), "elm,bg,show,transparent", "elm");
317         ad->ly_main = ly;
318
319         elm_win_resize_object_add(win, ly);
320
321         ad->dpy = ecore_x_display_get();
322         ad->xwin = elm_win_xwindow_get(win);
323
324         ad->rotate = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,
325                                                          __rotate, (void *)ad); 
326
327         __as_rotate(ad->dpy, ad->xwin, win, ad);
328
329 //      evas_object_show(ly);
330         evas_object_show(win);
331
332         /* init internationalization */
333         r = appcore_set_i18n(PACKAGE, LOCALEDIR);
334         if (r)
335                 return -1;      
336
337         __grab_home_key(ad);
338
339         return 0;
340 }
341
342 static int __app_init_with_bundle(void *data)
343 {
344         struct appdata *ad = data;
345
346 /*      Ecore_X_Display *display = ecore_x_display_get();
347         Ecore_X_Window xwin = elm_win_xwindow_get(ad->win);
348         Ecore_X_Window prev_win =
349             tm_get_user_created_win_with_pid(ad->parent_pid);
350
351         set_transient(display, xwin, prev_win);
352 */
353         load_app_select_popup(ad);
354
355         return 0;
356 }
357
358 static int __app_terminate(void *data)
359 {
360         struct appdata *ad = data;
361
362         if (ad->popup)
363                 evas_object_del(ad->popup);
364
365         if (ad->win)
366                 evas_object_del(ad->win);
367
368         __ungrab_home_key(ad);
369
370         return 0;
371 }
372
373 static int __app_pause(void *data)
374 {
375         struct appdata *ad = data;
376         ecore_event_handler_del(ad->rotate);
377         ad->rotate = NULL;
378         
379         sleep(1);
380         elm_exit();
381
382         return 0;
383 }
384
385 static int __app_resume(void *data)
386 {
387         /*struct appdata *ad = data; */
388
389         return 0;
390 }
391
392 static int __app_reset(bundle *b, void *data)
393 {
394         struct appdata *ad = data;
395         char *str = NULL;
396
397         if (ad->kb)
398                 bundle_free(ad->kb);
399
400         ad->kb = bundle_dup(b);
401
402         ad->mime_type = (char *)bundle_get_val(ad->kb, AUL_K_MIME_TYPE);
403         str = (char *)bundle_get_val(ad->kb, AUL_K_CALLER_PID);
404
405         ad->control_op = (char *)appsvc_get_operation(ad->kb);
406         ad->control_uri = (char *)appsvc_get_uri(ad->kb);
407         ad->control_mime = (char *)appsvc_get_mime(ad->kb);
408
409         if (str)
410                 ad->parent_pid = atoi(str);
411         else
412                 ad->parent_pid = -1;
413
414         if (!ad->mime_type && !ad->control_op) {
415                 load_info_popup(ad, _("Cannot get mimetype!"));
416                 return 0;
417         }
418
419 /*      ad->mime_type = "text"; */
420 /*      ad->parent_pid = 0000; */
421
422         /*
423            If AUL_K_ARGV0 is not NULL, the situation is launching(fork & exec).
424            else the situation is being received a reset event(old relaunch evet)
425          */
426         if (is_reset == 0) {
427                 __app_init_with_bundle(data);   /*(fork & exec) */
428                 is_reset = 1;
429         } else
430                 update_app_list(data);  /*(reset event) */
431
432         return 0;
433 }
434
435 int main(int argc, char *argv[])
436 {
437         struct appdata ad;
438         struct appcore_ops ops = {
439                 .create = __app_create,
440                 .terminate = __app_terminate,
441                 .pause = __app_pause,
442                 .resume = __app_resume,
443                 .reset = __app_reset,
444         };
445
446         memset(&ad, 0x0, sizeof(struct appdata));
447         ops.data = &ad;
448
449         return appcore_efl_main(PACKAGE, &argc, &argv, &ops);
450 }