a6b04d5e3e40ae9c39da62397bdc453a9f2d683e
[platform/core/uifw/libpui.git] / samples / PUI_sample.c
1 /*
2  * Copyright © 2019 Samsung Electronics co., Ltd. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial
14  * portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25
26 #include <stdio.h>
27 #include <unistd.h>
28
29 #define NUM_ECORE_EVENT_HANDLERS 7
30
31 /* pre-requisite to use ecore_wl2 APIs */
32 #define EFL_BETA_API_SUPPORT
33
34 #include <Ecore_Wl2.h>
35 #include <Ecore_Input.h>
36 #include <PUI.h>
37
38 int gpid;
39
40 #define debug_error(msg, ...)                                                                                   \
41         do {                                                                                                                            \
42                 fprintf(stderr, "[PUI sample][ERROR][PID:%d][%s] " msg, gpid, __FUNCTION__, ##__VA_ARGS__);     \
43         } while(0)
44
45 #define debug_info(msg, ...)                                                                                            \
46         do {                                                                                                                            \
47                 fprintf(stdout, "[PUI sample][INFO][PID:%d][%s] " msg, gpid, __FUNCTION__, ##__VA_ARGS__);      \
48         } while(0)
49
50 typedef struct _animation animation_t;
51 struct _animation
52 {
53         pui_id id;
54         pui_ani_cmd cmd;
55         int repeat;
56 };
57
58 typedef struct app_data app_data_t;
59 struct app_data
60 {
61         pui_h ph;
62         int ani_idx;
63         int n_animation;
64
65         Ecore_Wl2_Display *ewd;
66         Ecore_Wl2_Window *win;
67 };
68
69 static Eina_Array *_ecore_event_hdls = NULL;
70 static animation_t ani_collection[] = {
71         { "system/easy_setup", PUI_ANI_CMD_START, -1 },
72         { "system/processing", PUI_ANI_CMD_START, -1 },
73         { "system/sw_update_done", PUI_ANI_CMD_START, -1 },
74         { "system/mic_off", PUI_ANI_CMD_START, -1 },
75         { "voice/listening", PUI_ANI_CMD_START, -1 },
76         { "voice/streaming", PUI_ANI_CMD_START, -1 },
77         { "voice/processing", PUI_ANI_CMD_START, -1 },
78         { "voice/speaking", PUI_ANI_CMD_START, -1 },
79         { "voice/timeout", PUI_ANI_CMD_START, -1 },
80         { "notification/normal", PUI_ANI_CMD_START, -1 },
81         { "notification/emergency", PUI_ANI_CMD_START, -1 },
82         { "notification/network_error", PUI_ANI_CMD_START, -1 },
83         { "notification/error", PUI_ANI_CMD_START, -1 },
84         { "notification/alarm", PUI_ANI_CMD_START, -1 },
85         { "bt/pairing", PUI_ANI_CMD_START, -1 },
86         { "bt/connected", PUI_ANI_CMD_START, -1 }
87 };
88
89 pui_ani_h ani_handles[sizeof(ani_collection) / sizeof(animation_t)];
90
91 static void
92 ani_collection_play(app_data_t *app)
93 {
94         pui_error e = PUI_ERROR_NONE;
95         pui_ani_h ani_h = NULL;
96
97         if (!app->ph)
98         {
99                 debug_error("Invalid pui_h handle !\n");
100                 return;
101         }
102
103         while (!ani_handles[app->ani_idx])
104         {
105                 app->ani_idx++;
106
107                 if (++app->ani_idx >= app->n_animation)
108                         app->ani_idx = 0;
109         }
110
111         debug_info("Animation(%s) will be started !\n", pui_ani_get_id(ani_handles[app->ani_idx]));
112
113         /* play animation */
114         ani_h = ani_handles[app->ani_idx];
115         e = pui_ani_control(ani_h, PUI_ANI_CMD_START, ani_collection[app->ani_idx].repeat);
116
117         if (PUI_ERROR_NONE != e)
118         {
119                 debug_error("Failed on playing an animation ! (cmd:%d, repeat:%d)\n", PUI_ANI_CMD_START, ani_collection[app->ani_idx].repeat);
120                 return;
121         }
122
123         if (++app->ani_idx >= app->n_animation)
124                 app->ani_idx = 0;
125
126         return;
127 }
128
129 static Eina_Bool
130 _cb_key_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
131 {
132         app_data_t *app =  (app_data_t *)data;
133         Ecore_Event_Key *ev = event;
134
135         debug_info("KEY: name:%s, sym:%s, code:%d\n", ev->keyname, ev->key, ev->keycode);
136
137         ani_collection_play(app);
138
139         return ECORE_CALLBACK_PASS_ON;
140 }
141
142 static Eina_Bool
143 _cb_focus_in(void *data, int type EINA_UNUSED, void *event)
144 {
145         app_data_t *app =  (app_data_t *)data;
146         Ecore_Wl2_Event_Focus_In *ev = (Ecore_Wl2_Event_Focus_In *)event;
147
148         debug_info("\n");
149
150         /* TODO */
151         (void) app;
152         (void) ev;
153
154         return ECORE_CALLBACK_PASS_ON;
155 }
156
157 static Eina_Bool
158 _cb_focus_out(void *data, int type EINA_UNUSED, void *event)
159 {
160         app_data_t *app =  (app_data_t *)data;
161         Ecore_Wl2_Event_Focus_Out *ev = (Ecore_Wl2_Event_Focus_Out *)event;
162
163         debug_info("\n");
164
165         /* TODO */
166         (void) app;
167         (void) ev;
168
169         return ECORE_CALLBACK_PASS_ON;
170 }
171
172 static Eina_Bool
173 _cb_visibility_change(void *data, int type EINA_UNUSED, void *event)
174 {
175         app_data_t *app = (app_data_t *)data;
176         Ecore_Wl2_Event_Window_Visibility_Change *ev;
177
178         (void) app;
179         ev = event;
180         debug_info("Visibility change (window=0x%x, fully_obscured=%d)\n", ev->win, ev->fully_obscured);
181
182         return ECORE_CALLBACK_PASS_ON;
183 }
184
185 static Eina_Bool
186 _cb_ani_started(void *data, int type EINA_UNUSED, void *event)
187 {
188         app_data_t *app = (app_data_t *)data;
189         PUI_Event_Animation_Status *ev;
190
191         (void) app;
192         ev = event;
193         debug_info("[%s] ani id=%s, status=%d, window=0x%x\n", __FUNCTION__, pui_ani_get_id(ev->ani_h), ev->status, ev->win);
194
195         return ECORE_CALLBACK_PASS_ON;
196 }
197
198 static Eina_Bool
199 _cb_ani_stopped(void *data, int type EINA_UNUSED, void *event)
200 {
201         app_data_t *app = (app_data_t *)data;
202         PUI_Event_Animation_Status *ev;
203
204         (void) app;
205         ev = event;
206         debug_info("[%s] ani id=%s, status=%d, window=0x%x\n", __FUNCTION__, pui_ani_get_id(ev->ani_h), ev->status, ev->win);
207
208         /* decrease animation idx for starting from stopped animation */
209         //app->ani_idx--;
210
211         return ECORE_CALLBACK_PASS_ON;
212 }
213
214 static Eina_Bool
215 _cb_ani_ready_to_start(void *data, int type EINA_UNUSED, void *event)
216 {
217         app_data_t *app = (app_data_t *)data;
218         PUI_Event_Animation_Status *ev;
219
220         (void) app;
221         ev = event;
222         debug_info("[%s] ani id=%s, status=%d, window=0x%x\n", __FUNCTION__, pui_ani_get_id(ev->ani_h), ev->status, ev->win);
223
224         /* start animation */
225         ani_collection_play(app);
226
227         return ECORE_CALLBACK_PASS_ON;
228 }
229
230 static void
231 event_handlers_init(app_data_t *app)
232 {
233         Ecore_Event_Handler *h = NULL;
234         _ecore_event_hdls = eina_array_new(NUM_ECORE_EVENT_HANDLERS);
235
236         h = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _cb_key_up, app);
237         eina_array_push(_ecore_event_hdls, h);
238
239         h = ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_IN, _cb_focus_in, app);
240         eina_array_push(_ecore_event_hdls, h);
241
242         h = ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_OUT, _cb_focus_out, app);
243         eina_array_push(_ecore_event_hdls, h);
244
245         h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, _cb_visibility_change, app);
246         eina_array_push(_ecore_event_hdls, h);
247
248         h = ecore_event_handler_add(PUI_EVENT_ANI_STARTED, _cb_ani_started, app);
249         eina_array_push(_ecore_event_hdls, h);
250
251         h = ecore_event_handler_add(PUI_EVENT_ANI_STOPPED, _cb_ani_stopped, app);
252         eina_array_push(_ecore_event_hdls, h);
253
254         h = ecore_event_handler_add(PUI_EVENT_ANI_READY_TO_START, _cb_ani_ready_to_start, app);
255         eina_array_push(_ecore_event_hdls, h);
256 }
257
258 int main()
259 {
260         app_data_t *app = NULL;
261         const char *socket_name = NULL;
262
263         gpid = getpid();
264
265         if (!ecore_wl2_init())
266         {
267                 debug_error("Failed to init ecore wl2 !\n");
268                 return EXIT_SUCCESS;
269         }
270
271         socket_name = getenv("WAYLAND_DISPLAY");
272
273         if (!socket_name)
274                 socket_name = "wayland-0";
275
276         app = (app_data_t *)calloc(1, sizeof(app_data_t));
277
278         if (!app)
279         {
280                 debug_error("Failed to allocate app data !\n");
281                 goto err;
282         }
283
284         app->ani_idx = 0;
285         app->ewd = ecore_wl2_display_connect(socket_name);
286
287         if (!app->ewd)
288         {
289                 debug_error("Failed to connect to display !\n");
290                 goto err;
291         }
292
293         app->win = ecore_wl2_window_new(app->ewd, NULL, 0, 0, 1, 1);
294
295         if (!app->win)
296         {
297                 debug_error("Failed to create a window !\n");
298                 goto err;
299         }
300
301         ecore_wl2_window_alpha_set(app->win, EINA_FALSE);
302         ecore_wl2_window_show(app->win);
303         ecore_wl2_window_commit(app->win, EINA_TRUE);
304         ecore_wl2_window_activate(app->win);
305
306         if (!pui_init())
307         {
308                 debug_error("Failed to init pui !\n");
309                 goto err;
310         }
311
312         app->ph = pui_create(app->win);
313
314         if (!app->ph)
315         {
316                 debug_error("Failed to create PUI handle !\n");
317                 goto err;
318         }
319
320         app->n_animation = sizeof(ani_collection) / sizeof(animation_t);
321
322         for(int i=0;i<app->n_animation;i++)
323         {
324                 ani_handles[i] = pui_ani_create(app->ph, ani_collection[i].id);
325
326                 if (!ani_handles[i])
327                         debug_error("Failed to create pui ani handle !(id:%s)\n", ani_collection[i].id);
328         }
329
330         event_handlers_init(app);
331
332         ecore_main_loop_begin();
333 err:
334         if (app->n_animation > 0)
335         {
336                 for(int i=0;i<app->n_animation;i++)
337                 {
338                         pui_ani_destroy(ani_handles[i]);
339                 }
340         }
341
342         if (app->ph)
343                 pui_destroy(app->ph);
344
345         pui_shutdown();
346         ecore_wl2_shutdown();
347
348         return EXIT_SUCCESS;
349 }