+
+int
+tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
+{
+ struct _tbm_surface *surf;
+ tbm_surface_destroy_func_info *func_info = NULL;
+
+ _tbm_surface_mutex_lock();
+ _tbm_set_last_result(TBM_ERROR_NONE);
+
+ TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
+ TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
+
+ surf = (struct _tbm_surface *)surface;
+ LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
+ if (func_info->destroy_func == func && func_info->user_data == user_data) {
+ TBM_ERR("can't add twice");
+ _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
+ _tbm_surface_mutex_unlock();
+ return 0;
+ }
+ }
+
+ func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
+ if (func_info == NULL) {
+ TBM_ERR("alloc failed");
+ _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
+ _tbm_surface_mutex_unlock();
+ return 0;
+ }
+
+ func_info->destroy_func = func;
+ func_info->user_data = user_data;
+
+ LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
+
+ _tbm_surface_mutex_unlock();
+
+ return 1;
+}
+
+void
+tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
+{
+ struct _tbm_surface *surf;
+ tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
+
+ _tbm_surface_mutex_lock();
+ _tbm_set_last_result(TBM_ERROR_NONE);
+
+ TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
+ TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
+
+ surf = (struct _tbm_surface *)surface;
+ LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
+ if (func_info->destroy_func != func || func_info->user_data != user_data)
+ continue;
+
+ LIST_DEL(&func_info->item_link);
+ free(func_info);
+
+ _tbm_surface_mutex_unlock();
+
+ return;
+ }
+
+ _tbm_surface_mutex_unlock();
+}