widget_get_evas_object -> widget_get_evas
[apps/native/widget/widget.git] / src / virtual_window_wayland.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.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 #include <Elementary.h>
18 #include <string.h>
19 #include <Ecore_Evas.h>
20 #include <Ecore_X.h>
21 #include <Evas.h>
22
23 #include <dlog.h>
24 #include <widget_errno.h>
25 #include <widget_service.h>
26
27 #include "widget.h"
28 #include "debug.h"
29
30 #define IS_PD 1
31
32 #define PUBLIC __attribute__((visibility("default")))
33
34 /*!
35  * \brief
36  * Abstracted Data Type of Virtual Window
37  */
38 struct info {
39         char *id; /*!< Identification */
40         struct widget_buffer *handle; /*!< Livebox buffer handle */
41         int is_hw; /*!< 1 if a buffer is created on the H/W accelerated place or 0 */
42         Ecore_Evas *ee;
43         Evas *e;
44         int is_gbar;
45 };
46
47 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
48 {
49         Evas_Object *o, *ho;
50
51         o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
52         if (!o) return NULL;
53
54         ho = evas_object_data_get(o, "_elm_access_target");
55         return ho;
56 }
57
58 /*!
59  * \note
60  * Every user event (mouse) on the buffer will be passed via this event callback
61  */
62 static int event_handler_cb(struct widget_buffer *handler, struct widget_buffer_event_data *event_info, void *data)
63 {
64         struct info *info = data;
65         Elm_Access_Action_Info action_info;
66         Elm_Access_Action_Type action_type;
67         int ret = 0;
68         Evas_Object *parent_elm;
69
70
71         if (!info->handle) {
72                 /* Just ignore this event */
73                 return 0;
74         }
75
76         /*!
77          * \note
78          * Feed up events
79          */
80         switch (event_info->type) {
81         case WIDGET_BUFFER_EVENT_ENTER:
82                 evas_event_feed_mouse_in(info->e, event_info->timestamp * 1000, NULL);
83                 break;
84         case WIDGET_BUFFER_EVENT_LEAVE:
85                 evas_event_feed_mouse_out(info->e, event_info->timestamp * 1000, NULL);
86                 break;
87         case WIDGET_BUFFER_EVENT_DOWN:
88                 /*!
89                  * \note
90                  * Calculate the event occurred X & Y on the buffer
91                  */
92                 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, (event_info->timestamp - 0.001f) * 1000, NULL); /* + 0.1f just for fake event */
93                 evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, event_info->timestamp * 1000, NULL); /* + 0.2f just for fake event */
94                 break;
95         case WIDGET_BUFFER_EVENT_MOVE:
96                 /*!
97                  * \note
98                  * Calculate the event occurred X & Y on the buffer
99                  */
100                 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
101                 break;
102         case WIDGET_BUFFER_EVENT_UP:
103                 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
104                 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, (event_info->timestamp + 0.001f) * 1000, NULL);
105                 break;
106         case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT:
107                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
108                 if (!parent_elm) {
109                         ret = WIDGET_ACCESS_STATUS_ERROR;
110                         break;
111                 }
112                 memset(&action_info, 0, sizeof(action_info));
113                 action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
114                 /*!
115                  * \note
116                  * Calculate the event occurred X & Y on the buffer
117                  */
118                 action_info.x = event_info->info.pointer.x;
119                 action_info.y = event_info->info.pointer.y;
120                 ret = elm_access_action(parent_elm, action_type, &action_info);
121                 if (ret == EINA_TRUE) {
122                         if (!get_highlighted_object(parent_elm)) {
123                                 LOGE("Highlighted object is not found\n");
124                                 ret = WIDGET_ACCESS_STATUS_ERROR;
125                         } else {
126                                 LOGD("Highlighted object is found\n");
127                                 ret = WIDGET_ACCESS_STATUS_DONE;
128                         }
129                 } else {
130                         LOGE("Action error\n");
131                         ret = WIDGET_ACCESS_STATUS_ERROR;
132                 }
133                 break;
134         case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
135                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
136                 if (!parent_elm) {
137                         ret = WIDGET_ACCESS_STATUS_ERROR;
138                         break;
139                 }
140                 memset(&action_info, 0, sizeof(action_info));
141                 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
142                 action_info.highlight_cycle = EINA_FALSE;
143                 ret = elm_access_action(parent_elm, action_type, &action_info);
144                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_LAST : WIDGET_ACCESS_STATUS_DONE;
145                 break;
146         case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
147                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
148                 if (!parent_elm) {
149                         ret = WIDGET_ACCESS_STATUS_ERROR;
150                         break;
151                 }
152                 memset(&action_info, 0, sizeof(action_info));
153                 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
154                 action_info.highlight_cycle = EINA_FALSE;
155                 ret = elm_access_action(parent_elm, action_type, &action_info);
156                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_FIRST : WIDGET_ACCESS_STATUS_DONE;
157                 break;
158         case WIDGET_BUFFER_EVENT_ACCESS_ACTIVATE:
159                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
160                 if (!parent_elm) {
161                         ret = WIDGET_ACCESS_STATUS_ERROR;
162                         break;
163                 }
164                 memset(&action_info, 0, sizeof(action_info));
165                 action_type = ELM_ACCESS_ACTION_ACTIVATE;
166                 ret = elm_access_action(parent_elm, action_type, &action_info);
167                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
168                 break;
169         case WIDGET_BUFFER_EVENT_ACCESS_ACTION_UP:
170                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
171                 if (!parent_elm) {
172                         ret = WIDGET_ACCESS_STATUS_ERROR;
173                         break;
174                 }
175                 memset(&action_info, 0, sizeof(action_info));
176                 action_type = ELM_ACCESS_ACTION_UP;
177                 ret = elm_access_action(parent_elm, action_type, &action_info);
178                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
179                 break;
180         case WIDGET_BUFFER_EVENT_ACCESS_ACTION_DOWN:
181                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
182                 if (!parent_elm) {
183                         ret = WIDGET_ACCESS_STATUS_ERROR;
184                         break;
185                 }
186                 memset(&action_info, 0, sizeof(action_info));
187                 action_type = ELM_ACCESS_ACTION_DOWN;
188                 ret = elm_access_action(parent_elm, action_type, &action_info);
189                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
190                 break;
191         case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_UP:
192                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
193                 if (!parent_elm) {
194                         ret = WIDGET_ACCESS_STATUS_ERROR;
195                         break;
196                 }
197                 memset(&action_info, 0, sizeof(action_info));
198                 action_type = ELM_ACCESS_ACTION_SCROLL;
199                 action_info.x = event_info->info.pointer.x;
200                 action_info.y = event_info->info.pointer.y;
201                 action_info.mouse_type = 2;
202                 ret = elm_access_action(parent_elm, action_type, &action_info);
203                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
204                 break;
205         case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
206                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
207                 if (!parent_elm) {
208                         ret = WIDGET_ACCESS_STATUS_ERROR;
209                         break;
210                 }
211                 memset(&action_info, 0, sizeof(action_info));
212                 action_type = ELM_ACCESS_ACTION_SCROLL;
213                 action_info.x = event_info->info.pointer.x;
214                 action_info.y = event_info->info.pointer.y;
215                 action_info.mouse_type = 1;
216                 ret = elm_access_action(parent_elm, action_type, &action_info);
217                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
218                 break;
219         case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
220                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
221                 if (!parent_elm) {
222                         ret = WIDGET_ACCESS_STATUS_ERROR;
223                         break;
224                 }
225                 memset(&action_info, 0, sizeof(action_info));
226                 action_type = ELM_ACCESS_ACTION_SCROLL;
227                 action_info.x = event_info->info.pointer.x;
228                 action_info.y = event_info->info.pointer.y;
229                 action_info.mouse_type = 0;
230                 ret = elm_access_action(parent_elm, action_type, &action_info);
231                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
232                 break;
233         case WIDGET_BUFFER_EVENT_ACCESS_UNHIGHLIGHT:
234                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
235                 if (!parent_elm) {
236                         ret = WIDGET_ACCESS_STATUS_ERROR;
237                         break;
238                 }
239                 memset(&action_info, 0, sizeof(action_info));
240                 action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
241                 ret = elm_access_action(parent_elm, action_type, &action_info);
242                 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
243                 break;
244         case WIDGET_BUFFER_EVENT_KEY_DOWN:
245                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
246                 if (!parent_elm) {
247                         ret = WIDGET_ACCESS_STATUS_ERROR;
248                         break;
249                 }
250
251                 ret = WIDGET_KEY_STATUS_ERROR;
252                 break;
253         case WIDGET_BUFFER_EVENT_KEY_UP:
254                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
255                 if (!parent_elm) {
256                         ret = WIDGET_ACCESS_STATUS_ERROR;
257                         break;
258                 }
259
260                 ret = WIDGET_KEY_STATUS_ERROR;
261                 break;
262         case WIDGET_BUFFER_EVENT_KEY_FOCUS_IN:
263                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
264                 if (!parent_elm) {
265                         ret = WIDGET_ACCESS_STATUS_ERROR;
266                         break;
267                 }
268
269                 ret = WIDGET_KEY_STATUS_ERROR;
270                 break;
271         case WIDGET_BUFFER_EVENT_KEY_FOCUS_OUT:
272                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
273                 if (!parent_elm) {
274                         ret = WIDGET_ACCESS_STATUS_ERROR;
275                         break;
276                 }
277
278                 ret = WIDGET_KEY_STATUS_ERROR;
279                 break;
280         default:
281                 LOGD("Unhandled buffer event (%d)\n", event_info->type);
282                 break;
283         }
284
285         return ret;
286 }
287
288 static void *alloc_fb(void *data, int size)
289 {
290         struct info *info = data;
291         void *buffer;
292         int width = 0;
293         int height = 0;
294
295         if (info->ee == NULL) {
296                 width = 1;
297                 height = 1;
298         } else {
299                 ecore_evas_geometry_get(info->ee, NULL, NULL, &width, &height);
300         }
301
302         /*!
303          * Acquire a buffer for canvas.
304          */
305         info->handle = widget_viewer_acquire_buffer(info->id, info->is_gbar,
306                         width, height,
307                         event_handler_cb, info);
308
309         /*!
310          * If it supports the H/W accelerated buffer,
311          * Use it.
312          */
313         if (widget_support_hw_buffer(info->handle)) {
314                 if (widget_create_hw_buffer(info->handle) == 0) {
315                         buffer = widget_buffer_hw_buffer(info->handle);
316                         if (buffer) {
317                                 LOGD("HW Accelerated buffer is created\n");
318                                 info->is_hw = 1;
319                                 return buffer;
320                         }
321                 }
322
323                 LOGE("Failed to allocate HW Accelerated buffer\n");
324         }
325
326         /*!
327          * Or use the buffer of a S/W backend.
328          */
329         buffer = widget_ref_buffer(info->handle);
330         LOGD("SW buffer is created\n");
331         info->is_hw = 0;
332         return buffer;
333 }
334
335 static void free_fb(void *data, void *ptr)
336 {
337         struct info *info = data;
338
339         if (!info->handle) {
340                 return;
341         }
342
343         if (info->is_hw) {
344                 if (widget_destroy_hw_buffer(info->handle) == 0) {
345                         LOGD("HW Accelerated buffer is destroyed\n");
346                         goto out;
347                 }
348         }
349
350         widget_unref_buffer(ptr);
351         LOGD("SW buffer is destroyed\n");
352 out:
353         widget_viewer_release_buffer(info->handle);
354         info->handle = NULL;
355 }
356
357 static void pre_render_cb(void *data, Evas *e, void *event_info)
358 {
359         struct info *info = data;
360
361         if (!info->handle) {
362                 return;
363         }
364
365         if (info->is_hw) {
366                 widget_buffer_pre_render(info->handle);
367         }
368 }
369
370 static void post_render_cb(void *data, Evas *e, void *event_info)
371 {
372         struct info *info = data;
373
374         if (!info->handle) {
375                 return;
376         }
377
378         if (info->is_hw) {
379                 widget_buffer_post_render(info->handle);
380         } else {
381                 widget_viewer_sync_buffer(info->handle);
382         }
383 }
384
385 PUBLIC void *widget_get_evas(const char *id, int is_gbar)
386 {
387         struct info *info;
388         Evas_Object *rect;
389
390         if (!id) {
391                 ErrPrint("Invalid parameter\n");
392                 return NULL;
393         }
394
395         info = calloc(1, sizeof(*info));
396         if (!info) {
397                 ErrPrint("Heap: %s\n", strerror(errno));
398                 return NULL;
399         }
400
401         info->id = strdup(id);
402         if (!info->id) {
403                 ErrPrint("Heap: %s\n", strerror(errno));
404                 free(info);
405                 return NULL;
406         }
407
408         info->is_gbar = is_gbar;
409
410         info->ee = ecore_evas_buffer_allocfunc_new(1, 1, alloc_fb, free_fb, info);
411         if (!info->ee) {
412                 ErrPrint("Failed to create ecore_evas (%dx%d)\n", 1, 1);
413                 free(info->id);
414                 free(info);
415                 return NULL;
416         }
417
418         pre_render_cb(info, NULL, NULL);
419         ecore_evas_alpha_set(info->ee, EINA_TRUE);
420         post_render_cb(info, NULL, NULL);
421
422         ecore_evas_data_set(info->ee, "dynamic,box,info", info);
423
424         ecore_evas_manual_render_set(info->ee, EINA_FALSE);
425         ecore_evas_resize(info->ee, 1, 1);
426
427         info->e = ecore_evas_get(info->ee);
428         if (!info->e) {
429                 ErrPrint("Failed to get evas\n");
430                 ecore_evas_free(info->ee);
431                 return NULL;
432         }
433
434         evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
435         evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
436
437         return info->e;
438 }
439
440 /* End of a file */