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);
404 ret = LB_KEY_STATUS_ERROR;
406 case BUFFER_EVENT_KEY_UP:
407 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
409 ret = LB_ACCESS_STATUS_ERROR;
413 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
418 key_string = XKeysymToString(*key_symbol);
419 key_name = XKeysymToString(*key_symbol);
420 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
424 ret = LB_KEY_STATUS_ERROR;
426 case BUFFER_EVENT_KEY_FOCUS_IN:
427 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
429 ret = LB_ACCESS_STATUS_ERROR;
433 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
438 key_string = XKeysymToString(*key_symbol);
439 key_name = XKeysymToString(*key_symbol);
440 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
444 ret = LB_KEY_STATUS_ERROR;
446 case BUFFER_EVENT_KEY_FOCUS_OUT:
447 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
449 ret = LB_ACCESS_STATUS_ERROR;
453 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
458 key_string = XKeysymToString(*key_symbol);
459 key_name = XKeysymToString(*key_symbol);
460 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
464 ret = LB_KEY_STATUS_ERROR;
467 LOGD("Unhandled buffer event (%d)\n", event_info->type);
474 static void *alloc_fb(void *data, int size)
476 struct info *info = data;
480 ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
481 LOGD("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
485 * Acquire a buffer for canvas.
487 info->handle = livebox_acquire_buffer(info->id, info->is_pd,
488 info->w, info->h, sizeof(int), (livebox_conf_auto_align() || !s_info.alloc_canvas_with_stride),
489 event_handler_cb, info);
492 * If it supports the H/W accelerated buffer,
495 if (livebox_support_hw_buffer(info->handle)) {
496 if (livebox_create_hw_buffer(info->handle) == 0) {
497 buffer = livebox_buffer_hw_buffer(info->handle);
499 LOGD("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
505 LOGE("Failed to allocate HW Accelerated buffer\n");
509 * Or use the buffer of a S/W backend.
511 buffer = livebox_ref_buffer(info->handle);
512 LOGD("SW buffer is created (%dx%d)\n", info->w, info->h);
517 static void *alloc_stride_fb(void *data, int size, int *stride, int *bpp)
521 buffer = alloc_fb(data, size);
523 struct info *info = data;
527 _stride = livebox_buffer_stride(info->handle);
529 _stride = info->w * *bpp;
534 DbgPrint("bpp: %d, stride: %d\n", *bpp, *stride);
540 static void free_fb(void *data, void *ptr)
542 struct info *info = data;
549 if (livebox_destroy_hw_buffer(info->handle) == 0) {
550 LOGD("HW Accelerated buffer is destroyed\n");
553 LOGD("SW buffer is destroyed, %p\n", info);
554 livebox_unref_buffer(ptr);
557 livebox_release_buffer(info->handle);
568 static void pre_render_cb(void *data, Evas *e, void *event_info)
570 struct info *info = data;
576 if (livebox_conf_premultiplied_alpha()) {
580 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
581 evas_damage_rectangle_add(e, 0, 0, w, h);
585 livebox_buffer_pre_render(info->handle);
589 static void post_render_cb(void *data, Evas *e, void *event_info)
591 struct info *info = data;
597 if (livebox_conf_premultiplied_alpha()) {
601 // Get a pointer of a buffer of the virtual canvas
602 canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
604 ErrPrint("Failed to get pixel canvas\n");
608 ecore_evas_geometry_get(info->ee, &x, &y, &w, &h);
609 evas_data_argb_unpremul(canvas, w * h);
613 livebox_buffer_post_render(info->handle);
615 livebox_sync_buffer(info->handle);
619 static void ecore_evas_free_cb(Ecore_Evas *ee)
623 info = ecore_evas_data_get(ee, "dynamic,box,info");
625 LOGD("Info is not valid\n");
630 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
631 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
638 PUBLIC Evas_Object *livebox_get_evas_object(const char *id, int is_pd)
643 if (!s_info.alloc_canvas && !s_info.alloc_canvas_with_stride) {
644 s_info.alloc_canvas_with_stride = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_with_stride_new");
645 if (!s_info.alloc_canvas_with_stride) {
646 DbgPrint("allocfunc_with_stirde_new is not found\n");
649 s_info.alloc_canvas = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_new");
650 if (!s_info.alloc_canvas) {
651 ErrPrint("allocfunc_new is not found\n");
654 if (!s_info.alloc_canvas_with_stride && !s_info.alloc_canvas) {
655 ErrPrint("No way to allocate canvas\n");
661 ErrPrint("Invalid parameter\n");
665 info = calloc(1, sizeof(*info));
667 ErrPrint("Heap: %s\n", strerror(errno));
671 info->id = strdup(id);
673 ErrPrint("Heap: %s\n", strerror(errno));
681 * Size information must be initialized before call the ecore_evas_buffer_new.
686 if (!livebox_conf_auto_align() && s_info.alloc_canvas_with_stride) {
687 info->ee = s_info.alloc_canvas_with_stride(1, 1, alloc_stride_fb, free_fb, info);
689 info->ee = s_info.alloc_canvas(1, 1, alloc_fb, free_fb, info);
693 ErrPrint("Failed to create ecore_evas (%dx%d)\n", 1, 1);
699 ecore_evas_data_set(info->ee, "dynamic,box,info", info);
700 ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
702 info->e = ecore_evas_get(info->ee);
704 ErrPrint("Failed to get evas\n");
705 ecore_evas_free(info->ee);
709 pre_render_cb(info, NULL, NULL);
710 ecore_evas_alpha_set(info->ee, EINA_TRUE);
711 post_render_cb(info, NULL, NULL);
713 ecore_evas_manual_render_set(info->ee, EINA_FALSE);
714 ecore_evas_resize(info->ee, 1, 1);
716 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
717 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
719 rect = evas_object_rectangle_add(info->e);
721 ErrPrint("Failed to create evas_object\n");
722 ecore_evas_free(info->ee);
726 evas_object_resize(rect, 1, 1);
727 evas_object_color_set(rect, 0, 0, 0, 0);