1 #include <Elementary.h>
2 #include <Ecore_Evas.h>
6 #include <livebox-errno.h>
12 #define PUBLIC __attribute__((visibility("default")))
15 * Abstracted Data Type of Virtual Window
18 char *id; /*!< Identification */
19 int width; /*!< Width */
20 int height; /*!< Height */
21 struct livebox_buffer *handle; /*!< Livebox buffer handle */
22 Evas_Object *window; /*!< Parent evas object - WARN: Incompatible with the elm_win object */
23 int is_hw; /*!< 1 if a buffer is created on the H/W accelerated place or 0 */
25 Evas_Object *elm_parent;
30 * Every user event (mouse) on the buffer will be passed via this event callback
32 static int event_handler_cb(struct livebox_buffer *handler, enum buffer_event evt, double timestamp, double x, double y, void *data)
34 Elm_Access_Action_Info *info;
35 Elm_Access_Action_Type action;
36 struct info *info = data;
42 /* Just ignore this event */
48 * Calculate the event occurred X & Y on the buffer
51 iy = info->height * y;
53 e = evas_object_evas_get(info->window);
60 case BUFFER_EVENT_ENTER:
61 evas_event_feed_mouse_in(e, timestamp, NULL);
63 case BUFFER_EVENT_LEAVE:
64 evas_event_feed_mouse_out(e, timestamp, NULL);
66 case BUFFER_EVENT_DOWN:
67 evas_event_feed_mouse_in(e, timestamp, NULL);
68 evas_event_feed_mouse_move(e, ix, iy, timestamp + 0.01f, NULL); /* + 0.1f just for fake event */
69 evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, timestamp + 0.02f, NULL); /* + 0.2f just for fake event */
71 case BUFFER_EVENT_MOVE:
72 evas_event_feed_mouse_move(e, ix, iy, timestamp, NULL);
75 evas_event_feed_mouse_up(e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
76 evas_event_feed_mouse_out(e, timestamp + 0.01f, NULL); /* + 0.1f just for fake event */
78 case BUFFER_EVENT_HIGHLIGHT:
79 if (!info->elm_parent)
80 return LB_ACCESS_STATUS_ERROR;
82 action = ELM_ACCESS_ACTION_HIGHLIGHT;
85 ret = elm_access_action(info->elm_parent, action, info);
86 DbgPrint("ACCESS_HIGHLIGHT: %dx%d returns %d\n", x, y, ret);
87 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
89 case BUFFER_EVENT_HIGHLIGHT_NEXT:
90 if (!info->elm_parent)
91 return LB_ACCESS_STATUS_ERROR;
92 action = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
93 info->highlight_cycle = EINA_FALSE;
94 ret = elm_access_action(info->elm_parent, action, info);
95 DbgPrint("ACCESS_HIGHLIGHT_NEXT, returns %d\n", ret);
96 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_LAST : LB_ACCESS_STATUS_DONE;
98 case BUFFER_EVENT_HIGHLIGHT_PREV:
99 if (!info->elm_parent)
100 return LB_ACCESS_STATUS_ERROR;
101 action = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
102 info->highlight_cycle = EINA_FALSE;
103 ret = elm_access_action(info->elm_parent, action, info);
104 DbgPrint("ACCESS_HIGHLIGHT_PREV, returns %d\n", ret);
105 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_FIRST : LB_ACCESS_STATUS_DONE;
107 case BUFFER_EVENT_ACTIVATE:
108 if (!info->elm_parent)
109 return LB_ACCESS_STATUS_ERROR;
110 action = ELM_ACCESS_ACTION_ACTIVATE;
111 ret = elm_access_action(info->elm_parent, action, info);
112 DbgPrint("ACCESS_ACTIVATE, returns %d\n", ret);
113 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
115 case BUFFER_EVENT_ACTION_UP:
116 if (!info->elm_parent)
117 return LB_ACCESS_STATUS_ERROR;
118 action = ELM_ACCESS_ACTION_UP;
119 ret = elm_access_action(info->elm_parent, action, info);
120 DbgPrint("ACCESS_ACTION(%d), returns %d\n", down, ret);
122 case BUFFER_EVENT_ACTION_DOWN:
123 if (!info->elm_parent)
124 return LB_ACCESS_STATUS_ERROR;
125 action = ELM_ACCESS_ACTION_DOWN;
126 ret = elm_access_action(info->elm_parent, action, info);
127 DbgPrint("ACCESS_ACTION(%d), returns %d\n", down, ret);
128 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
130 case BUFFER_EVENT_SCROLL_UP:
131 if (!info->elm_parent)
132 return LB_ACCESS_STATUS_ERROR;
133 action = ELM_ACCESS_ACTION_SCROLL;
136 info->mouse_type = 0;
137 ret = elm_access_action(info->elm_parent, action, info);
138 DbgPrint("ACCESS_HIGHLIGHT_SCROLL, returns %d\n", ret);
139 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
141 case BUFFER_EVENT_SCROLL_MOVE:
142 if (!info->elm_parent)
143 return LB_ACCESS_STATUS_ERROR;
144 action = ELM_ACCESS_ACTION_SCROLL;
147 info->mouse_type = -1;
148 ret = elm_access_action(info->elm_parent, action, info);
149 DbgPrint("ACCESS_HIGHLIGHT_SCROLL, returns %d\n", ret);
150 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
152 case BUFFER_EVENT_SCROLL_DOWN:
153 if (!info->elm_parent)
154 return LB_ACCESS_STATUS_ERROR;
155 action = ELM_ACCESS_ACTION_SCROLL;
158 info->mouse_type = 1;
159 ret = elm_access_action(info->elm_parent, action, info);
160 DbgPrint("ACCESS_HIGHLIGHT_SCROLL, returns %d\n", ret);
161 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
163 case BUFFER_EVENT_UNHIGHLIGHT:
164 if (!info->elm_parent)
165 return LB_ACCESS_STATUS_ERROR;
166 action = ELM_ACCESS_ACTION_UNHIGHLIGHT;
167 ret = elm_access_action(info->elm_parent, action, info);
168 DbgPrint("ACCESS_UNHIGHLIGHT, returns %d\n", ret);
169 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
172 LOGD("Unhandled buffer event (%d)\n", evt);
179 static void *alloc_fb(void *data, int size)
181 struct info *info = data;
185 * Acquire a buffer for canvas.
187 info->handle = livebox_acquire_buffer(info->id, IS_PD,
188 info->width, info->height,
189 event_handler_cb, info);
192 * If it supports the H/W accelerated buffer,
195 if (livebox_support_hw_buffer(info->handle)) {
196 if (livebox_create_hw_buffer(info->handle) == 0) {
197 buffer = livebox_buffer_hw_buffer(info->handle);
199 LOGD("HW Accelerated buffer is created\n");
205 LOGE("Failed to allocate HW Accelerated buffer\n");
209 * Or use the buffer of a S/W backend.
211 buffer = livebox_ref_buffer(info->handle);
212 LOGD("SW buffer is created\n");
217 static void free_fb(void *data, void *ptr)
219 struct info *info = data;
225 if (livebox_destroy_hw_buffer(info->handle) == 0) {
226 LOGD("HW Accelerated buffer is destroyed\n");
231 livebox_unref_buffer(ptr);
232 LOGD("SW buffer is destroyed\n");
234 livebox_release_buffer(info->handle);
238 static void resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
240 struct info *info = data;
243 ee = ecore_evas_ecore_evas_get(e);
247 evas_object_geometry_get(obj, NULL, NULL, &info->width, &info->height);
248 LOGD("Resize to %dx%d\n", info->width, info->height);
250 * Box(parent object) is resized.
251 * Try to resize the canvas too.
253 ecore_evas_resize(ee, info->width, info->height);
257 * If a canvas is destroyed,
258 * Free all buffer of canvas.
260 static void del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
263 struct info *info = data;
265 evas_object_del(obj, "info");
267 ee = ecore_evas_ecore_evas_get(e);
271 LOGD("Try to release the ECORE_EVAS\n");
275 LOGD("ECORE_EVAS is released\n");
278 static void pre_render_cb(void *data, Evas *e, void *event_info)
280 struct info *info = data;
286 livebox_buffer_pre_render(info->handle);
289 static void post_render_cb(void *data, Evas *e, void *event_info)
291 struct info *info = data;
297 livebox_buffer_post_render(info->handle);
299 livebox_sync_buffer(info->handle);
302 PUBLIC Evas_Object *livebox_virtual_window_add(const char *id, int width, int height)
308 info = calloc(1, sizeof(*info));
313 info->id = strdup(id);
320 info->height = height;
322 ee = ecore_evas_buffer_allocfunc_new(width, height, alloc_fb, free_fb, info);
329 pre_render_cb(info, NULL, NULL);
330 ecore_evas_alpha_set(ee, EINA_TRUE);
331 post_render_cb(info, NULL, NULL);
333 ecore_evas_manual_render_set(ee, EINA_FALSE);
334 ecore_evas_resize(ee, width, height);
336 e = ecore_evas_get(ee);
342 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
343 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
345 info->window = evas_object_rectangle_add(e);
351 evas_object_resize(info->window, width, height);
352 evas_object_color_set(info->window, 0, 0, 0, 0);
353 evas_object_event_callback_add(info->window, EVAS_CALLBACK_DEL, del_cb, info);
354 evas_object_event_callback_add(info->window, EVAS_CALLBACK_RESIZE, resize_cb, info);
355 evas_object_data_set(info->window, "info", info);
360 PUBLIC int livebox_virtual_window_set_parent_elm(Evas_Object *win, Evas_Object *parent_elm)
363 info = evas_object_data_get(win, "info");
365 return LB_STATUS_ERROR_INVALID;
367 if (info->parent_elm)
368 DbgPrint("Parent object will be replaced: %p\n", info->parent_elm);
370 info->parent_elm = parent_elm;
374 PUBLIC int livebox_virtual_window_del(Evas_Object *virtual_win)
376 evas_object_del(virtual_win);
377 return LB_STATUS_SUCCESS;