1 #include "PUI_internal.h"
2 #include "PUI_backend.h"
6 static int KEY_WL_BUFFER = 0xabcdbeaf;
7 static int KEY_CLIENT = 0xdcbabeaf;
10 _cb_window_show(void *data, int type EINA_UNUSED, void *event)
12 pui_ani_h handle = (pui_ani_h)data;
13 Ecore_Wl2_Event_Window_Show *ev = (Ecore_Wl2_Event_Window_Show *)event;
21 return ECORE_CALLBACK_PASS_ON;
25 _cb_focus_in(void *data, int type EINA_UNUSED, void *event)
27 pui_ani_h handle = (pui_ani_h)data;
28 Ecore_Wl2_Event_Focus_In *ev = (Ecore_Wl2_Event_Focus_In *)event;
36 return ECORE_CALLBACK_PASS_ON;
40 _cb_focus_out(void *data, int type EINA_UNUSED, void *event)
42 pui_ani_h handle = (pui_ani_h)data;
43 Ecore_Wl2_Event_Focus_Out *ev = (Ecore_Wl2_Event_Focus_Out *)event;
51 return ECORE_CALLBACK_PASS_ON;
55 _cb_visibility_change(void *data, int type EINA_UNUSED, void *event)
57 pui_ani_h ani_h = (pui_ani_h)data;
58 pui_ani_t *ani = ani_h->ani;
59 pui_h ph = ani_h->pui_handle;
61 Ecore_Wl2_Event_Window_Visibility_Change *ev;
62 PUI_Event_Animation_Status *e = NULL;
66 pui_info("Visibility change (window=0x%x, fully_obscured=%d)\n", ev->win, ev->fully_obscured);
68 /* check if this is needed */
69 ph->visibility = !(ev->fully_obscured);
71 if (ev->fully_obscured)
73 if (ani->status == PUI_ANI_STATUS_RUNNING)
75 ani->status = PUI_ANI_STATUS_STOPPED;
77 e = (PUI_Event_Animation_Status *)calloc(1, sizeof(PUI_Event_Animation_Status));
81 pui_err("Failed to allocate memory for PUI Event !\n");
82 return ECORE_CALLBACK_PASS_ON;
86 e->status = PUI_ANI_STATUS_FORCE_STOPPED;
88 ecore_event_add(PUI_EVENT_ANI_STOPPED, e, NULL, ani_h);
93 e = (PUI_Event_Animation_Status *)calloc(1, sizeof(PUI_Event_Animation_Status));
97 pui_err("Failed to allocate memory for PUI Event !\n");
98 return ECORE_CALLBACK_PASS_ON;
102 e->status = ani->status;
104 if (ani->status == PUI_ANI_STATUS_STOPPED)
105 ecore_event_add(PUI_EVENT_ANI_READY_TO_START, e, NULL, ani_h);
106 else if(ani->status == PUI_ANI_STATUS_PAUSED)
107 ecore_event_add(PUI_EVENT_ANI_READY_TO_RESUME, e, NULL, ani_h);
110 return ECORE_CALLBACK_PASS_ON;
114 _pui_ani_cb_frame_done(Ecore_Wl2_Window *win, uint32_t timestamp EINA_UNUSED, void *data)
116 pui_h handle = (pui_h) data;
118 pui_info("Frame done ! (window=%p)\n", win);
127 _buffer_release(void *data, struct wl_buffer *buffer)
129 tbm_surface_h surface = (tbm_surface_h)data;
132 tbm_surface_internal_get_user_data(surface, (unsigned long)&KEY_CLIENT, (void **)&handle);
133 tbm_surface_queue_release(handle->tbm_queue, surface);
135 pui_info("[UPDATE] release wl_buffer:%p, surface:%p\n", buffer, surface);
138 static const struct wl_buffer_listener buffer_listener = {
142 pui_ani_control_buffer *
143 pui_ani_get_buffer(pui_ani_h ani_h)
146 tbm_surface_error_e ret;
147 tbm_surface_h surface;
148 pui_ani_control_buffer *buffer = NULL;
152 pui_err(
\r"Invalid pui ani handle !\n");
156 handle = ani_h->pui_handle;
160 pui_err("Error : PUI_INT_ERROR_INVALID_HANDLE\n");
164 if (handle->current_surface)
166 pui_warn("Current_surface is not used !\n");
169 if (!tbm_surface_queue_can_dequeue(handle->tbm_queue, 0))
171 pui_err("[UPDATE] Cannot dequeue (error : PUI_ERROR_INTERNAL)\n");
175 ret = tbm_surface_queue_dequeue(handle->tbm_queue, &surface);
177 if (ret != TBM_SURFACE_ERROR_NONE)
179 pui_err("[UPDATE] dequeue err:%d\n", ret);
183 tbm_surface_map(surface, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &handle->current_sinfo);
185 handle->current_surface = surface;
186 buffer = (pui_ani_control_buffer *)&(handle->current_sinfo.planes[0]);
192 pui_ani_set_buffer(pui_ani_h ani_h, pui_ani_control_buffer *buffer)
198 pui_err("Invalid ani handle !\n");
199 return PUI_INT_ERROR_INVALID_HANDLE;
202 handle = ani_h->pui_handle;
206 pui_err("Error : PUI_INT_ERROR_INVALID_HANDLE\n");
207 return PUI_INT_ERROR_INVALID_HANDLE;
210 if (!handle->current_surface)
212 pui_err("Current_surface is not valid !\n");
213 return PUI_INT_ERROR_INVALID_SURFACE;
216 if (!buffer || !buffer->ptr || !buffer->size)
217 return PUI_INT_ERROR_INVALID_BUFFER;
219 handle->is_buffer_set = 1;
221 return PUI_INT_ERROR_NONE;
225 pui_ani_update(pui_ani_h ani_h)
227 tbm_surface_h surface;
228 tbm_surface_error_e ret;
229 struct wl_buffer *wl_buffer = NULL;
235 pui_err("Invalid ani handle !\n");
236 return PUI_INT_ERROR_INVALID_HANDLE;
239 handle = ani_h->pui_handle;
243 pui_err("Error : PUI_INT_ERROR_INVALID_HANDLE\n");
244 return PUI_INT_ERROR_INVALID_HANDLE;
247 if (!handle->current_surface)
248 return PUI_INT_ERROR_INVALID_SURFACE;
250 if (!handle->is_buffer_set)
252 pui_err("Buffer is not set !\n");
253 return PUI_INT_ERROR_INVALID_BUFFER;
256 surface = handle->current_surface;
257 handle->current_surface = NULL;
259 tbm_surface_unmap(surface);
261 ret = tbm_surface_queue_enqueue(handle->tbm_queue, surface);
263 if (ret != TBM_SURFACE_ERROR_NONE)
265 pui_err("[UPDATE] enqueue err:%d\n", ret);
266 return PUI_INT_ERROR_INVALID_SURFACE;
269 ret = tbm_surface_queue_acquire(handle->tbm_queue, &surface);
271 if (ret != TBM_SURFACE_ERROR_NONE)
273 pui_err("[UPDATE] acquire err:%d\n", ret);
274 return PUI_INT_ERROR_INVALID_SURFACE;
277 if (!tbm_surface_internal_get_user_data(surface, (unsigned long)&KEY_WL_BUFFER, (void **)&wl_buffer)) {
278 wl_buffer = wayland_tbm_client_create_buffer(handle->wl_tbm_client, surface);
282 pui_err("[UPDATE] failed to create wl_buffer tbm_surface:%p\n", surface);
283 return PUI_INT_ERROR_INVALID_BUFFER;
286 wl_buffer_add_listener(wl_buffer, &buffer_listener, surface);
288 tbm_surface_internal_add_user_data(surface, (unsigned long)&KEY_WL_BUFFER, NULL);
289 tbm_surface_internal_set_user_data(surface, (unsigned long)&KEY_WL_BUFFER, wl_buffer);
290 tbm_surface_internal_add_user_data(surface, (unsigned long)&KEY_CLIENT, NULL);
291 tbm_surface_internal_set_user_data(surface, (unsigned long)&KEY_CLIENT, handle);
296 pui_err("[UPDATE] dequeue err:%d\n", ret);
297 return PUI_INT_ERROR_INVALID_BUFFER;
300 ecore_wl2_window_buffer_attach(handle->win, wl_buffer, 0, 0, 0);
301 ecore_wl2_window_damage(handle->win, NULL, 0);
302 ecore_wl2_window_commit(handle->win, EINA_TRUE);
304 pui_info("[UPDATE] commit wl_buffer:%p, surface:%p\n", wl_buffer, surface);
306 handle->is_buffer_set = 0;
308 return PUI_INT_ERROR_NONE;
312 _pui_ani_event_handlers_init(pui_ani_h ani_h)
314 Ecore_Event_Handler *h = NULL;
318 pui_err("Invalid handle !\n");
322 if (!ani_h->ecore_event_hdls)
323 ani_h->ecore_event_hdls = eina_array_new(5);
325 h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_SHOW, _cb_window_show, ani_h);
326 eina_array_push(ani_h->ecore_event_hdls, h);
328 h = ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_IN, _cb_focus_in, ani_h);
329 eina_array_push(ani_h->ecore_event_hdls, h);
331 h = ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_OUT, _cb_focus_out, ani_h);
332 eina_array_push(ani_h->ecore_event_hdls, h);
334 h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, _cb_visibility_change, ani_h);
335 eina_array_push(ani_h->ecore_event_hdls, h);
340 _pui_ani_event_handlers_shutdown(pui_ani_h ani_h)
344 pui_err("Invalid handle !\n");
348 while (eina_array_count(ani_h->ecore_event_hdls))
349 ecore_event_handler_del(eina_array_pop(ani_h->ecore_event_hdls));
350 eina_array_free(ani_h->ecore_event_hdls);
352 ani_h->ecore_event_hdls = NULL;
355 Eina_Bool _pui_ani_frame_cb(void *data)
359 pui_ani_t *ani = (pui_ani_t *)data;
363 pui_err("Invalid pui ani !\n");
364 return ECORE_CALLBACK_CANCEL;
367 if (!ani->backend_frame_cb)
369 pui_err("Invalid backend frame_cb !\n");
370 return ECORE_CALLBACK_CANCEL;
373 pui_info("frame_cb !\n");
375 ret = (Eina_Bool)ani->backend_frame_cb(ani, ++ani->serial);
377 if (!ani->frame_cb_timer)
378 return ECORE_CALLBACK_CANCEL;
380 pui_ani_status_update(ani, PUI_ANI_STATUS_RUNNING);
386 pui_ani_add_frame_cb(pui_ani_t *ani, pui_bool (*frame_cb)(void *data, int serial), double frame_interval)
388 Ecore_Timer *timer = NULL;
392 pui_err("Invalid put ani !\n");
396 ani->frame_cb = _pui_ani_frame_cb;
397 ani->backend_frame_cb = frame_cb;
398 ani->frame_interval = frame_interval;
399 ani->frame_cb_data = ani;
402 timer = ecore_timer_add(frame_interval, (Ecore_Task_Cb)ani->frame_cb, ani->frame_cb_data);
404 if (ani->frame_cb_timer)
406 ecore_timer_del(ani->frame_cb_timer);
407 ani->frame_cb_timer = NULL;
410 ani->frame_cb_timer = timer;
412 /* call frame_cb for starting the first frame */
413 _pui_ani_frame_cb(ani);
417 pui_ani_remove_frame_cb(pui_ani_t *ani)
422 if (ani->frame_cb_timer)
424 ecore_timer_del(ani->frame_cb_timer);
425 ani->frame_cb_timer = NULL;
428 ani->frame_cb = NULL;
429 ani->backend_frame_cb = NULL;
430 ani->frame_interval = 0;
431 ani->frame_cb_data = NULL;
435 pui_ani_get_id(pui_ani_h ani_h)
437 if (!ani_h || !ani_h->ani)
440 return ani_h->ani->id;
444 pui_ani_get_cmd(pui_ani_h ani_h)
446 if (!ani_h || !ani_h->ani)
447 return PUI_ANI_CMD_NONE;
449 return ani_h->ani->cmd;
453 pui_ani_get_repeat(pui_ani_h ani_h)
455 if (!ani_h || !ani_h->ani)
458 return ani_h->ani->repeat;
461 pui_backend_ani_data *
462 pui_ani_get_ani_data(pui_ani_t *ani)
467 return ani->ani_data;
471 pui_ani_status_update(pui_ani_t *ani, pui_ani_status status)
473 //TODO : add PUI EVENT
475 ani->status = status;
479 pui_ani_status_get(pui_ani_t *ani)
481 pui_ani_status status = PUI_ANI_STATUS_UNKNOWN;
485 pui_err("Invalid pui ani !\n");
493 pui_ani_control(pui_ani_h ani_h, pui_ani_cmd cmd, int repeat)
495 pui_ani_t *ani = NULL;
497 pui_backend_ani_func *ani_func = NULL;
500 return PUI_ERROR_INVALID_ANI_HANDLE;
502 if (cmd < PUI_ANI_CMD_START || cmd >= PUI_ANI_CMD_LAST)
504 pui_err("Invalid cmd ! (repeat=%d)\n", repeat);
505 return PUI_ERROR_INVALID_ANI_CMD;
510 pui_err("Invalid repeat count ! (repeat=%d)\n", repeat);
511 return PUI_ERROR_INVALID_ANI_REPEAT;
514 //TODO : check if there is any animation being played already
515 //NOTE : the id of the animation being played can be different from ani_h->id
517 handle = ani_h->pui_handle;
520 if (!ani || !ani->ani_data)
522 pui_err("Invalid ani or ani_data !\n");
523 return PUI_ERROR_INTERNAL;
526 ani_func = ani->ani_data->ani_func;
528 if (cmd == PUI_ANI_CMD_START)
530 ani_func->ani_start(ani, repeat);
532 else//cmd == PUI_ANI_CMD_STOP
534 ani_func->ani_stop(ani);
538 ani->repeat = repeat;
540 ani_h->frame_done_cb = ecore_wl2_window_frame_callback_add(handle->win, _pui_ani_cb_frame_done, handle);
542 if (!ani_h->frame_done_cb)
544 pui_err("Failed to add frame callback !");
550 return PUI_ERROR_NONE;
553 return PUI_ERROR_INTERNAL;
557 pui_ani_create(pui_h handle, pui_id id)
559 pui_ani_h ani_h = NULL;
560 pui_ani_t *ani = NULL;
561 pui_backend_ani_data *ani_data = NULL;
563 if (!handle || !handle->backend_module_data)
565 pui_err("Invalid pui handle or backend module data !\n");
569 ani_data = handle->backend_module_data->ani_create(id);
573 pui_err("Invalid ani data from backend module data !\n");
577 ani_h = (pui_ani_h)calloc(1, sizeof(pui_ani));
581 pui_err("Failed to allocate memory for pui ani handle !\n");
585 ani_h->ecore_event_hdls = NULL;
586 _pui_ani_event_handlers_init(ani_h);
588 ani = (pui_ani_t *)calloc(1, sizeof(pui_ani_t));
592 pui_err("Failed to allocate memory for pui ani mgr !\n");
598 ani->status = PUI_ANI_STATUS_INITIAL;
599 ani->ani_data = ani_data;
601 handle->ani_handles = eina_list_append(handle->ani_handles, ani_h);
608 handle->backend_module_data->ani_destroy(ani_data);
618 pui_ani_destroy(pui_ani_h ani_h)
621 pui_ani_t *ani = NULL;
622 pui_backend_module_data *backend_module_data = NULL;
624 if (!ani_h || !ani_h->pui_handle)
627 handle = ani_h->pui_handle;
630 /* stop the animation being played already if any */
631 if (ani->status != PUI_ANI_STATUS_STOPPED)
632 pui_ani_control(ani_h, PUI_ANI_CMD_STOP, 0);
634 backend_module_data = handle->backend_module_data;
635 backend_module_data->ani_destroy(ani->ani_data);
636 ani->ani_data = NULL;
638 if (ani->frame_cb_timer)
640 ecore_timer_del(ani->frame_cb_timer);
641 ani->frame_cb_timer = NULL;
646 _pui_ani_event_handlers_shutdown(ani_h);
648 if (ani_h->frame_done_cb)
650 ecore_wl2_window_frame_callback_del(ani_h->frame_done_cb);
651 ani_h->frame_done_cb = NULL;
654 handle->ani_handles = eina_list_remove(handle->ani_handles, ani_h);