1 #include <Elementary.h>
3 #include <Ecore_Evas.h>
7 #include <livebox-errno.h>
8 #include <livebox-service.h>
15 #define PUBLIC __attribute__((visibility("default")))
18 * Abstracted Data Type of Virtual Window
21 char *id; /*!< Identification */
22 int width; /*!< Width */
23 int height; /*!< Height */
24 struct livebox_buffer *handle; /*!< Livebox buffer handle */
25 Evas_Object *window; /*!< Parent evas object - WARN: Incompatible with the elm_win object */
26 int is_hw; /*!< 1 if a buffer is created on the H/W accelerated place or 0 */
29 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
33 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
36 ho = evas_object_data_get(o, "_elm_access_target");
42 * Every user event (mouse) on the buffer will be passed via this event callback
44 static int event_handler_cb(struct livebox_buffer *handler, struct buffer_event_data *event_info, void *data)
46 struct info *info = data;
47 Elm_Access_Action_Info action_info;
48 Elm_Access_Action_Type action_type;
51 Evas_Object *parent_elm;
55 /* Just ignore this event */
59 e = evas_object_evas_get(info->window);
61 memset(&action_info, 0, sizeof(action_info));
67 switch (event_info->type) {
68 case BUFFER_EVENT_ENTER:
69 evas_event_feed_mouse_in(e, event_info->timestamp * 1000, NULL);
71 case BUFFER_EVENT_LEAVE:
72 evas_event_feed_mouse_out(e, event_info->timestamp * 1000, NULL);
74 case BUFFER_EVENT_DOWN:
77 * Calculate the event occurred X & Y on the buffer
79 evas_event_feed_mouse_in(e, (event_info->timestamp - 0.002f) * 1000, NULL);
80 evas_event_feed_mouse_move(e, info->width * event_info->info.pointer.x, info->height * event_info->info.pointer.y, (event_info->timestamp - 0.001f) * 1000, NULL); /* + 0.1f just for fake event */
81 evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, event_info->timestamp * 1000, NULL); /* + 0.2f just for fake event */
83 case BUFFER_EVENT_MOVE:
86 * Calculate the event occurred X & Y on the buffer
88 evas_event_feed_mouse_move(e, info->width * event_info->info.pointer.x, info->height * event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
91 evas_event_feed_mouse_up(e, 1, EVAS_BUTTON_NONE, event_info->timestamp * 1000, NULL);
92 evas_event_feed_mouse_out(e, (event_info->timestamp + 0.001f) * 1000, NULL); /* + 0.1f just for fake event */
94 case BUFFER_EVENT_HIGHLIGHT:
95 ee = ecore_evas_ecore_evas_get(e);
96 parent_elm = ecore_evas_data_get(ee, "parent,elm");
98 ret = LB_ACCESS_STATUS_ERROR;
101 action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
104 * Calculate the event occurred X & Y on the buffer
106 action_info.x = info->width * event_info->info.pointer.x;
107 action_info.y = info->height * event_info->info.pointer.y;
108 ret = elm_access_action(parent_elm, action_type, &action_info);
109 if (ret == EINA_TRUE) {
110 if (!get_highlighted_object(parent_elm)) {
111 LOGE("Highlighted object is not found\n");
112 ret = LB_ACCESS_STATUS_ERROR;
114 LOGD("Highlighted object is found\n");
115 ret = LB_ACCESS_STATUS_DONE;
118 LOGE("Action error\n");
119 ret = LB_ACCESS_STATUS_ERROR;
122 case BUFFER_EVENT_HIGHLIGHT_NEXT:
123 ee = ecore_evas_ecore_evas_get(e);
124 parent_elm = ecore_evas_data_get(ee, "parent,elm");
126 ret = LB_ACCESS_STATUS_ERROR;
129 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
130 action_info.highlight_cycle = EINA_FALSE;
131 ret = elm_access_action(parent_elm, action_type, &action_info);
132 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_LAST : LB_ACCESS_STATUS_DONE;
134 case BUFFER_EVENT_HIGHLIGHT_PREV:
135 ee = ecore_evas_ecore_evas_get(e);
136 parent_elm = ecore_evas_data_get(ee, "parent,elm");
138 ret = LB_ACCESS_STATUS_ERROR;
141 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
142 action_info.highlight_cycle = EINA_FALSE;
143 ret = elm_access_action(parent_elm, action_type, &action_info);
144 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_FIRST : LB_ACCESS_STATUS_DONE;
146 case BUFFER_EVENT_ACTIVATE:
147 ee = ecore_evas_ecore_evas_get(e);
148 parent_elm = ecore_evas_data_get(ee, "parent,elm");
150 ret = LB_ACCESS_STATUS_ERROR;
153 action_type = ELM_ACCESS_ACTION_ACTIVATE;
154 ret = elm_access_action(parent_elm, action_type, &action_info);
155 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
157 case BUFFER_EVENT_ACTION_UP:
158 ee = ecore_evas_ecore_evas_get(e);
159 parent_elm = ecore_evas_data_get(ee, "parent,elm");
161 ret = LB_ACCESS_STATUS_ERROR;
164 action_type = ELM_ACCESS_ACTION_UP;
165 ret = elm_access_action(parent_elm, action_type, &action_info);
166 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
168 case BUFFER_EVENT_ACTION_DOWN:
169 ee = ecore_evas_ecore_evas_get(e);
170 parent_elm = ecore_evas_data_get(ee, "parent,elm");
172 ret = LB_ACCESS_STATUS_ERROR;
175 action_type = ELM_ACCESS_ACTION_DOWN;
176 ret = elm_access_action(parent_elm, action_type, &action_info);
177 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
179 case BUFFER_EVENT_SCROLL_UP:
180 ee = ecore_evas_ecore_evas_get(e);
181 parent_elm = ecore_evas_data_get(ee, "parent,elm");
183 ret = LB_ACCESS_STATUS_ERROR;
186 action_type = ELM_ACCESS_ACTION_SCROLL;
187 action_info.x = info->width * event_info->info.pointer.x;
188 action_info.y = info->height * event_info->info.pointer.y;
189 action_info.mouse_type = 2;
190 ret = elm_access_action(parent_elm, action_type, &action_info);
191 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
193 case BUFFER_EVENT_SCROLL_MOVE:
194 ee = ecore_evas_ecore_evas_get(e);
195 parent_elm = ecore_evas_data_get(ee, "parent,elm");
197 ret = LB_ACCESS_STATUS_ERROR;
200 action_type = ELM_ACCESS_ACTION_SCROLL;
201 action_info.x = info->width * event_info->info.pointer.x;
202 action_info.y = info->height * event_info->info.pointer.y;
203 action_info.mouse_type = 1;
204 ret = elm_access_action(parent_elm, action_type, &action_info);
205 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
207 case BUFFER_EVENT_SCROLL_DOWN:
208 ee = ecore_evas_ecore_evas_get(e);
209 parent_elm = ecore_evas_data_get(ee, "parent,elm");
211 ret = LB_ACCESS_STATUS_ERROR;
214 action_type = ELM_ACCESS_ACTION_SCROLL;
215 action_info.x = info->width * event_info->info.pointer.x;
216 action_info.y = info->height * event_info->info.pointer.y;
217 action_info.mouse_type = 0;
218 ret = elm_access_action(parent_elm, action_type, &action_info);
219 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
221 case BUFFER_EVENT_UNHIGHLIGHT:
222 ee = ecore_evas_ecore_evas_get(e);
223 parent_elm = ecore_evas_data_get(ee, "parent,elm");
225 ret = LB_ACCESS_STATUS_ERROR;
228 action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
229 ret = elm_access_action(parent_elm, action_type, &action_info);
230 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
232 case BUFFER_EVENT_KEY_DOWN:
233 ret = LB_KEY_STATUS_ERROR;
235 case BUFFER_EVENT_KEY_UP:
236 ret = LB_KEY_STATUS_ERROR;
238 case BUFFER_EVENT_KEY_FOCUS_IN:
239 ret = LB_KEY_STATUS_ERROR;
241 case BUFFER_EVENT_KEY_FOCUS_OUT:
242 ret = LB_KEY_STATUS_ERROR;
245 LOGD("Unhandled buffer event (%d)\n", event_info->type);
252 static void *alloc_fb(void *data, int size)
254 struct info *info = data;
258 * Acquire a buffer for canvas.
260 info->handle = livebox_acquire_buffer(info->id, IS_PD,
261 info->width, info->height,
262 event_handler_cb, info);
265 * If it supports the H/W accelerated buffer,
268 if (livebox_support_hw_buffer(info->handle)) {
269 if (livebox_create_hw_buffer(info->handle) == 0) {
270 buffer = livebox_buffer_hw_buffer(info->handle);
272 LOGD("HW Accelerated buffer is created\n");
278 LOGE("Failed to allocate HW Accelerated buffer\n");
282 * Or use the buffer of a S/W backend.
284 buffer = livebox_ref_buffer(info->handle);
285 LOGD("SW buffer is created\n");
290 static void free_fb(void *data, void *ptr)
292 struct info *info = data;
299 if (livebox_destroy_hw_buffer(info->handle) == 0) {
300 LOGD("HW Accelerated buffer is destroyed\n");
305 livebox_unref_buffer(ptr);
306 LOGD("SW buffer is destroyed\n");
308 livebox_release_buffer(info->handle);
312 static void resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
314 struct info *info = data;
317 ee = ecore_evas_ecore_evas_get(e);
322 evas_object_geometry_get(obj, NULL, NULL, &info->width, &info->height);
323 SECURE_LOGD("Resize to %dx%d\n", info->width, info->height);
325 * Box(parent object) is resized.
326 * Try to resize the canvas too.
328 ecore_evas_resize(ee, info->width, info->height);
332 * If a canvas is destroyed,
333 * Free all buffer of canvas.
335 static void del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
338 struct info *info = data;
340 ee = ecore_evas_ecore_evas_get(e);
350 static void pre_render_cb(void *data, Evas *e, void *event_info)
352 struct info *info = data;
359 livebox_buffer_pre_render(info->handle);
363 static void post_render_cb(void *data, Evas *e, void *event_info)
365 struct info *info = data;
372 livebox_buffer_post_render(info->handle);
374 livebox_sync_buffer(info->handle);
378 PUBLIC Evas_Object *livebox_get_evas_object(const char *id, int width, int height)
384 info = calloc(1, sizeof(*info));
386 ErrPrint("Heap: %s\n", strerror(errno));
390 info->id = strdup(id);
392 ErrPrint("Heap: %s\n", strerror(errno));
398 info->height = height;
400 ee = ecore_evas_buffer_allocfunc_new(width, height, alloc_fb, free_fb, info);
402 ErrPrint("Failed to create ecore_evas (%dx%d)\n", width, height);
408 pre_render_cb(info, NULL, NULL);
409 ecore_evas_alpha_set(ee, EINA_TRUE);
410 post_render_cb(info, NULL, NULL);
412 ecore_evas_manual_render_set(ee, EINA_FALSE);
413 ecore_evas_resize(ee, width, height);
415 e = ecore_evas_get(ee);
417 ErrPrint("Failed to get evas\n");
422 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
423 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
425 info->window = evas_object_rectangle_add(e);
427 ErrPrint("Failed to create evas_object\n");
432 evas_object_resize(info->window, width, height);
433 evas_object_color_set(info->window, 0, 0, 0, 0);
434 evas_object_event_callback_add(info->window, EVAS_CALLBACK_DEL, del_cb, info);
435 evas_object_event_callback_add(info->window, EVAS_CALLBACK_RESIZE, resize_cb, info);
440 PUBLIC int livebox_set_elm_window(Evas_Object *lb_evas_object, Evas_Object *window)
445 if (!lb_evas_object) {
446 return LB_STATUS_ERROR_INVALID;
449 e = evas_object_evas_get(lb_evas_object);
451 return LB_STATUS_ERROR_FAULT;
454 ee = ecore_evas_ecore_evas_get(e);
456 return LB_STATUS_ERROR_FAULT;
459 ecore_evas_data_set(ee, "parent,elm", window);