Change the sequence of last updated pixmap
[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 <dynamicbox_errno.h>
25 #include <dynamicbox_service.h>
26
27 #include "dynamicbox.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 dynamicbox_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 dynamicbox_buffer *handler, struct dynamicbox_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 DBOX_BUFFER_EVENT_ENTER:
82             evas_event_feed_mouse_in(info->e, event_info->timestamp * 1000, NULL);
83             break;
84         case DBOX_BUFFER_EVENT_LEAVE:
85             evas_event_feed_mouse_out(info->e, event_info->timestamp * 1000, NULL);
86             break;
87         case DBOX_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 DBOX_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 DBOX_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 DBOX_BUFFER_EVENT_ACCESS_HIGHLIGHT:
107             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
108             if (!parent_elm) {
109                 ret = DBOX_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 = DBOX_ACCESS_STATUS_ERROR;
125                 } else {
126                     LOGD("Highlighted object is found\n");
127                     ret = DBOX_ACCESS_STATUS_DONE;
128                 }
129             } else {
130                 LOGE("Action error\n");
131                 ret = DBOX_ACCESS_STATUS_ERROR;
132             }
133             break;
134         case DBOX_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
135             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
136             if (!parent_elm) {
137                 ret = DBOX_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) ? DBOX_ACCESS_STATUS_LAST : DBOX_ACCESS_STATUS_DONE;
145             break;
146         case DBOX_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
147             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
148             if (!parent_elm) {
149                 ret = DBOX_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) ? DBOX_ACCESS_STATUS_FIRST : DBOX_ACCESS_STATUS_DONE;
157             break;
158         case DBOX_BUFFER_EVENT_ACCESS_ACTIVATE:
159             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
160             if (!parent_elm) {
161                 ret = DBOX_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) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
168             break;
169         case DBOX_BUFFER_EVENT_ACCESS_ACTION_UP:
170             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
171             if (!parent_elm) {
172                 ret = DBOX_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) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
179             break;
180         case DBOX_BUFFER_EVENT_ACCESS_ACTION_DOWN:
181             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
182             if (!parent_elm) {
183                 ret = DBOX_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) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
190             break;
191         case DBOX_BUFFER_EVENT_ACCESS_SCROLL_UP:
192             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
193             if (!parent_elm) {
194                 ret = DBOX_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) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
204             break;
205         case DBOX_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
206             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
207             if (!parent_elm) {
208                 ret = DBOX_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) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
218             break;
219         case DBOX_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
220             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
221             if (!parent_elm) {
222                 ret = DBOX_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) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
232             break;
233         case DBOX_BUFFER_EVENT_ACCESS_UNHIGHLIGHT:
234             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
235             if (!parent_elm) {
236                 ret = DBOX_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) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
243             break;
244         case DBOX_BUFFER_EVENT_KEY_DOWN:
245             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
246             if (!parent_elm) {
247                 ret = DBOX_ACCESS_STATUS_ERROR;
248                 break;
249             }
250
251             ret = DBOX_KEY_STATUS_ERROR;
252             break;
253         case DBOX_BUFFER_EVENT_KEY_UP:
254             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
255             if (!parent_elm) {
256                 ret = DBOX_ACCESS_STATUS_ERROR;
257                 break;
258             }
259
260             ret = DBOX_KEY_STATUS_ERROR;
261             break;
262         case DBOX_BUFFER_EVENT_KEY_FOCUS_IN:
263             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
264             if (!parent_elm) {
265                 ret = DBOX_ACCESS_STATUS_ERROR;
266                 break;
267             }
268
269             ret = DBOX_KEY_STATUS_ERROR;
270             break;
271         case DBOX_BUFFER_EVENT_KEY_FOCUS_OUT:
272             parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
273             if (!parent_elm) {
274                 ret = DBOX_ACCESS_STATUS_ERROR;
275                 break;
276             }
277
278             ret = DBOX_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 = dynamicbox_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 (dynamicbox_support_hw_buffer(info->handle)) {
314         if (dynamicbox_create_hw_buffer(info->handle) == 0) {
315             buffer = dynamicbox_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 = dynamicbox_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 (dynamicbox_destroy_hw_buffer(info->handle) == 0) {
345             LOGD("HW Accelerated buffer is destroyed\n");
346             goto out;
347         }
348     }
349
350     dynamicbox_unref_buffer(ptr);
351     LOGD("SW buffer is destroyed\n");
352 out:
353     dynamicbox_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         dynamicbox_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         dynamicbox_buffer_post_render(info->handle);
380     } else {
381         dynamicbox_sync_buffer(info->handle);
382     }
383 }
384
385 PUBLIC void *dynamicbox_get_evas_object(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     rect = evas_object_rectangle_add(info->e);
438     if (!rect) {
439         ErrPrint("Failed to create evas_object\n");
440         ecore_evas_free(info->ee);
441         return NULL;
442     }
443
444     evas_object_resize(rect, 1, 1);
445     evas_object_color_set(rect, 0, 0, 0, 0);
446     return rect;
447 }
448
449 /* End of a file */