1 #include <Elementary.h>
3 #include <Ecore_Evas.h>
7 #include <livebox-errno.h>
8 #include <livebox-service.h>
14 #define PUBLIC __attribute__((visibility("default")))
17 * Abstracted Data Type of Virtual Window
20 char *id; /*!< Identification */
21 int width; /*!< Width */
22 int height; /*!< Height */
23 struct livebox_buffer *handle; /*!< Livebox buffer handle */
24 Evas_Object *window; /*!< Parent evas object - WARN: Incompatible with the elm_win object */
25 int is_hw; /*!< 1 if a buffer is created on the H/W accelerated place or 0 */
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 struct info *info = data;
35 Elm_Access_Action_Info action_info;
36 Elm_Access_Action_Type action_type;
39 Evas_Object *parent_elm;
45 /* Just ignore this event */
51 * Calculate the event occurred X & Y on the buffer
54 iy = info->height * y;
56 memset(&action_info, 0, sizeof(action_info));
58 e = evas_object_evas_get(info->window);
59 ee = ecore_evas_ecore_evas_get(e);
60 parent_elm = ecore_evas_data_get(ee, "parent,elm");
67 case BUFFER_EVENT_ENTER:
68 evas_event_feed_mouse_in(e, timestamp, NULL);
70 case BUFFER_EVENT_LEAVE:
71 evas_event_feed_mouse_out(e, timestamp, NULL);
73 case BUFFER_EVENT_DOWN:
74 evas_event_feed_mouse_in(e, timestamp, NULL);
75 evas_event_feed_mouse_move(e, ix, iy, timestamp + 0.01f, NULL); /* + 0.1f just for fake event */
76 evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, timestamp + 0.02f, NULL); /* + 0.2f just for fake event */
78 case BUFFER_EVENT_MOVE:
79 evas_event_feed_mouse_move(e, ix, iy, timestamp, NULL);
82 evas_event_feed_mouse_up(e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
83 evas_event_feed_mouse_out(e, timestamp + 0.01f, NULL); /* + 0.1f just for fake event */
85 case BUFFER_EVENT_HIGHLIGHT:
87 ret = LB_ACCESS_STATUS_ERROR;
90 action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
93 ret = elm_access_action(parent_elm, action_type, &action_info);
94 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
96 case BUFFER_EVENT_HIGHLIGHT_NEXT:
98 ret = LB_ACCESS_STATUS_ERROR;
101 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
102 action_info.highlight_cycle = EINA_FALSE;
103 ret = elm_access_action(parent_elm, action_type, &action_info);
104 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_LAST : LB_ACCESS_STATUS_DONE;
106 case BUFFER_EVENT_HIGHLIGHT_PREV:
108 ret = LB_ACCESS_STATUS_ERROR;
111 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
112 action_info.highlight_cycle = EINA_FALSE;
113 ret = elm_access_action(parent_elm, action_type, &action_info);
114 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_FIRST : LB_ACCESS_STATUS_DONE;
116 case BUFFER_EVENT_ACTIVATE:
118 ret = LB_ACCESS_STATUS_ERROR;
121 action_type = ELM_ACCESS_ACTION_ACTIVATE;
122 ret = elm_access_action(parent_elm, action_type, &action_info);
123 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
125 case BUFFER_EVENT_ACTION_UP:
127 ret = LB_ACCESS_STATUS_ERROR;
130 action_type = ELM_ACCESS_ACTION_UP;
131 ret = elm_access_action(parent_elm, action_type, &action_info);
132 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
134 case BUFFER_EVENT_ACTION_DOWN:
136 ret = LB_ACCESS_STATUS_ERROR;
139 action_type = ELM_ACCESS_ACTION_DOWN;
140 ret = elm_access_action(parent_elm, action_type, &action_info);
141 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
143 case BUFFER_EVENT_SCROLL_UP:
145 ret = LB_ACCESS_STATUS_ERROR;
148 action_type = ELM_ACCESS_ACTION_SCROLL;
151 action_info.mouse_type = 0;
152 ret = elm_access_action(parent_elm, action_type, &action_info);
153 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
155 case BUFFER_EVENT_SCROLL_MOVE:
157 ret = LB_ACCESS_STATUS_ERROR;
162 action_info.mouse_type = 1;
163 ret = elm_access_action(parent_elm, action_type, &action_info);
164 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
166 case BUFFER_EVENT_SCROLL_DOWN:
168 ret = LB_ACCESS_STATUS_ERROR;
171 action_info.mouse_type = 2;
172 ret = elm_access_action(parent_elm, action_type, &action_info);
173 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
175 case BUFFER_EVENT_UNHIGHLIGHT:
177 ret = LB_ACCESS_STATUS_ERROR;
180 action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
181 ret = elm_access_action(parent_elm, action_type, &action_info);
182 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
185 LOGD("Unhandled buffer event (%d)\n", evt);
192 static void *alloc_fb(void *data, int size)
194 struct info *info = data;
198 * Acquire a buffer for canvas.
200 info->handle = livebox_acquire_buffer(info->id, IS_PD,
201 info->width, info->height,
202 event_handler_cb, info);
205 * If it supports the H/W accelerated buffer,
208 if (livebox_support_hw_buffer(info->handle)) {
209 if (livebox_create_hw_buffer(info->handle) == 0) {
210 buffer = livebox_buffer_hw_buffer(info->handle);
212 LOGD("HW Accelerated buffer is created\n");
218 LOGE("Failed to allocate HW Accelerated buffer\n");
222 * Or use the buffer of a S/W backend.
224 buffer = livebox_ref_buffer(info->handle);
225 LOGD("SW buffer is created\n");
230 static void free_fb(void *data, void *ptr)
232 struct info *info = data;
238 if (livebox_destroy_hw_buffer(info->handle) == 0) {
239 LOGD("HW Accelerated buffer is destroyed\n");
244 livebox_unref_buffer(ptr);
245 LOGD("SW buffer is destroyed\n");
247 livebox_release_buffer(info->handle);
251 static void resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
253 struct info *info = data;
256 ee = ecore_evas_ecore_evas_get(e);
260 evas_object_geometry_get(obj, NULL, NULL, &info->width, &info->height);
261 LOGD("Resize to %dx%d\n", info->width, info->height);
263 * Box(parent object) is resized.
264 * Try to resize the canvas too.
266 ecore_evas_resize(ee, info->width, info->height);
270 * If a canvas is destroyed,
271 * Free all buffer of canvas.
273 static void del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
276 struct info *info = data;
278 ee = ecore_evas_ecore_evas_get(e);
287 static void pre_render_cb(void *data, Evas *e, void *event_info)
289 struct info *info = data;
295 livebox_buffer_pre_render(info->handle);
298 static void post_render_cb(void *data, Evas *e, void *event_info)
300 struct info *info = data;
306 livebox_buffer_post_render(info->handle);
308 livebox_sync_buffer(info->handle);
311 PUBLIC Evas_Object *virtual_window_create(const char *id, int width, int height)
317 info = calloc(1, sizeof(*info));
322 info->id = strdup(id);
329 info->height = height;
331 ee = ecore_evas_buffer_allocfunc_new(width, height, alloc_fb, free_fb, info);
338 pre_render_cb(info, NULL, NULL);
339 ecore_evas_alpha_set(ee, EINA_TRUE);
340 post_render_cb(info, NULL, NULL);
342 ecore_evas_manual_render_set(ee, EINA_FALSE);
343 ecore_evas_resize(ee, width, height);
345 e = ecore_evas_get(ee);
351 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
352 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
354 info->window = evas_object_rectangle_add(e);
360 evas_object_resize(info->window, width, height);
361 evas_object_color_set(info->window, 0, 0, 0, 0);
362 evas_object_event_callback_add(info->window, EVAS_CALLBACK_DEL, del_cb, info);
363 evas_object_event_callback_add(info->window, EVAS_CALLBACK_RESIZE, resize_cb, info);
368 PUBLIC int virtual_window_set_parent_elm(Evas_Object *win, Evas_Object *parent)
374 return LB_STATUS_ERROR_INVALID;
376 e = evas_object_evas_get(win);
378 return LB_STATUS_ERROR_FAULT;
380 ee = ecore_evas_ecore_evas_get(e);
382 return LB_STATUS_ERROR_FAULT;
384 ecore_evas_data_set(ee, "parent,elm", parent);