53e8bd4383e51eb71c2bb2e60617b7804891bc8f
[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 #define NUM_ECORE_EVENT_HANDLERS 4
28 #define EFL_BETA_API_SUPPORT
29
30 #include <Ecore_Wl2.h>
31 #include <Ecore_Input.h>
32 #include <PUI.h>
33
34 #define debug_error(msg, ...)                                                                                   \
35         do {                                                                                                                            \
36                 fprintf(stderr, "[ERROR][%s] " msg, __FUNCTION__, ##__VA_ARGS__);       \
37         } while(0)
38
39 #define debug_info(msg, ...)                                                                                            \
40         do {                                                                                                                            \
41                 fprintf(stdout, "[INFO][%s] " msg, __FUNCTION__, ##__VA_ARGS__);        \
42         } while(0)
43
44 typedef struct _animation animation_t;
45 struct _animation
46 {
47         pui_id id;
48         pui_ani_cmd cmd;
49         int repeat;
50 };
51
52 typedef struct app_data app_data_t;
53 struct app_data
54 {
55         pui_h ph;
56         pui_ani_h ani_h;
57
58         Ecore_Wl2_Display *ewd;
59         Ecore_Wl2_Window *win;
60 };
61
62 static Eina_Array *_ecore_event_hdls = NULL;
63 static animation_t ani_collection[] = {
64         { "alarm calm", PUI_ANI_CMD_START, 1 },
65         { "bixby listening", PUI_ANI_CMD_START, -1 },
66         { "bixby speaking", PUI_ANI_CMD_START, -1 },
67         { "bixby_error", PUI_ANI_CMD_START, 1 },
68         { "blinking", PUI_ANI_CMD_START, -1 },
69         { "notification", PUI_ANI_CMD_START, -1 },
70 };
71
72 static void
73 ani_stop(app_data_t *app)
74 {
75         pui_error e = PUI_ERROR_NONE;
76
77         debug_info("Animation(%s) will be stopped !\n", pui_ani_get_id(app->ani_h));
78
79         /* stop animation running already */
80         e = pui_ani_control(app->ani_h, PUI_ANI_CMD_STOP, 0);
81
82         if (PUI_ERROR_NONE != e)
83         {
84                 debug_error("Failed on stopping an animation !(cmd:%d, repeat:%d)\n", PUI_ANI_CMD_STOP, 0);
85                 return;
86         }
87 }
88
89 static void
90 ani_collection_play(app_data_t *app)
91 {
92         static int ani_idx = 0;
93         int n_animation = 0;
94         pui_ani_h ani_h = NULL;
95         pui_error e = PUI_ERROR_NONE;
96
97         n_animation = sizeof(ani_collection) / sizeof(animation_t);
98
99         if (n_animation < 0)
100         {
101                 debug_error("No animation is available ! (n_animation=%d)\n", n_animation);
102                 return;
103         }
104
105         if (!app->ph)
106         {
107                 debug_error("Invalid pui_h handle !\n");
108                 return;
109         }
110
111         if (app->ani_h)
112         {
113                 /* stop animation running already */
114                 ani_stop(app);
115                 pui_ani_destroy(app->ani_h);
116                 app->ani_h = NULL;
117         }
118
119         ani_h = pui_ani_create(app->ph, ani_collection[ani_idx].id);
120
121         if (!ani_h)
122         {
123                 debug_error("Failed to create new PUI animation handle !\n");
124
125                 if (++ani_idx >= n_animation)
126                         ani_idx = 0;
127
128                 return;
129         }
130
131         app->ani_h = ani_h;
132
133         debug_info("Animation(%s) will be started !\n", pui_ani_get_id(app->ani_h));
134
135         /* play animation */
136         e = pui_ani_control(app->ani_h, PUI_ANI_CMD_START, ani_collection[ani_idx].repeat);
137
138         if (PUI_ERROR_NONE != e)
139         {
140                 debug_error("Failed on playing an animation ! (cmd:%d, repeat:%d)\n", PUI_ANI_CMD_START, ani_collection[ani_idx].repeat);
141                 return;
142         }
143
144         if (++ani_idx >= n_animation)
145                 ani_idx = 0;
146
147         return;
148 }
149
150 static Eina_Bool
151 _cb_key_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
152 {
153         app_data_t *app =  (app_data_t *)data;
154         Ecore_Event_Key *ev = event;
155
156         debug_info("KEY: name:%s, sym:%s, code:%d\n", ev->keyname, ev->key, ev->keycode);
157
158         ani_collection_play(app);
159
160         return ECORE_CALLBACK_PASS_ON;
161 }
162
163 static Eina_Bool
164 _cb_focus_in(void *data, int type EINA_UNUSED, void *event)
165 {
166         app_data_t *app =  (app_data_t *)data;
167         Ecore_Wl2_Event_Focus_In *ev = (Ecore_Wl2_Event_Focus_In *)event;
168
169         debug_info("\n");
170
171         /* TODO */
172         (void) app;
173         (void) ev;
174
175         return ECORE_CALLBACK_PASS_ON;
176 }
177
178 static Eina_Bool
179 _cb_focus_out(void *data, int type EINA_UNUSED, void *event)
180 {
181         app_data_t *app =  (app_data_t *)data;
182         Ecore_Wl2_Event_Focus_Out *ev = (Ecore_Wl2_Event_Focus_Out *)event;
183
184         debug_info("\n");
185
186         /* TODO */
187         (void) app;
188         (void) ev;
189
190         return ECORE_CALLBACK_PASS_ON;
191 }
192
193 static Eina_Bool
194 _cb_visibility_change(void *data, int type EINA_UNUSED, void *event)
195 {
196         app_data_t *app = (app_data_t *)data;
197         Ecore_Wl2_Event_Window_Visibility_Change *ev;
198
199         ev = event;
200
201         debug_info("Visibility change (window=0x%x, fully_obscured=%d)\n", ev->win, ev->fully_obscured);
202
203         if (ev->fully_obscured)
204         {
205                 debug_info("Loose LED control !\n");
206                 ani_stop(app);
207         }
208         else
209         {
210                 debug_info("Gain LED control !\n");
211                 ani_collection_play(app);
212         }
213
214         return ECORE_CALLBACK_PASS_ON;
215 }
216
217 static void
218 event_handlers_init(app_data_t *app)
219 {
220         Ecore_Event_Handler *h = NULL;
221         _ecore_event_hdls = eina_array_new(NUM_ECORE_EVENT_HANDLERS);
222
223         h = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _cb_key_up, app);
224         eina_array_push(_ecore_event_hdls, h);
225
226         h = ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_IN, _cb_focus_in, app);
227         eina_array_push(_ecore_event_hdls, h);
228
229         h = ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_OUT, _cb_focus_out, app);
230         eina_array_push(_ecore_event_hdls, h);
231
232         h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, _cb_visibility_change, app);
233         eina_array_push(_ecore_event_hdls, h);
234 }
235
236 int main()
237 {
238         app_data_t *app = NULL;
239         const char *socket_name = NULL;
240
241         if (!ecore_wl2_init())
242         {
243                 fprintf(stderr, "Failed to init ecore wl2 !\n");
244                 return EXIT_SUCCESS;
245         }
246
247         socket_name = getenv("WAYLAND_DISPLAY");
248
249         if (!socket_name)
250                 socket_name = "wayland-0";
251
252         app = (app_data_t *)calloc(1, sizeof(app_data_t));
253
254         if (!app)
255         {
256                 debug_error("Failed to allocate app data !\n");
257                 goto err;
258         }
259
260         app->ewd = ecore_wl2_display_connect(socket_name);
261
262         if (!app->ewd)
263         {
264                 debug_error("Failed to connect to display !\n");
265                 goto err;
266         }
267
268         app->win = ecore_wl2_window_new(app->ewd, NULL, 0, 0, 1, 1);
269
270         if (!app->win)
271         {
272                 debug_error("Failed to create a window !\n");
273                 goto err;
274         }
275
276         ecore_wl2_window_alpha_set(app->win, EINA_FALSE);
277         ecore_wl2_window_show(app->win);
278         ecore_wl2_window_commit(app->win, EINA_TRUE);
279         ecore_wl2_window_activate(app->win);
280
281         if (!pui_init())
282         {
283                 debug_error("Failed to init pui !\n");
284                 goto err;
285         }
286
287         app->ph = pui_create(app->win);
288
289         if (!app->ph)
290         {
291                 debug_error("Failed to create PUI handle !\n");
292                 goto err;
293         }
294
295         event_handlers_init(app);
296
297         ecore_main_loop_begin();
298 err:
299         if (app->ani_h)
300                 pui_ani_destroy(app->ani_h);
301         if (app->ph)
302                 pui_destroy(app->ph);
303
304         pui_shutdown();
305         ecore_wl2_shutdown();
306
307         return EXIT_SUCCESS;
308 }