2 * Copyright 2013 Samsung Electronics Co., Ltd
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
8 * http://floralicense.org/license/
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.
19 #include <Elementary.h>
21 #include <Ecore_Evas.h>
29 #include <livebox-errno.h>
30 #include <livebox-service.h>
33 #include "livebox_product.h"
38 #define PUBLIC __attribute__((visibility("default")))
40 static struct static_info {
41 Ecore_Evas *(*alloc_canvas)(int w, int h, void *(*a)(void *data, int size), void (*f)(void *data, void *ptr), void *data);
42 Ecore_Evas *(*alloc_canvas_with_stride)(int w, int h, void *(*a)(void *data, int size, int *stride, int *bpp), void (*f)(void *data, void *ptr), void *data);
45 .alloc_canvas_with_stride = NULL,
50 * Abstracted Data Type of Virtual Window
53 char *id; /*!< Identification */
54 struct livebox_buffer *handle; /*!< Livebox buffer handle */
55 int is_hw; /*!< 1 if a buffer is created on the H/W accelerated place or 0 */
64 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
68 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
71 ho = evas_object_data_get(o, "_elm_access_target");
77 * Every user event (mouse) on the buffer will be passed via this event callback
79 static int event_handler_cb(struct livebox_buffer *handler, struct buffer_event_data *event_info, void *data)
81 struct info *info = data;
82 Elm_Access_Action_Info action_info;
83 Elm_Access_Action_Type action_type;
85 Evas_Object *parent_elm;
87 unsigned int flags = 0;
90 /* Just ignore this event */
98 switch (event_info->type) {
99 case BUFFER_EVENT_ON_HOLD:
100 DbgPrint("ON_HOLD\n");
101 flags = evas_event_default_flags_get(info->e);
102 flags |= EVAS_EVENT_FLAG_ON_HOLD;
103 evas_event_default_flags_set(info->e, flags);
105 case BUFFER_EVENT_OFF_HOLD:
106 flags = evas_event_default_flags_get(info->e);
107 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
108 evas_event_default_flags_set(info->e, flags);
110 case BUFFER_EVENT_ON_SCROLL:
111 flags = evas_event_default_flags_get(info->e);
112 flags |= EVAS_EVENT_FLAG_ON_SCROLL;
113 evas_event_default_flags_set(info->e, flags);
115 case BUFFER_EVENT_OFF_SCROLL:
116 flags = evas_event_default_flags_get(info->e);
117 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
118 evas_event_default_flags_set(info->e, flags);
120 case BUFFER_EVENT_ENTER:
121 evas_event_feed_mouse_in(info->e, event_info->timestamp * 1000, NULL);
123 case BUFFER_EVENT_LEAVE:
124 evas_event_feed_mouse_out(info->e, event_info->timestamp * 1000, NULL);
126 case BUFFER_EVENT_DOWN:
129 * Calculate the event occurred X & Y on the buffer
131 flags = evas_event_default_flags_get(info->e);
132 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
133 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
134 evas_event_default_flags_set(info->e, flags);
136 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
137 evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, event_info->timestamp * 1000, NULL); /* + 0.2f just for fake event */
139 case BUFFER_EVENT_MOVE:
142 * Calculate the event occurred X & Y on the buffer
144 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
146 case BUFFER_EVENT_UP:
147 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
148 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, event_info->timestamp * 1000, NULL);
150 case BUFFER_EVENT_HIGHLIGHT:
151 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
153 ret = LB_ACCESS_STATUS_ERROR;
156 memset(&action_info, 0, sizeof(action_info));
157 action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
160 * Calculate the event occurred X & Y on the buffer
162 action_info.x = event_info->info.access.x;
163 action_info.y = event_info->info.access.y;
164 ret = elm_access_action(parent_elm, action_type, &action_info);
165 if (ret == EINA_TRUE) {
166 if (!get_highlighted_object(parent_elm)) {
167 LOGE("Highlighted object is not found\n");
168 ret = LB_ACCESS_STATUS_ERROR;
170 LOGD("Highlighted object is found\n");
171 ret = LB_ACCESS_STATUS_DONE;
174 LOGE("Action error\n");
175 ret = LB_ACCESS_STATUS_ERROR;
178 case BUFFER_EVENT_HIGHLIGHT_NEXT:
179 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
181 ret = LB_ACCESS_STATUS_ERROR;
184 memset(&action_info, 0, sizeof(action_info));
185 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
186 action_info.highlight_cycle = EINA_FALSE;
187 ret = elm_access_action(parent_elm, action_type, &action_info);
188 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_LAST : LB_ACCESS_STATUS_DONE;
190 case BUFFER_EVENT_HIGHLIGHT_PREV:
191 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
193 ret = LB_ACCESS_STATUS_ERROR;
196 memset(&action_info, 0, sizeof(action_info));
197 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
198 action_info.highlight_cycle = EINA_FALSE;
199 ret = elm_access_action(parent_elm, action_type, &action_info);
200 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_FIRST : LB_ACCESS_STATUS_DONE;
202 case BUFFER_EVENT_ACTIVATE:
203 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
205 ret = LB_ACCESS_STATUS_ERROR;
208 memset(&action_info, 0, sizeof(action_info));
209 action_type = ELM_ACCESS_ACTION_ACTIVATE;
210 ret = elm_access_action(parent_elm, action_type, &action_info);
211 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
213 case BUFFER_EVENT_ACTION_UP:
214 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
216 ret = LB_ACCESS_STATUS_ERROR;
219 memset(&action_info, 0, sizeof(action_info));
220 action_type = ELM_ACCESS_ACTION_UP;
221 ret = elm_access_action(parent_elm, action_type, &action_info);
222 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
224 case BUFFER_EVENT_ACTION_DOWN:
225 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
227 ret = LB_ACCESS_STATUS_ERROR;
230 memset(&action_info, 0, sizeof(action_info));
231 action_type = ELM_ACCESS_ACTION_DOWN;
232 ret = elm_access_action(parent_elm, action_type, &action_info);
233 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
235 case BUFFER_EVENT_SCROLL_UP:
236 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
238 ret = LB_ACCESS_STATUS_ERROR;
241 memset(&action_info, 0, sizeof(action_info));
242 action_type = ELM_ACCESS_ACTION_SCROLL;
243 action_info.x = event_info->info.access.x;
244 action_info.y = event_info->info.access.y;
245 action_info.mouse_type = event_info->info.access.mouse_type;
246 ret = elm_access_action(parent_elm, action_type, &action_info);
247 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
249 case BUFFER_EVENT_SCROLL_MOVE:
250 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
252 ret = LB_ACCESS_STATUS_ERROR;
255 memset(&action_info, 0, sizeof(action_info));
256 action_type = ELM_ACCESS_ACTION_SCROLL;
257 action_info.x = event_info->info.access.x;
258 action_info.y = event_info->info.access.y;
259 action_info.mouse_type = event_info->info.access.mouse_type;
260 ret = elm_access_action(parent_elm, action_type, &action_info);
261 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
263 case BUFFER_EVENT_SCROLL_DOWN:
264 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
266 ret = LB_ACCESS_STATUS_ERROR;
269 memset(&action_info, 0, sizeof(action_info));
270 action_type = ELM_ACCESS_ACTION_SCROLL;
271 action_info.x = event_info->info.access.x;
272 action_info.y = event_info->info.access.y;
273 action_info.mouse_type = event_info->info.access.mouse_type;
274 ret = elm_access_action(parent_elm, action_type, &action_info);
275 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
277 case BUFFER_EVENT_UNHIGHLIGHT:
278 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
280 ret = LB_ACCESS_STATUS_ERROR;
283 memset(&action_info, 0, sizeof(action_info));
284 action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
285 ret = elm_access_action(parent_elm, action_type, &action_info);
286 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
288 case BUFFER_EVENT_VALUE_CHANGE:
289 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
291 ret = LB_ACCESS_STATUS_ERROR;
294 memset(&action_info, 0, sizeof(action_info));
295 action_type = ELM_ACCESS_ACTION_VALUE_CHANGE;
296 action_info.x = event_info->info.access.x;
297 action_info.y = event_info->info.access.y;
298 action_info.mouse_type = event_info->info.access.mouse_type;
299 ret = elm_access_action(parent_elm, action_type, &action_info);
300 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
302 case BUFFER_EVENT_MOUSE:
303 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
305 ret = LB_ACCESS_STATUS_ERROR;
308 memset(&action_info, 0, sizeof(action_info));
309 action_type = ELM_ACCESS_ACTION_MOUSE;
310 action_info.x = event_info->info.access.x;
311 action_info.y = event_info->info.access.y;
312 action_info.mouse_type = event_info->info.access.mouse_type;
313 ret = elm_access_action(parent_elm, action_type, &action_info);
314 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
316 case BUFFER_EVENT_BACK:
317 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
319 ret = LB_ACCESS_STATUS_ERROR;
322 memset(&action_info, 0, sizeof(action_info));
323 action_type = ELM_ACCESS_ACTION_BACK;
324 action_info.x = event_info->info.access.x;
325 action_info.y = event_info->info.access.y;
326 action_info.mouse_type = event_info->info.access.mouse_type;
327 ret = elm_access_action(parent_elm, action_type, &action_info);
328 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
330 case BUFFER_EVENT_OVER:
331 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
333 ret = LB_ACCESS_STATUS_ERROR;
336 memset(&action_info, 0, sizeof(action_info));
337 action_type = ELM_ACCESS_ACTION_OVER;
338 action_info.x = event_info->info.access.x;
339 action_info.y = event_info->info.access.y;
340 action_info.mouse_type = event_info->info.access.mouse_type;
341 ret = elm_access_action(parent_elm, action_type, &action_info);
342 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
344 case BUFFER_EVENT_READ:
345 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
347 ret = LB_ACCESS_STATUS_ERROR;
350 memset(&action_info, 0, sizeof(action_info));
351 action_type = ELM_ACCESS_ACTION_READ;
352 action_info.x = event_info->info.access.x;
353 action_info.y = event_info->info.access.y;
354 action_info.mouse_type = event_info->info.access.mouse_type;
355 ret = elm_access_action(parent_elm, action_type, &action_info);
356 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
358 case BUFFER_EVENT_ENABLE:
359 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
361 ret = LB_ACCESS_STATUS_ERROR;
364 memset(&action_info, 0, sizeof(action_info));
365 action_type = ELM_ACCESS_ACTION_ENABLE;
366 action_info.x = event_info->info.access.x;
367 action_info.y = event_info->info.access.y;
368 action_info.mouse_type = event_info->info.access.mouse_type;
369 ret = elm_access_action(parent_elm, action_type, &action_info);
370 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
372 case BUFFER_EVENT_DISABLE:
373 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
375 ret = LB_ACCESS_STATUS_ERROR;
378 memset(&action_info, 0, sizeof(action_info));
379 action_type = ELM_ACCESS_ACTION_DISABLE;
380 action_info.x = event_info->info.access.x;
381 action_info.y = event_info->info.access.y;
382 action_info.mouse_type = event_info->info.access.mouse_type;
383 ret = elm_access_action(parent_elm, action_type, &action_info);
384 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
386 case BUFFER_EVENT_KEY_DOWN:
387 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
389 ret = LB_ACCESS_STATUS_ERROR;
393 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
398 key_string = XKeysymToString(*key_symbol);
399 key_name = XKeysymToString(*key_symbol);
400 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
405 ret = LB_KEY_STATUS_ERROR;
407 case BUFFER_EVENT_KEY_UP:
408 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
410 ret = LB_ACCESS_STATUS_ERROR;
414 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
419 key_string = XKeysymToString(*key_symbol);
420 key_name = XKeysymToString(*key_symbol);
421 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
426 ret = LB_KEY_STATUS_ERROR;
428 case BUFFER_EVENT_KEY_FOCUS_IN:
429 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
431 ret = LB_ACCESS_STATUS_ERROR;
435 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
440 key_string = XKeysymToString(*key_symbol);
441 key_name = XKeysymToString(*key_symbol);
442 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
447 ret = LB_KEY_STATUS_ERROR;
449 case BUFFER_EVENT_KEY_FOCUS_OUT:
450 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
452 ret = LB_ACCESS_STATUS_ERROR;
456 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
461 key_string = XKeysymToString(*key_symbol);
462 key_name = XKeysymToString(*key_symbol);
463 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
468 ret = LB_KEY_STATUS_ERROR;
471 LOGD("Unhandled buffer event (%d)\n", event_info->type);
478 static void *alloc_fb(void *data, int size)
480 struct info *info = data;
484 ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
485 LOGD("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
489 * Acquire a buffer for canvas.
491 info->handle = livebox_acquire_buffer(info->id, info->is_pd,
492 info->w, info->h, sizeof(int), (livebox_conf_auto_align() || !s_info.alloc_canvas_with_stride),
493 event_handler_cb, info);
496 * If it supports the H/W accelerated buffer,
499 if (livebox_support_hw_buffer(info->handle)) {
500 if (livebox_create_hw_buffer(info->handle) == 0) {
501 buffer = livebox_buffer_hw_buffer(info->handle);
503 LOGD("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
509 LOGE("Failed to allocate HW Accelerated buffer\n");
513 * Or use the buffer of a S/W backend.
515 buffer = livebox_ref_buffer(info->handle);
516 LOGD("SW buffer is created (%dx%d)\n", info->w, info->h);
521 static void *alloc_stride_fb(void *data, int size, int *stride, int *bpp)
525 buffer = alloc_fb(data, size);
527 struct info *info = data;
531 _stride = livebox_buffer_stride(info->handle);
533 _stride = info->w * *bpp;
538 DbgPrint("bpp: %d, stride: %d\n", *bpp, *stride);
544 static void free_fb(void *data, void *ptr)
546 struct info *info = data;
553 if (livebox_destroy_hw_buffer(info->handle) == 0) {
554 LOGD("HW Accelerated buffer is destroyed\n");
557 LOGD("SW buffer is destroyed, %p\n", info);
558 livebox_unref_buffer(ptr);
561 livebox_release_buffer(info->handle);
572 static void pre_render_cb(void *data, Evas *e, void *event_info)
574 struct info *info = data;
580 if (livebox_conf_premultiplied_alpha()) {
584 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
585 evas_damage_rectangle_add(e, 0, 0, w, h);
589 livebox_buffer_pre_render(info->handle);
593 static void post_render_cb(void *data, Evas *e, void *event_info)
595 struct info *info = data;
601 if (livebox_conf_premultiplied_alpha()) {
605 // Get a pointer of a buffer of the virtual canvas
606 canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
608 ErrPrint("Failed to get pixel canvas\n");
612 ecore_evas_geometry_get(info->ee, &x, &y, &w, &h);
613 evas_data_argb_unpremul(canvas, w * h);
617 livebox_buffer_post_render(info->handle);
619 livebox_sync_buffer(info->handle);
623 static void ecore_evas_free_cb(Ecore_Evas *ee)
627 info = ecore_evas_data_get(ee, "dynamic,box,info");
629 LOGD("Info is not valid\n");
634 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
635 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
642 PUBLIC Evas_Object *livebox_get_evas_object(const char *id, int is_pd)
647 if (!s_info.alloc_canvas && !s_info.alloc_canvas_with_stride) {
648 s_info.alloc_canvas_with_stride = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_with_stride_new");
649 if (!s_info.alloc_canvas_with_stride) {
650 DbgPrint("allocfunc_with_stirde_new is not found\n");
653 s_info.alloc_canvas = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_new");
654 if (!s_info.alloc_canvas) {
655 ErrPrint("allocfunc_new is not found\n");
658 if (!s_info.alloc_canvas_with_stride && !s_info.alloc_canvas) {
659 ErrPrint("No way to allocate canvas\n");
665 ErrPrint("Invalid parameter\n");
669 info = calloc(1, sizeof(*info));
671 ErrPrint("Heap: %s\n", strerror(errno));
675 info->id = strdup(id);
677 ErrPrint("Heap: %s\n", strerror(errno));
685 * Size information must be initialized before call the ecore_evas_buffer_new.
690 if (!livebox_conf_auto_align() && s_info.alloc_canvas_with_stride) {
691 info->ee = s_info.alloc_canvas_with_stride(1, 1, alloc_stride_fb, free_fb, info);
693 info->ee = s_info.alloc_canvas(1, 1, alloc_fb, free_fb, info);
697 ErrPrint("Failed to create ecore_evas (%dx%d)\n", 1, 1);
703 info->e = ecore_evas_get(info->ee);
705 ErrPrint("Failed to get evas\n");
706 ecore_evas_free(info->ee);
710 ecore_evas_data_set(info->ee, "dynamic,box,info", info);
712 pre_render_cb(info, NULL, NULL);
713 ecore_evas_alpha_set(info->ee, EINA_TRUE);
714 post_render_cb(info, NULL, NULL);
716 ecore_evas_manual_render_set(info->ee, EINA_FALSE);
717 ecore_evas_resize(info->ee, 1, 1);
719 ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
720 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
721 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
723 rect = evas_object_rectangle_add(info->e);
725 ErrPrint("Failed to create evas_object\n");
726 ecore_evas_free(info->ee);
730 evas_object_resize(rect, 1, 1);
731 evas_object_color_set(rect, 0, 0, 0, 0);