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("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 if (ani_h->ecore_event_hdls)
350 while (eina_array_count(ani_h->ecore_event_hdls))
351 ecore_event_handler_del(eina_array_pop(ani_h->ecore_event_hdls));
353 eina_array_free(ani_h->ecore_event_hdls);
354 ani_h->ecore_event_hdls = NULL;
359 _pui_ani_frame_cb(void *data)
363 pui_ani_t *ani = (pui_ani_t *)data;
367 pui_err("Invalid pui ani !\n");
368 return ECORE_CALLBACK_CANCEL;
371 if (!ani->backend_frame_cb)
373 pui_err("Invalid backend frame_cb !\n");
374 return ECORE_CALLBACK_CANCEL;
377 if (!ani->frame_cb_timer)
379 pui_err("Invalid frame_cb timer !\n");
380 return ECORE_CALLBACK_CANCEL;
383 pui_info("frame_cb !\n");
385 ret = (Eina_Bool)ani->backend_frame_cb(ani, ++ani->serial);
387 pui_ani_status_update(ani, PUI_ANI_STATUS_RUNNING);
393 pui_ani_add_frame_cb(pui_ani_t *ani, pui_bool (*frame_cb)(void *data, int serial), double frame_interval)
395 Ecore_Timer *timer = NULL;
399 pui_err("Invalid put ani !\n");
403 ani->frame_cb = _pui_ani_frame_cb;
404 ani->backend_frame_cb = frame_cb;
405 ani->frame_interval = frame_interval;
406 ani->frame_cb_data = ani;
409 timer = ecore_timer_add(frame_interval, _pui_ani_frame_cb, ani);
413 pui_err("Failed to add ecore timer !\n");
417 ani->frame_cb_timer = timer;
419 /* call frame_cb for starting the first frame */
420 _pui_ani_frame_cb(ani);
426 pui_ani_remove_frame_cb(pui_ani_t *ani)
431 if (ani->frame_cb_timer)
433 ecore_timer_del(ani->frame_cb_timer);
434 ani->frame_cb_timer = NULL;
437 ani->frame_cb = NULL;
438 ani->backend_frame_cb = NULL;
439 ani->frame_interval = 0;
440 ani->frame_cb_data = NULL;
444 pui_ani_get_id(pui_ani_h ani_h)
446 if (!ani_h || !ani_h->ani)
449 return ani_h->ani->id;
453 pui_ani_get_cmd(pui_ani_h ani_h)
455 if (!ani_h || !ani_h->ani)
456 return PUI_ANI_CMD_NONE;
458 return ani_h->ani->cmd;
462 pui_ani_get_repeat(pui_ani_h ani_h)
464 if (!ani_h || !ani_h->ani)
467 return ani_h->ani->repeat;
470 pui_backend_ani_data *
471 pui_ani_get_ani_data(pui_ani_t *ani)
476 return ani->ani_data;
480 pui_ani_status_update(pui_ani_t *ani, pui_ani_status status)
482 //TODO : add PUI EVENT
484 ani->status = status;
488 pui_ani_status_get(pui_ani_t *ani)
490 pui_ani_status status = PUI_ANI_STATUS_UNKNOWN;
494 pui_err("Invalid pui ani !\n");
502 pui_ani_control(pui_ani_h ani_h, pui_ani_cmd cmd, int repeat)
504 pui_ani_t *ani = NULL;
506 pui_backend_ani_func *ani_func = NULL;
509 return PUI_ERROR_INVALID_ANI_HANDLE;
511 if (cmd < PUI_ANI_CMD_START || cmd >= PUI_ANI_CMD_LAST)
513 pui_err("Invalid cmd ! (repeat=%d)\n", repeat);
514 return PUI_ERROR_INVALID_ANI_CMD;
519 pui_err("Invalid repeat count ! (repeat=%d)\n", repeat);
520 return PUI_ERROR_INVALID_ANI_REPEAT;
523 //TODO : check if there is any animation being played already
524 //NOTE : the id of the animation being played can be different from ani_h->id
526 handle = ani_h->pui_handle;
529 if (!ani || !ani->ani_data)
531 pui_err("Invalid ani or ani_data !\n");
532 return PUI_ERROR_INTERNAL;
535 ani_func = ani->ani_data->ani_func;
538 ani->repeat = repeat;
540 if (cmd == PUI_ANI_CMD_START)
542 ani_func->ani_start(ani, repeat);
544 else//cmd == PUI_ANI_CMD_STOP
546 ani_func->ani_stop(ani);
547 return PUI_ERROR_NONE;
550 ani_h->frame_done_cb = ecore_wl2_window_frame_callback_add(handle->win, _pui_ani_cb_frame_done, handle);
552 if (!ani_h->frame_done_cb)
554 pui_err("Failed to add frame callback !");
560 return PUI_ERROR_NONE;
563 return PUI_ERROR_INTERNAL;
567 pui_ani_create(pui_h handle, pui_id id)
569 pui_ani_h ani_h = NULL;
570 pui_ani_t *ani = NULL;
571 pui_backend_ani_data *ani_data = NULL;
573 if (!handle || !handle->backend_module_data)
575 pui_err("Invalid pui handle or backend module data !\n");
579 ani_data = handle->backend_module_data->ani_create(id);
583 pui_err("Invalid ani data from backend module data !\n");
587 ani_h = (pui_ani_h)calloc(1, sizeof(pui_ani));
591 pui_err("Failed to allocate memory for pui ani handle !\n");
595 ani_h->id = strdup(id);
596 ani_h->pui_handle = handle;
597 ani_h->ecore_event_hdls = NULL;
599 _pui_ani_event_handlers_init(ani_h);
601 ani = (pui_ani_t *)calloc(1, sizeof(pui_ani_t));
605 pui_err("Failed to allocate memory for pui ani mgr !\n");
611 ani->cmd = PUI_ANI_CMD_NONE;
613 ani->status = PUI_ANI_STATUS_INITIAL;
614 ani->ani_data = ani_data;
618 handle->ani_handles = eina_list_append(handle->ani_handles, ani_h);
625 handle->backend_module_data->ani_destroy(ani_data);
635 pui_ani_destroy(pui_ani_h ani_h)
638 pui_ani_t *ani = NULL;
639 pui_backend_module_data *backend_module_data = NULL;
641 if (!ani_h || !ani_h->pui_handle)
644 handle = ani_h->pui_handle;
647 /* stop the animation being played already if any */
648 if (ani->status != PUI_ANI_STATUS_STOPPED)
649 pui_ani_control(ani_h, PUI_ANI_CMD_STOP, 0);
651 backend_module_data = handle->backend_module_data;
652 backend_module_data->ani_destroy(ani->ani_data);
653 ani->ani_data = NULL;
655 if (ani->frame_cb_timer)
657 ecore_timer_del(ani->frame_cb_timer);
658 ani->frame_cb_timer = NULL;
663 _pui_ani_event_handlers_shutdown(ani_h);
665 if (ani_h->frame_done_cb)
667 ecore_wl2_window_frame_callback_del(ani_h->frame_done_cb);
668 ani_h->frame_done_cb = NULL;
671 handle->ani_handles = eina_list_remove(handle->ani_handles, ani_h);