struct ivi_layout_surface *layout_surface;
struct wl_listener surface_destroy_listener;
struct wl_list list_layer;
+ uint32_t controller_surface_count;
+ int can_be_removed;
};
struct ivilayer {
struct ivishell *shell;
struct ivi_layout_layer *layout_layer;
struct wl_list list_screen;
+ uint32_t controller_layer_count;
+ int layer_canbe_removed;
};
struct iviscreen {
int previous_state;
int event_restriction;
};
+static void surface_event_remove(struct ivi_layout_surface *, void *);
static void
destroy_ivicontroller_surface(struct wl_resource *resource)
struct ivishell *shell = ivisurf->shell;
struct ivicontroller_surface *ctrlsurf = NULL;
struct ivicontroller_surface *next = NULL;
- uint32_t id_surface = 0;
-
- id_surface = ivi_layout_getIdOfSurface(ivisurf->layout_surface);
+ int is_removed = 0;
wl_list_for_each_safe(ctrlsurf, next,
&shell->list_controller_surface, link) {
continue;
}
+ if (!wl_list_empty(&ctrlsurf->link)) {
+ wl_list_remove(&ctrlsurf->link);
+ }
- wl_list_remove(&ctrlsurf->link);
+ is_removed = 1;
free(ctrlsurf);
ctrlsurf = NULL;
+ --ivisurf->controller_surface_count;
break;
}
+
+ if ((is_removed) && (ivisurf->controller_surface_count == 0)) {
+ if (ivisurf->can_be_removed) {
+ free(ivisurf);
+ }
+ else {
+ ivisurf->can_be_removed = 1;
+ }
+ }
}
static void
}
wl_list_remove(&ctrllayer->link);
+ --ivilayer->controller_layer_count;
+ ivi_controller_layer_send_destroyed(ctrllayer->resource);
free(ctrllayer);
ctrllayer = NULL;
break;
}
+
+ if ((ivilayer->layout_layer != NULL) &&
+ (ivilayer->controller_layer_count == 0) &&
+ (ivilayer->layer_canbe_removed == 1)) {
+ ivi_layout_layerRemove(ivilayer->layout_layer);
+ }
}
static void
static void
send_surface_add_event(struct ivisurface *ivisurf,
- struct wl_resource *resource)
+ struct wl_resource *resource,
+ enum ivi_layout_notification_mask mask)
{
- ivi_layout_layer_ptr *pArray = NULL;
+ struct ivi_layout_layer **pArray = NULL;
uint32_t length = 0;
int32_t ans = 0;
int i = 0;
struct ivilayer *ivilayer = NULL;
struct ivishell *shell = ivisurf->shell;
uint32_t id_layout_layer = 0;
+ struct wl_client *surface_client = wl_resource_get_client(resource);
int found = 0;
ans = ivi_layout_getLayersUnderSurface(ivisurf->layout_surface,
}
/* Send Null to cancel added surface */
- wl_list_for_each_safe(link_layer, next, &ivisurf->list_layer, link) {
- for (i = 0, found = 0; i < (int)length; i++) {
- if (pArray[i] == link_layer->layer->layout_layer) {
- /* No need to send event, if new layer doesn't be added. */
- found = 1;
- break;
- }
+ if (mask & IVI_NOTIFICATION_REMOVE) {
+ wl_list_for_each_safe(link_layer, next, &ivisurf->list_layer, link) {
+ ivi_controller_surface_send_layer(resource, NULL);
}
- if (found != 0) {
- continue;
- }
-
- ivi_controller_surface_send_layer(resource, NULL);
- wl_list_remove(&link_layer->link);
- free(link_layer);
- link_layer = NULL;
}
-
- for (i = 0; i < (int)length; i++) {
- found = 0;
- wl_list_for_each(link_layer, &ivisurf->list_layer, link) {
- if (pArray[i] == link_layer->layer->layout_layer) {
- /* No need to send event, if new layer doesn't be added. */
- found = 1;
- break;
+ else if (mask & IVI_NOTIFICATION_ADD) {
+ for (i = 0; i < (int)length; i++) {
+ /* Send new surface event */
+ ivilayer = NULL;
+ wl_list_for_each(ivilayer, &shell->list_layer, link) {
+ if (ivilayer->layout_layer == pArray[i]) {
+ break;
+ }
}
- }
- if (found != -1) {
- continue;
- }
- /* Create list_layer */
- link_layer = calloc(1, sizeof(*link_layer));
- if (NULL == link_layer) {
- continue;
- }
- wl_list_init(&link_layer->link);
- link_layer->layer = NULL;
- wl_list_for_each(ivilayer, &shell->list_layer, link) {
- if (ivilayer->layout_layer == pArray[i]) {
- link_layer->layer = ivilayer;
- break;
+ if (ivilayer == NULL) {
+ continue;
}
- }
- if (link_layer->layer == NULL) {
- free(link_layer);
- link_layer = NULL;
- continue;
- }
- wl_list_insert(&ivisurf->list_layer, &link_layer->link);
+ id_layout_layer =
+ ivi_layout_getIdOfLayer(ivilayer->layout_layer);
+ wl_list_for_each(ctrllayer, &shell->list_controller_layer, link) {
+ if (id_layout_layer != ctrllayer->id_layer) {
+ continue;
+ }
- /* Send new surface event */
- id_layout_layer =
- ivi_layout_getIdOfLayer(link_layer->layer->layout_layer);
- wl_list_for_each(ctrllayer, &shell->list_controller_layer, link) {
- if (id_layout_layer != ctrllayer->id_layer) {
- continue;
+ struct wl_client *layer_client = wl_resource_get_client(ctrllayer->resource);
+ if (surface_client != layer_client) {
+ continue;
+ }
+
+ ivi_controller_surface_send_layer(resource, ctrllayer->resource);
}
- ivi_controller_surface_send_layer(resource, ctrllayer->resource);
}
}
ivi_controller_surface_send_pixelformat(resource,
prop->pixelformat);
}
+ if (mask & IVI_NOTIFICATION_REMOVE) {
+ send_surface_add_event(ivisurf, resource, IVI_NOTIFICATION_REMOVE);
+ }
if (mask & IVI_NOTIFICATION_ADD) {
- send_surface_add_event(ivisurf, resource);
+ send_surface_add_event(ivisurf, resource, IVI_NOTIFICATION_ADD);
+ }
+}
+
+static void
+update_surface_prop(struct ivisurface *ivisurf,
+ uint32_t mask)
+{
+ struct ivi_layout_layer **pArray = NULL;
+ uint32_t length = 0;
+ int32_t ans = 0;
+ int i = 0;
+ struct ivishell *shell = ivisurf->shell;
+
+ ans = ivi_layout_getLayersUnderSurface(ivisurf->layout_surface,
+ &length, &pArray);
+ if (0 != ans) {
+ weston_log("failed to get layers at send_surface_add_event\n");
+ return;
+ }
+
+ if (mask & IVI_NOTIFICATION_REMOVE) {
+ struct link_layer *link_layer = NULL;
+ struct link_layer *next = NULL;
+
+ wl_list_for_each_safe(link_layer, next, &ivisurf->list_layer, link) {
+ wl_list_remove(&link_layer->link);
+ free(link_layer);
+ link_layer = NULL;
+ }
+ }
+ if (mask & IVI_NOTIFICATION_ADD) {
+ for (i = 0; i < (int)length; ++i) {
+ /* Create list_layer */
+ struct ivilayer *ivilayer = NULL;
+ struct link_layer *link_layer = calloc(1, sizeof(*link_layer));
+ if (NULL == link_layer) {
+ continue;
+ }
+ wl_list_init(&link_layer->link);
+ link_layer->layer = NULL;
+ wl_list_for_each(ivilayer, &shell->list_layer, link) {
+ if (ivilayer->layout_layer == pArray[i]) {
+ link_layer->layer = ivilayer;
+ break;
+ }
+ }
+
+ if (link_layer->layer == NULL) {
+ free(link_layer);
+ link_layer = NULL;
+ continue;
+ }
+
+ wl_list_insert(&ivisurf->list_layer, &link_layer->link);
+ }
}
}
}
send_surface_event(ctrlsurf->resource, ivisurf, prop, mask);
}
+
+ update_surface_prop(ivisurf, mask);
}
static void
send_layer_add_event(struct ivilayer *ivilayer,
- struct wl_resource *resource)
+ struct wl_resource *resource,
+ enum ivi_layout_notification_mask mask)
{
- ivi_layout_screen_ptr *pArray = NULL;
+ struct ivi_layout_screen **pArray = NULL;
uint32_t length = 0;
int32_t ans = 0;
int i = 0;
struct link_screen *next = NULL;
struct iviscreen *iviscrn = NULL;
struct ivishell *shell = ivilayer->shell;
- int found = 0;
struct wl_client *client = wl_resource_get_client(resource);
struct wl_resource *resource_output = NULL;
}
/* Send Null to cancel added layer */
- wl_list_for_each_safe(link_scrn, next, &ivilayer->list_screen, link) {
- for (i = 0, found = 0; i < (int)length; i++) {
- if (pArray[i] == link_scrn->screen->layout_screen) {
- /* No need to send event, if new layer doesn't be added. */
- found = 1;
- break;
- }
+ if (mask & IVI_NOTIFICATION_REMOVE) {
+ wl_list_for_each_safe(link_scrn, next, &ivilayer->list_screen, link) {
+ ivi_controller_layer_send_screen(resource, NULL);
}
- if (found != 0) {
- continue;
- }
-
- ivi_controller_layer_send_screen(resource, NULL);
- wl_list_remove(&link_scrn->link);
- free(link_scrn);
- link_scrn = NULL;
}
-
- for (i = 0; i < (int)length; i++) {
- found = 0;
- wl_list_for_each(link_scrn, &ivilayer->list_screen, link) {
- if (pArray[i] == link_scrn->screen->layout_screen) {
- /* No need to send event, if new screen doesn't be added. */
- found = 1;
- break;
+ else if (mask & IVI_NOTIFICATION_ADD) {
+ for (i = 0; i < (int)length; i++) {
+ /* Send new layer event */
+ iviscrn = NULL;
+ wl_list_for_each(iviscrn, &shell->list_screen, link) {
+ if (iviscrn->layout_screen == pArray[i]) {
+ break;
+ }
}
- }
- if (found != 0) {
- continue;
- }
- /* Create list_screen */
- link_scrn = calloc(1, sizeof(*link_scrn));
- if (NULL == link_scrn) {
- continue;
- }
- wl_list_init(&link_scrn->link);
- link_scrn->screen = NULL;
- wl_list_for_each(iviscrn, &shell->list_screen, link) {
- if (iviscrn->layout_screen == pArray[i]) {
- link_scrn->screen = iviscrn;
- break;
+ if (iviscrn == NULL) {
+ continue;
}
- }
- if (link_scrn->screen == NULL) {
- free(link_scrn);
- link_scrn = NULL;
- continue;
- }
- wl_list_insert(&ivilayer->list_screen, &link_scrn->link);
-
- /* Send new layer event */
- resource_output =
- wl_resource_find_for_client(&iviscrn->output->resource_list,
- client);
- if (resource_output != NULL) {
- ivi_controller_layer_send_screen(resource, resource_output);
+ resource_output =
+ wl_resource_find_for_client(&iviscrn->output->resource_list,
+ client);
+ if (resource_output != NULL) {
+ ivi_controller_layer_send_screen(resource, resource_output);
+ }
}
}
ivi_controller_layer_send_visibility(resource,
prop->visibility);
}
+ if (mask & IVI_NOTIFICATION_REMOVE) {
+ send_layer_add_event(ivilayer, resource, IVI_NOTIFICATION_REMOVE);
+ }
+ if (mask & IVI_NOTIFICATION_ADD) {
+ send_layer_add_event(ivilayer, resource, IVI_NOTIFICATION_ADD);
+ }
+}
+
+static void
+update_layer_prop(struct ivilayer *ivilayer,
+ enum ivi_layout_notification_mask mask)
+{
+ struct ivi_layout_screen **pArray = NULL;
+ uint32_t length = 0;
+ int32_t ans = 0;
+ struct link_screen *link_scrn = NULL;
+ struct link_screen *next = NULL;
+
+ ans = ivi_layout_getScreensUnderLayer(ivilayer->layout_layer,
+ &length, &pArray);
+ if (0 != ans) {
+ weston_log("failed to get screens at send_layer_add_event\n");
+ return;
+ }
+
+ /* Send Null to cancel added layer */
+ if (mask & IVI_NOTIFICATION_REMOVE) {
+ wl_list_for_each_safe(link_scrn, next, &ivilayer->list_screen, link) {
+ wl_list_remove(&link_scrn->link);
+ free(link_scrn);
+ link_scrn = NULL;
+ }
+ }
if (mask & IVI_NOTIFICATION_ADD) {
- send_layer_add_event(ivilayer, resource);
+ int i = 0;
+ for (i = 0; i < (int)length; i++) {
+ struct ivishell *shell = ivilayer->shell;
+ struct iviscreen *iviscrn = NULL;
+ /* Create list_screen */
+ link_scrn = calloc(1, sizeof(*link_scrn));
+ if (NULL == link_scrn) {
+ continue;
+ }
+ wl_list_init(&link_scrn->link);
+ link_scrn->screen = NULL;
+ wl_list_for_each(iviscrn, &shell->list_screen, link) {
+ if (iviscrn->layout_screen == pArray[i]) {
+ link_scrn->screen = iviscrn;
+ break;
+ }
+ }
+
+ if (link_scrn->screen == NULL) {
+ free(link_scrn);
+ link_scrn = NULL;
+ continue;
+ }
+ wl_list_insert(&ivilayer->list_screen, &link_scrn->link);
+ }
}
+
+ free(pArray);
+ pArray = NULL;
}
static void
}
send_layer_event(ctrllayer->resource, ivilayer, prop, mask);
}
+
+ update_layer_prop(ivilayer, mask);
}
static void
struct wl_resource *resource,
int32_t destroy_scene_object)
{
- struct ivisurface *ivisurf = wl_resource_get_user_data(resource);
- struct ivishell *shell = ivisurf->shell;
- struct ivicontroller_surface *ctrlsurf = NULL;
- struct ivicontroller_surface *next = NULL;
- uint32_t id_surface = ivi_layout_getIdOfSurface(ivisurf->layout_surface);
(void)client;
(void)destroy_scene_object;
-
- wl_list_for_each_safe(ctrlsurf, next,
- &shell->list_controller_surface, link) {
- if (ctrlsurf->resource != resource) {
- continue;
- }
-
- if (!wl_list_empty(&ctrlsurf->link)) {
- wl_list_remove(&ctrlsurf->link);
- }
- free(ctrlsurf);
- wl_resource_destroy(resource);
- break;
- }
+ wl_resource_destroy(resource);
}
static void
struct ivilayer *ivilayer = wl_resource_get_user_data(resource);
struct ivishell *shell = ivilayer->shell;
struct ivicontroller_layer *ctrllayer = NULL;
+ struct ivicontroller_layer *next = NULL;
uint32_t id_layer = ivi_layout_getIdOfLayer(ivilayer->layout_layer);
(void)client;
(void)destroy_scene_object;
- wl_list_for_each(ctrllayer, &shell->list_controller_layer, link) {
+ ivilayer->layer_canbe_removed = 1;
+ wl_list_for_each_safe(ctrllayer, next, &shell->list_controller_layer, link) {
if (ctrllayer->id_layer != id_layer) {
continue;
}
- if (!wl_list_empty(&ctrllayer->link)) {
- wl_list_remove(&ctrllayer->link);
- }
- free(ctrllayer);
- wl_resource_destroy(resource);
- break;
+ wl_resource_destroy(ctrllayer->resource);
}
-
- ivi_layout_layerRemove(ivilayer->layout_layer);
}
static const
return;
}
+ ++ivilayer->controller_layer_count;
+ ivilayer->layer_canbe_removed = 0;
+
ctrllayer->shell = shell;
ctrllayer->client = client;
ctrllayer->id = id;
memset(&prop, 0, sizeof prop);
ivi_layout_getPropertiesOfLayer(ivilayer->layout_layer, &prop);
+ send_layer_event(ctrllayer->resource, ivilayer,
+ &prop, IVI_NOTIFICATION_ALL);
+}
- wl_list_for_each(ctrllayer, &shell->list_controller_layer, link) {
- if (id_layer != ctrllayer->id_layer) {
- continue;
- }
- send_layer_event(ctrllayer->resource, ivilayer,
- &prop, IVI_NOTIFICATION_ALL);
+static void
+surface_event_content(struct ivi_layout_surface *layout_surface, int32_t content, void *userdata)
+{
+ struct ivishell *shell = userdata;
+ struct ivicontroller_surface *ctrlsurf = NULL;
+ uint32_t id_surface = 0;
+
+ if (content == 0) {
+ surface_event_remove(layout_surface, userdata);
}
}
return;
}
+ ++ivisurf->controller_surface_count;
+
wl_resource_set_implementation(ctrlsurf->resource,
&controller_surface_implementation,
ivisurf, destroy_ivicontroller_surface);
memset(&prop, 0, sizeof prop);
ivi_layout_getPropertiesOfSurface(ivisurf->layout_surface, &prop);
+ ivi_layout_surfaceSetContentObserver(ivisurf->layout_surface, surface_event_content, shell);
- wl_list_for_each(ctrlsurf, &shell->list_controller_surface, link) {
- if (id_surface != ctrlsurf->id_surface) {
- continue;
- }
- send_surface_event(ctrlsurf->resource, ivisurf,
- &prop, IVI_NOTIFICATION_ALL);
- }
+ send_surface_event(ctrlsurf->resource, ivisurf,
+ &prop, IVI_NOTIFICATION_ALL);
}
static const struct ivi_controller_interface controller_implementation = {
uint32_t id_layout_surface = 0;
uint32_t id_layout_layer = 0;
- wl_list_for_each(ivisurf, &shell->list_surface, link) {
- id_layout_surface =
- ivi_layout_getIdOfSurface(ivisurf->layout_surface);
-
- ivi_controller_send_surface(controller->resource,
- id_layout_surface);
- }
-
- wl_list_for_each(ivilayer, &shell->list_layer, link) {
- id_layout_layer =
- ivi_layout_getIdOfLayer(ivilayer->layout_layer);
-
- ivi_controller_send_layer(controller->resource,
- id_layout_layer);
- }
-
wl_list_for_each(iviscrn, &shell->list_screen, link) {
resource_output = wl_resource_find_for_client(
&iviscrn->output->resource_list, client);
wl_resource_get_id(resource_output),
ctrlscrn->resource);
}
+ wl_list_for_each_reverse(ivilayer, &shell->list_layer, link) {
+ id_layout_layer =
+ ivi_layout_getIdOfLayer(ivilayer->layout_layer);
+
+ ivi_controller_send_layer(controller->resource,
+ id_layout_layer);
+ }
+ wl_list_for_each_reverse(ivisurf, &shell->list_surface, link) {
+ id_layout_surface =
+ ivi_layout_getIdOfSurface(ivisurf->layout_surface);
+
+ ivi_controller_send_surface(controller->resource,
+ id_layout_surface);
+ }
}
static void
struct ivilayer *ivilayer = NULL;
struct ivilayer *next = NULL;
uint32_t id_layer = 0;
+ int is_removed = 0;
wl_list_for_each_safe(ivilayer, next, &shell->list_layer, link) {
if (layout_layer != ivilayer->layout_layer) {
}
wl_list_remove(&ivilayer->link);
+
+ is_removed = 1;
free(ivilayer);
ivilayer = NULL;
break;
}
- id_layer = ivi_layout_getIdOfLayer(layout_layer);
+ if (is_removed) {
+ id_layer = ivi_layout_getIdOfLayer(layout_layer);
- wl_list_for_each(ctrllayer, &shell->list_controller_layer, link) {
- if (id_layer != ctrllayer->id_layer) {
- continue;
+ wl_list_for_each(ctrllayer, &shell->list_controller_layer, link) {
+ if (id_layer != ctrllayer->id_layer) {
+ continue;
+ }
+ ivi_controller_layer_send_destroyed(ctrllayer->resource);
}
- ivi_controller_layer_send_destroyed(ctrllayer->resource);
}
}
struct ivisurface *ivisurf = NULL;
struct ivisurface *next = NULL;
uint32_t id_surface = 0;
+ int is_removed = 0;
wl_list_for_each_safe(ivisurf, next, &shell->list_surface, link) {
if (layout_surface != ivisurf->layout_surface) {
}
wl_list_remove(&ivisurf->link);
- free(ivisurf);
- ivisurf = NULL;
+ is_removed = 1;
+
+ if (ivisurf->controller_surface_count == 0) {
+ free(ivisurf);
+ }
+ else {
+ ivisurf->can_be_removed = 1;
+ }
+
break;
}
- id_surface = ivi_layout_getIdOfSurface(layout_surface);
+ if (is_removed) {
+ id_surface = ivi_layout_getIdOfSurface(layout_surface);
- wl_list_for_each(ctrlsurf, &shell->list_controller_surface, link) {
- if (id_surface != ctrlsurf->id_surface) {
- continue;
+ wl_list_for_each(ctrlsurf, &shell->list_controller_surface, link) {
+ if (id_surface != ctrlsurf->id_surface) {
+ continue;
+ }
+ ivi_controller_surface_send_destroyed(ctrlsurf->resource);
}
- ivi_controller_surface_send_destroyed(ctrlsurf->resource);
}
}
static int32_t
check_layout_layers(struct ivishell *shell)
{
- ivi_layout_layer_ptr *pArray = NULL;
+ struct ivi_layout_layer **pArray = NULL;
struct ivilayer *ivilayer = NULL;
uint32_t id_layer = 0;
uint32_t length = 0;
static int32_t
check_layout_surfaces(struct ivishell *shell)
{
- ivi_layout_surface_ptr *pArray = NULL;
+ struct ivi_layout_surface **pArray = NULL;
struct ivisurface *ivisurf = NULL;
uint32_t id_surface = 0;
uint32_t length = 0;
weston_log("failed to check_layout_surfaces");
}
- ivi_layout_setNotificationCreateLayer(layer_event_create, shell);
- ivi_layout_setNotificationRemoveLayer(layer_event_remove, shell);
+ ivi_layout_addNotificationCreateLayer(layer_event_create, shell);
+ ivi_layout_addNotificationRemoveLayer(layer_event_remove, shell);
- ivi_layout_setNotificationCreateSurface(surface_event_create, shell);
- ivi_layout_setNotificationRemoveSurface(surface_event_remove, shell);
- ivi_layout_setNotificationConfigureSurface(surface_event_configure, shell);
+ ivi_layout_addNotificationCreateSurface(surface_event_create, shell);
+ ivi_layout_addNotificationRemoveSurface(surface_event_remove, shell);
+ ivi_layout_addNotificationConfigureSurface(surface_event_configure, shell);
}
WL_EXPORT int