Change std:vector to eina_array
[platform/upstream/SDL.git] / src / video / tizen / indicator / SDL_tizenindicator.c
1 #include <app.h>
2 #include <Elementary.h>
3 #include <Ecore_Ipc.h>
4
5 //for 'tizen_policy_set_transient_for'
6 //#ifndef EFL_BETA_API_SUPPORT
7 //#define EFL_BETA_API_SUPPORT
8 //#endif
9 #include <Ecore_Wl2.h>
10 #include <tizen-extension-client-protocol.h>
11 #include <wayland-util.h>
12
13 #include "SDL_tizenindicator.h"
14 #include "dbg.h"
15
16 Eina_Array *mEcoreEventHandler;
17
18 static Eina_Bool
19 _tizen_set_transient_for (appdata_s *ad, uint32_t child_id, uint32_t parent_id)
20 {
21         /*
22         child_id : indicator resource id
23         parent_id :  SDL window resource id,
24         */
25     Eina_Iterator *globals;
26     Ecore_Wl2_Global *global;
27         struct wl_registry *registry;
28         if (!ad->tizen_policy)
29         {
30         Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
31
32         registry = ecore_wl2_display_registry_get(wl2_display);
33         globals = ecore_wl2_display_globals_get(wl2_display);
34
35                 if (!registry || !globals)
36                 {
37                         if(globals)
38                         {
39                                 eina_iterator_free(globals);
40                         }
41                         return EINA_FALSE;
42                 }
43         EINA_ITERATOR_FOREACH(globals, global)
44                 {
45                         if (!strcmp(global->interface, "tizen_policy"))
46                         ad->tizen_policy = wl_registry_bind(registry, global->id, &tizen_policy_interface, 7);
47                 }
48         eina_iterator_free(globals);
49                 if (!ad->tizen_policy)
50                         return EINA_FALSE;
51         }
52
53         _INFO("[SDL] handle_server_data major : %d, minor : %d\n", child_id, parent_id);
54         tizen_policy_set_transient_for (ad->tizen_policy, child_id, parent_id);
55
56         return EINA_TRUE;
57 }
58
59 Eina_Bool
60 handler_server_add(void *data, int ev_type EINA_UNUSED, void *ev)
61 {
62         appdata_s *ad = (appdata_s *)data;
63         IPC_HEAD(ad , Add);
64
65         _INFO("[SDL] handler_server_add\n");
66         ad->isShowing = 1;
67         ecore_ipc_server_send(ad->IpcServer, OP_INDICATOR_INIT, ad->indicator_h, 0, 0, 0, NULL, 0);
68         return 1;
69 }
70
71 Eina_Bool
72 handler_server_del(void *data, int ev_type EINA_UNUSED, void *ev)
73 {
74         appdata_s *ad = (appdata_s *)data;
75         IPC_HEAD(ad, Del);
76         _INFO("[SDL] handler_server_del\n");
77         return 1;
78 }
79
80 void resetTimer(appdata_s *ad)
81 {
82         if(ad->timer_hide_effect)
83         {
84                 ecore_timer_freeze(ad->timer_hide_effect);
85                 ecore_timer_reset(ad->timer_hide_effect);
86                 ecore_timer_del(ad->timer_hide_effect);
87         }
88
89         if(ad->timer_hide_window)
90         {
91                 ecore_timer_freeze(ad->timer_hide_window);
92                 ecore_timer_reset(ad->timer_hide_window);
93                 ecore_timer_del(ad->timer_hide_window);
94         }
95
96         ad->timer_hide_effect = NULL;
97         ad->timer_hide_window = NULL;
98 }
99
100 Eina_Bool ecore_timer_cb_hide_effect(void *data) {
101         appdata_s *ad = (appdata_s *)data;
102
103         elm_object_signal_emit(ad->conform, "indicator,hide,effect", "elm");
104         ecore_ipc_server_send(ad->IpcServer, OP_INDICATOR_HIDE, 1, 0, 0, 0, NULL, 0);
105
106         return ECORE_CALLBACK_PASS_ON;
107 }
108
109 Eina_Bool ecore_timer_cb_hide_window(void *data) {
110         appdata_s *ad = (appdata_s *)data;
111         ecore_ipc_server_send(ad->IpcServer, OP_INDICATOR_HIDE, 2, 0, 0, 0, NULL, 0);
112         resetTimer(ad);
113         elm_win_iconified_set(ad->win, EINA_TRUE);
114         elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_HIDE);
115
116         return ECORE_CALLBACK_PASS_ON;
117 }
118
119 void start_hide_timer(appdata_s *ad)
120 {
121
122         ad->timer_hide_effect = ecore_timer_add(2.4, ecore_timer_cb_hide_effect, ad);
123         ad->timer_hide_window = ecore_timer_add(2.5, ecore_timer_cb_hide_window, ad);
124 }
125
126 void setIndicatorGeometry(appdata_s *ad)
127 {
128         int idx = ad->rotation / 90;
129         elm_win_rotation_set(ad->win, ad->rotation);
130         evas_object_resize(ad->win, info_size[idx][0], info_size[idx][1]);
131         evas_object_move(ad->win, info_position[idx][0], info_position[idx][1]);
132
133         _INFO("[SDL] setIndicator - rotation:%d, x:%d, y:%d, w:%d, h:%d\n", ad->rotation,
134                         info_position[idx][0], info_position[idx][1], info_size[idx][0], info_size[idx][1]);
135
136 }
137
138 void setIndicatorOpacity(appdata_s *ad, int style)
139 {
140         switch(style)
141         {
142         case 1:
143                 elm_win_indicator_opacity_set(ad->win, SDL_INDICATOR_OPAQUE);
144         break;
145         case 2:
146                 elm_win_indicator_opacity_set(ad->win, SDL_INDICATOR_TRANSLUCENT);
147         break;
148         case 3:
149                 elm_win_indicator_opacity_set(ad->win, SDL_INDICATOR_TRANSPARENT);
150         break;
151         case 4:
152                 elm_win_indicator_opacity_set(ad->win, SDL_INDICATOR_OPAQUE);
153                 elm_object_signal_emit(ad->conform, "elm,state,indicator,overlap", "elm");
154         break;
155         }
156 }
157
158 void showIndicator(appdata_s *ad)
159 {
160         elm_win_iconified_set(ad->win, EINA_FALSE);
161         setIndicatorGeometry(ad);
162         elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
163         elm_object_signal_emit(ad->conform, "indicator,show,effect", "elm");
164
165         if(ad->indicator_type == SDL_INDICATOR_TRANSPARENT || ad->rotation % 180)
166                 start_hide_timer(ad);
167 }
168
169 Eina_Bool handler_server_data(void *data, int ev_type EINA_UNUSED, void *ev)
170 {
171         appdata_s *ad = (appdata_s *)data;
172         IPC_HEAD(ad, Data);
173         Ecore_Ipc_Event_Server_Data* epcEvent = (Ecore_Ipc_Event_Server_Data*)ev;
174
175         switch(epcEvent->major)
176         {
177         case OP_INDICATOR_SHOW:
178         {
179                 if(!ad->isShowing)
180                         return EINA_TRUE;
181                 _INFO("[SDL] 1. call event OP_INDICATOR_SHOW");
182
183                 resetTimer(ad);
184
185                 ad->rotation = epcEvent->minor;
186                 ad->parent_res_id = epcEvent->ref;
187
188                 if(epcEvent->ref_to!=0)
189                 {
190                         ad->indicator_type = epcEvent->ref_to;
191                         setIndicatorOpacity(ad, ad->indicator_type);
192                 }
193
194                 showIndicator(ad);
195
196                 _tizen_set_transient_for(ad, ad->indicator_res_id, ad->parent_res_id);
197                 ecore_ipc_server_send(ad->IpcServer, OP_INDICATOR_SHOW, 0, 0, 0, 0, NULL, 0);
198
199         break;
200         }
201         case OP_RESUME:
202         {
203                 ad->timer_hide_window = ecore_timer_add(0.5, ecore_timer_cb_hide_window, ad);
204                 ad->isShowing = 1;
205         break;
206         }
207         case OP_PAUSE:
208         {
209                 ad->isShowing = 0;
210         break;
211         }
212         case OP_TERMINATE:
213         {
214                 ecore_ipc_server_send(ad->IpcServer, OP_TERMINATE, 0, 0, 0, 0, NULL, 0);
215                 ui_app_exit();
216         break;
217         }
218         }
219
220         return EINA_TRUE;
221 }
222
223 void create_ipcServer(appdata_s *ad)
224 {
225         ecore_ipc_init();
226         Ecore_Event_Handler *h;
227         if((ad->IpcServer = ecore_ipc_server_connect(ECORE_IPC_LOCAL_USER, ECORE_IPC_INDICATOR, 0, NULL)))
228         {
229                 h = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, handler_server_add, ad);
230                 eina_array_push(mEcoreEventHandler, h);
231                 h = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, handler_server_del, NULL);
232                 eina_array_push(mEcoreEventHandler, h);
233                 h = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, handler_server_data, ad);
234                 eina_array_push(mEcoreEventHandler, h);
235         }
236         else
237         {
238                 _INFO("[SDL] Failed IPC Server\n");
239                 ui_app_exit();
240         }
241 }
242
243 Evas_Object *
244 elm_win_create(const char *name)
245 {
246         Evas_Object *win = elm_win_add(NULL, name, ELM_WIN_UTILITY);
247
248         elm_win_autodel_set(win, EINA_TRUE);
249         elm_win_alpha_set(win, EINA_TRUE);
250         elm_win_conformant_set(win, EINA_TRUE);
251
252         if (elm_win_wm_rotation_supported_get(win)) {
253                 int rots[4] = { 0, 90, 180, 270 };
254                 elm_win_wm_rotation_available_rotations_set(win, (const int *)(&rots), 4);
255         }
256
257         evas_object_show(win);
258         elm_win_prop_focus_skip_set(win, EINA_TRUE);
259         return win;
260 }
261
262 Evas_Object *
263 elm_conformand_create(Evas_Object *parent)
264 {
265         Evas_Object* conform = elm_conformant_add(parent);
266         evas_object_size_hint_align_set(conform,  EVAS_HINT_FILL, EVAS_HINT_FILL);
267         evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
268         elm_win_resize_object_add(parent, conform);
269         elm_win_indicator_mode_set(parent, ELM_WIN_INDICATOR_SHOW);
270         elm_win_indicator_opacity_set(parent, ELM_WIN_INDICATOR_TRANSPARENT);
271         evas_object_show(conform);
272         return conform;
273 }
274
275 static void
276 win_delete_request_cb(void *data, Evas_Object *obj, void *event_info)
277 {
278         ui_app_exit();
279 }
280
281 static Eina_Bool _window_show_cb(void *data, int type, void *event)
282 {
283         appdata_s *ad = data;
284     Ecore_Wl2_Event_Window_Show *e;
285
286         uint32_t g_res_id = -1;
287
288         e = event;
289         if (e->data[0] > 0)
290                 g_res_id = e->data[0];
291
292         dlog_print(DLOG_INFO, LOG_TAG, "[SDL]Window resource Id : %d", g_res_id);
293
294         if(g_res_id!=0)
295                 ad->indicator_res_id = g_res_id;
296
297         return ECORE_CALLBACK_PASS_ON;
298 }
299
300 void init_info(appdata_s *ad)
301 {
302         int width=0;
303         int height=0;
304         elm_win_screen_size_get(ad->win, 0, 0, &width, &height);
305
306         int h;
307         edje_object_part_geometry_get(elm_layout_edje_get(ad->conform), "indicator_base", NULL, NULL, NULL, &(h));
308         ad->indicator_h = h;
309         evas_object_resize(ad->win, width, ad->indicator_h);
310
311         dlog_print(DLOG_INFO, LOG_TAG, "[SDL]indicator size : %d", ad->indicator_h);
312         for(int i=0; i<4; i++)
313                 info_position[i][0] = info_position[i][1] = 0;
314         info_position[2][1] = height - ad->indicator_h;
315         info_position[3][0] = width - ad->indicator_h;
316
317         for(int i=0; i<4; i++)
318         {
319                 if((i*90)%180)
320                 {
321                         info_size[i][0] = height;
322                         info_size[i][1] = ad->indicator_h;
323                 }
324                 else
325                 {
326                         info_size[i][0] = width;
327                         info_size[i][1] = ad->indicator_h;
328                 }
329         }
330 }
331
332 static void
333 create_base_gui(appdata_s *ad)
334 {
335         Ecore_Event_Handler *h;
336         h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_SHOW, _window_show_cb, ad);
337         eina_array_push(mEcoreEventHandler, h);
338
339         ad->win = (Evas_Object *)elm_win_create("SDL_Indicator");
340         evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);
341         ad->conform = (Evas_Object *)elm_conformand_create(ad->win);
342         init_info(ad);
343 }
344
345 static bool
346 app_create(void *data)
347 {
348         /* Hook to take necessary actions before main event loop starts
349                 Initialize UI resources and application's data
350                 If this function returns true, the main loop of application starts
351                 If this function returns false, the application is terminated */
352         appdata_s *ad = data;
353
354         create_base_gui(ad);
355         create_ipcServer(ad);
356
357         return true;
358 }
359
360 static void
361 app_control(app_control_h app_control, void *data)
362 {
363         /* Handle the launch request. */
364 }
365
366 static void
367 app_pause(void *data)
368 {
369         /* Take necessary actions when application becomes invisible. */
370 }
371
372 static void
373 app_resume(void *data)
374 {
375         /* Take necessary actions when application becomes visible. */
376 }
377
378 static void
379 app_terminate(void *data)
380 {
381         /* Release all resources. */
382 }
383
384 static void
385 ui_app_lang_changed(app_event_info_h event_info, void *user_data)
386 {
387         /*APP_EVENT_LANGUAGE_CHANGED*/
388
389         int ret;
390         char *language;
391
392         ret = app_event_get_language(event_info, &language);
393         if (ret != APP_ERROR_NONE) {
394                 dlog_print(DLOG_ERROR, LOG_TAG, "app_event_get_language() failed. Err = %d.", ret);
395                 return;
396         }
397
398         if (language != NULL) {
399                 elm_language_set(language);
400                 free(language);
401         }
402 }
403
404 static void
405 ui_app_orient_changed(app_event_info_h event_info, void *user_data)
406 {
407         /*APP_EVENT_DEVICE_ORIENTATION_CHANGED*/
408         return;
409 }
410
411 static void
412 ui_app_region_changed(app_event_info_h event_info, void *user_data)
413 {
414         /*APP_EVENT_REGION_FORMAT_CHANGED*/
415 }
416
417 static void
418 ui_app_low_battery(app_event_info_h event_info, void *user_data)
419 {
420         /*APP_EVENT_LOW_BATTERY*/
421 }
422
423 static void
424 ui_app_low_memory(app_event_info_h event_info, void *user_data)
425 {
426         /*APP_EVENT_LOW_MEMORY*/
427 }
428
429 int
430 main(int argc, char *argv[])
431 {
432         mEcoreEventHandler = eina_array_new(2);
433         appdata_s ad = {0,};
434         ad.indicator_type = SDL_INDICATOR_TRANSPARENT;
435         int ret = 0;
436
437         ui_app_lifecycle_callback_s event_callback = {0,};
438         app_event_handler_h handlers[5] = {NULL, };
439
440         event_callback.create = app_create;
441         event_callback.terminate = app_terminate;
442         event_callback.pause = app_pause;
443         event_callback.resume = app_resume;
444         event_callback.app_control = app_control;
445
446
447         ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad);
448         ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad);
449         ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad);
450         ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad);
451         ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
452
453         ret = ui_app_main(argc, argv, &event_callback, &ad);
454         if (ret != APP_ERROR_NONE) {
455                 dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret);
456         }
457
458         if (mEcoreEventHandler)
459         {
460                 while (eina_array_count(mEcoreEventHandler))
461                         ecore_event_handler_del(eina_array_pop(mEcoreEventHandler));
462                 eina_array_free(mEcoreEventHandler);
463         }
464         return ret;
465 }