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 */
28 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
32 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
35 ho = evas_object_data_get(o, "_elm_access_target");
41 * Every user event (mouse) on the buffer will be passed via this event callback
43 static int event_handler_cb(struct livebox_buffer *handler, enum buffer_event evt, double timestamp, double x, double y, void *data)
45 struct info *info = data;
46 Elm_Access_Action_Info action_info;
47 Elm_Access_Action_Type action_type;
50 Evas_Object *parent_elm;
56 /* Just ignore this event */
62 * Calculate the event occurred X & Y on the buffer
65 iy = info->height * y;
67 memset(&action_info, 0, sizeof(action_info));
69 e = evas_object_evas_get(info->window);
70 ee = ecore_evas_ecore_evas_get(e);
71 parent_elm = ecore_evas_data_get(ee, "parent,elm");
78 case BUFFER_EVENT_ENTER:
79 evas_event_feed_mouse_in(e, timestamp * 1000, NULL);
81 case BUFFER_EVENT_LEAVE:
82 evas_event_feed_mouse_out(e, timestamp * 1000, NULL);
84 case BUFFER_EVENT_DOWN:
85 evas_event_feed_mouse_in(e, (timestamp - 0.002f) * 1000, NULL);
86 evas_event_feed_mouse_move(e, ix, iy, (timestamp - 0.001f) * 1000, NULL); /* + 0.1f just for fake event */
87 evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, timestamp * 1000, NULL); /* + 0.2f just for fake event */
89 case BUFFER_EVENT_MOVE:
90 evas_event_feed_mouse_move(e, ix, iy, timestamp * 1000, NULL);
93 evas_event_feed_mouse_up(e, 1, EVAS_BUTTON_NONE, timestamp * 1000, NULL);
94 evas_event_feed_mouse_out(e, (timestamp + 0.001f) * 1000, NULL); /* + 0.1f just for fake event */
96 case BUFFER_EVENT_HIGHLIGHT:
98 ret = LB_ACCESS_STATUS_ERROR;
101 action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
104 ret = elm_access_action(parent_elm, action_type, &action_info);
105 if (ret == EINA_TRUE) {
106 if (!get_highlighted_object(parent_elm)) {
107 LOGE("Highlighted object is not found\n");
108 ret = LB_ACCESS_STATUS_ERROR;
110 LOGD("Highlighted object is found\n");
111 ret = LB_ACCESS_STATUS_DONE;
114 ErrPrint("Action error\n");
115 ret = LB_ACCESS_STATUS_ERROR;
118 case BUFFER_EVENT_HIGHLIGHT_NEXT:
120 ret = LB_ACCESS_STATUS_ERROR;
123 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
124 action_info.highlight_cycle = EINA_FALSE;
125 ret = elm_access_action(parent_elm, action_type, &action_info);
126 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_LAST : LB_ACCESS_STATUS_DONE;
128 case BUFFER_EVENT_HIGHLIGHT_PREV:
130 ret = LB_ACCESS_STATUS_ERROR;
133 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
134 action_info.highlight_cycle = EINA_FALSE;
135 ret = elm_access_action(parent_elm, action_type, &action_info);
136 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_FIRST : LB_ACCESS_STATUS_DONE;
138 case BUFFER_EVENT_ACTIVATE:
140 ret = LB_ACCESS_STATUS_ERROR;
143 action_type = ELM_ACCESS_ACTION_ACTIVATE;
144 ret = elm_access_action(parent_elm, action_type, &action_info);
145 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
147 case BUFFER_EVENT_ACTION_UP:
149 ret = LB_ACCESS_STATUS_ERROR;
152 action_type = ELM_ACCESS_ACTION_UP;
153 ret = elm_access_action(parent_elm, action_type, &action_info);
154 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
156 case BUFFER_EVENT_ACTION_DOWN:
158 ret = LB_ACCESS_STATUS_ERROR;
161 action_type = ELM_ACCESS_ACTION_DOWN;
162 ret = elm_access_action(parent_elm, action_type, &action_info);
163 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
165 case BUFFER_EVENT_SCROLL_UP:
167 ret = LB_ACCESS_STATUS_ERROR;
170 action_type = ELM_ACCESS_ACTION_SCROLL;
173 action_info.mouse_type = 2;
174 ret = elm_access_action(parent_elm, action_type, &action_info);
175 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
177 case BUFFER_EVENT_SCROLL_MOVE:
179 ret = LB_ACCESS_STATUS_ERROR;
182 action_type = ELM_ACCESS_ACTION_SCROLL;
185 action_info.mouse_type = 1;
186 ret = elm_access_action(parent_elm, action_type, &action_info);
187 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
189 case BUFFER_EVENT_SCROLL_DOWN:
191 ret = LB_ACCESS_STATUS_ERROR;
194 action_type = ELM_ACCESS_ACTION_SCROLL;
197 action_info.mouse_type = 0;
198 ret = elm_access_action(parent_elm, action_type, &action_info);
199 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
201 case BUFFER_EVENT_UNHIGHLIGHT:
203 ret = LB_ACCESS_STATUS_ERROR;
206 action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
207 ret = elm_access_action(parent_elm, action_type, &action_info);
208 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
211 LOGD("Unhandled buffer event (%d)\n", evt);
218 static void *alloc_fb(void *data, int size)
220 struct info *info = data;
224 * Acquire a buffer for canvas.
226 info->handle = livebox_acquire_buffer(info->id, IS_PD,
227 info->width, info->height,
228 event_handler_cb, info);
231 * If it supports the H/W accelerated buffer,
234 if (livebox_support_hw_buffer(info->handle)) {
235 if (livebox_create_hw_buffer(info->handle) == 0) {
236 buffer = livebox_buffer_hw_buffer(info->handle);
238 LOGD("HW Accelerated buffer is created\n");
244 LOGE("Failed to allocate HW Accelerated buffer\n");
248 * Or use the buffer of a S/W backend.
250 buffer = livebox_ref_buffer(info->handle);
251 LOGD("SW buffer is created\n");
256 static void free_fb(void *data, void *ptr)
258 struct info *info = data;
265 if (livebox_destroy_hw_buffer(info->handle) == 0) {
266 LOGD("HW Accelerated buffer is destroyed\n");
271 livebox_unref_buffer(ptr);
272 LOGD("SW buffer is destroyed\n");
274 livebox_release_buffer(info->handle);
278 static void resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
280 struct info *info = data;
283 ee = ecore_evas_ecore_evas_get(e);
288 evas_object_geometry_get(obj, NULL, NULL, &info->width, &info->height);
289 SECURE_LOGD("Resize to %dx%d\n", info->width, info->height);
291 * Box(parent object) is resized.
292 * Try to resize the canvas too.
294 ecore_evas_resize(ee, info->width, info->height);
298 * If a canvas is destroyed,
299 * Free all buffer of canvas.
301 static void del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
304 struct info *info = data;
306 ee = ecore_evas_ecore_evas_get(e);
316 static void pre_render_cb(void *data, Evas *e, void *event_info)
318 struct info *info = data;
325 livebox_buffer_pre_render(info->handle);
329 static void post_render_cb(void *data, Evas *e, void *event_info)
331 struct info *info = data;
338 livebox_buffer_post_render(info->handle);
340 livebox_sync_buffer(info->handle);
344 PUBLIC Evas_Object *virtual_window_create(const char *id, int width, int height)
350 info = calloc(1, sizeof(*info));
355 info->id = strdup(id);
362 info->height = height;
364 ee = ecore_evas_buffer_allocfunc_new(width, height, alloc_fb, free_fb, info);
371 pre_render_cb(info, NULL, NULL);
372 ecore_evas_alpha_set(ee, EINA_TRUE);
373 post_render_cb(info, NULL, NULL);
375 ecore_evas_manual_render_set(ee, EINA_FALSE);
376 ecore_evas_resize(ee, width, height);
378 e = ecore_evas_get(ee);
384 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
385 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
387 info->window = evas_object_rectangle_add(e);
393 evas_object_resize(info->window, width, height);
394 evas_object_color_set(info->window, 0, 0, 0, 0);
395 evas_object_event_callback_add(info->window, EVAS_CALLBACK_DEL, del_cb, info);
396 evas_object_event_callback_add(info->window, EVAS_CALLBACK_RESIZE, resize_cb, info);
401 PUBLIC int virtual_window_set_parent_elm(Evas_Object *win, Evas_Object *parent)
407 return LB_STATUS_ERROR_INVALID;
410 e = evas_object_evas_get(win);
412 return LB_STATUS_ERROR_FAULT;
415 ee = ecore_evas_ecore_evas_get(e);
417 return LB_STATUS_ERROR_FAULT;
420 ecore_evas_data_set(ee, "parent,elm", parent);