blob: 6c734a44a9af742600afd87318f0f528de5e2ca8 [file] [log] [blame]
/*
* If not stated otherwise in this file or this component's Licenses.txt file the
* following copyright and licenses apply:
*
* Copyright 2016 RDK Management
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <sys/time.h>
#include "weston-simpleshell.h"
#include "aml-weston/aml-simpleshell.h"
#include <libweston/zalloc.h>
#include <shared/helpers.h>
#include "wayland-server.h"
#include "simpleshell-server-protocol.h"
#define WST_UNUSED( n ) ((void)n)
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#define DEFAULT_NAME "noname"
#define BROADCAST_DELAY (2000)
static void destroy_shell(struct wl_resource *resource);
static void wstSimpleShellBroadcastCreation( struct wl_simple_shell *shell, uint32_t surfaceId );
struct shell_info
{
struct wl_client *client;
struct wl_resource *resource;
struct wl_list link;
};
struct pending_broadcast_info
{
uint32_t surfaceId;
long long creationTime;
struct wl_list link;
};
struct simple_shell_surface_id {
uint32_t surfaceId;
struct wl_list link;
};
struct wl_simple_shell
{
struct wl_display *display;
struct wl_global *wl_simple_shell_global;
struct wayland_simple_shell_callbacks *callbacks;
void *userData;
struct wl_event_source *delayTimer;
struct wl_list shells;
struct wl_list surfaces;
struct wl_list pendingCreateBroadcast;
struct wl_listener create_surface_listener;
};
struct simple_shell_destroy_info {
struct wl_simple_shell *shell;
struct wl_listener destroy_surface_listener;
};
static long long getCurrentTimeMillis()
{
struct timeval tv;
long long utcCurrentTimeMillis;
gettimeofday(&tv,0);
utcCurrentTimeMillis= tv.tv_sec*1000LL+(tv.tv_usec/1000LL);
return utcCurrentTimeMillis;
}
static void wstISimpleShellSetName(struct wl_client *client, struct wl_resource *resource,
uint32_t surfaceId, const char *name);
static void wstISimpleShellSetVisible(struct wl_client *client, struct wl_resource *resource,
uint32_t surfaceId, uint32_t visible);
static void wstISimpleShellSetGeometry(struct wl_client *client, struct wl_resource *resource,
uint32_t surfaceId, int32_t x, int32_t y, int32_t width, int32_t height);
static void wstISimpleShellSetOpacity(struct wl_client *client, struct wl_resource *resource,
uint32_t surfaceId, wl_fixed_t opacity);
static void wstISimpleShellSetZOrder(struct wl_client *client, struct wl_resource *resource,
uint32_t surfaceId, wl_fixed_t zorder);
static void wstISimpleShellGetStatus(struct wl_client *client, struct wl_resource *resource, uint32_t surface);
static void wstISimpleShellGetSurfaces(struct wl_client *client, struct wl_resource *resource);
static void wstISimpleShellSetFocus(struct wl_client *client, struct wl_resource *resource,
uint32_t surfaceId);
static void wstISimpleShellSetScale(struct wl_client *client, struct wl_resource *resource,
uint32_t surfaceId, wl_fixed_t scaleX, wl_fixed_t scaleY);
static void wstISimpleShellSetKeyIntercept(struct wl_client * client, struct wl_resource * resource,
uint32_t surfaceId, uint32_t keyCode, uint32_t modifiers);
static void wstISimpleShellSetMultiKeyIntercept(struct wl_client * client, struct wl_resource * resource,
uint32_t surfaceId, struct wl_array * keyCode, struct wl_array * modifiers);
static void wstISimpleShellRemoveMultiKeyIntercept(struct wl_client * client, struct wl_resource * resource,
uint32_t surfaceId, struct wl_array * keyCode, struct wl_array * modifiers);
static void wstISimpleShellApplyAppsZorder(struct wl_client * client, struct wl_resource * resource,
struct wl_array * appList);
static void wstISimpleShellSendMultiKey(struct wl_client * client, struct wl_resource * resource,
uint32_t surfaceId, struct wl_array * keyCode, struct wl_array * modifiers);
const static struct wl_simple_shell_interface simple_shell_interface = {
wstISimpleShellSetName,
wstISimpleShellSetVisible,
wstISimpleShellSetGeometry,
wstISimpleShellSetOpacity,
wstISimpleShellSetZOrder,
wstISimpleShellGetStatus,
wstISimpleShellGetSurfaces,
wstISimpleShellSetFocus,
wstISimpleShellSetScale,
wstISimpleShellSetKeyIntercept,
wstISimpleShellSetMultiKeyIntercept,
wstISimpleShellRemoveMultiKeyIntercept,
wstISimpleShellApplyAppsZorder,
wstISimpleShellSendMultiKey
};
static void wstSimpleShellBroadcastSurfaceUpdate(struct wl_client *client,
struct wl_simple_shell *shell, uint32_t surfaceId )
{
const char *name= 0;
bool visible;
int x, y, width, height;
float opacity, zorder;
wl_fixed_t fixedOpacity, fixedZOrder;
struct shell_info *info, *tmp;
if (!client || !shell || !shell->callbacks)
return;
if (shell->callbacks->get_name)
shell->callbacks->get_name( shell->userData, surfaceId, &name );
if ( !name )
name= (const char *)DEFAULT_NAME;
if (shell->callbacks->get_status) {
shell->callbacks->get_status( shell->userData, surfaceId,
&visible,
&x, &y, &width, &height,
&opacity, &zorder );
fixedOpacity= wl_fixed_from_double( (double)opacity );
fixedZOrder= wl_fixed_from_double( (double)zorder );
// Broadcast the surface update announcement to all other clients.
wl_list_for_each_safe(info, tmp, &shell->shells, link) {
if (info->client != client) {
wl_simple_shell_send_surface_status(info->resource, surfaceId,
name, (visible ? 1 : 0),
x, y, width, height, fixedOpacity, fixedZOrder);
}
}
}
}
static void wstISimpleShellSetName(struct wl_client *client,
struct wl_resource *resource,
uint32_t surfaceId, const char *name)
{
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
struct pending_broadcast_info *info, *tmp;
if ( shell ) {
if (shell->callbacks && shell->callbacks->set_name)
shell->callbacks->set_name( shell->userData, surfaceId, name );
wl_list_for_each_safe(info, tmp, &shell->pendingCreateBroadcast, link) {
if (info->surfaceId == surfaceId) {
wl_list_remove(&info->link);
free(info);
wstSimpleShellBroadcastCreation( shell, surfaceId );
break;
}
}
wstSimpleShellBroadcastSurfaceUpdate(client, shell, surfaceId );
}
}
static void wstISimpleShellSetVisible(struct wl_client *client,
struct wl_resource *resource,
uint32_t surfaceId, uint32_t visible)
{
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
if ( shell ) {
if (shell->callbacks && shell->callbacks->set_visible)
shell->callbacks->set_visible( shell->userData, surfaceId, (visible != 0) );
wstSimpleShellBroadcastSurfaceUpdate(client, shell, surfaceId );
}
}
static void wstISimpleShellSetGeometry(struct wl_client *client,
struct wl_resource *resource,
uint32_t surfaceId,
int32_t x, int32_t y, int32_t width, int32_t height)
{
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
if ( shell ) {
if (shell->callbacks && shell->callbacks->set_geometry)
shell->callbacks->set_geometry( shell->userData, surfaceId,
x, y, width, height );
wstSimpleShellBroadcastSurfaceUpdate(client, shell, surfaceId );
}
}
static void wstISimpleShellSetOpacity(struct wl_client *client,
struct wl_resource *resource,
uint32_t surfaceId,
wl_fixed_t opacity)
{
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
if ( shell ) {
float opacityLevel= wl_fixed_to_double( opacity );
if ( opacityLevel < 0.0 ) opacityLevel= 0.0;
if ( opacityLevel > 1.0 ) opacityLevel= 1.0;
if (shell->callbacks && shell->callbacks->set_opacity)
shell->callbacks->set_opacity( shell->userData, surfaceId, opacityLevel );
wstSimpleShellBroadcastSurfaceUpdate(client, shell, surfaceId );
}
}
static void wstISimpleShellSetZOrder(struct wl_client *client,
struct wl_resource *resource,
uint32_t surfaceId,
wl_fixed_t zorder)
{
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
if ( shell ) {
float zOrderLevel= wl_fixed_to_double( zorder );
if ( zOrderLevel < 0.0 ) zOrderLevel= 0.0;
if ( zOrderLevel > 1.0 ) zOrderLevel= 1.0;
if (shell->callbacks && shell->callbacks->set_zorder)
shell->callbacks->set_zorder( shell->userData, surfaceId, zOrderLevel );
wstSimpleShellBroadcastSurfaceUpdate(client, shell, surfaceId );
}
}
static void wstISimpleShellGetStatus(struct wl_client *client, struct wl_resource *resource, uint32_t surfaceId )
{
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
if ( shell ) {
const char *name= 0;
bool visible;
int x, y, width = 0, height = 0;
float opacity, zorder;
wl_fixed_t fixedOpacity, fixedZOrder;
if (shell->callbacks && shell->callbacks->get_name)
shell->callbacks->get_name( shell->userData, surfaceId, &name );
if ( !name )
name= (const char *)DEFAULT_NAME;
if (shell->callbacks && shell->callbacks->get_status) {
shell->callbacks->get_status( shell->userData, surfaceId,
&visible,
&x, &y, &width, &height,
&opacity, &zorder );
if (width == 0 && height == 0)
return;
fixedOpacity= wl_fixed_from_double( (double)opacity );
fixedZOrder= wl_fixed_from_double( (double)zorder );
wl_simple_shell_send_surface_status( resource, surfaceId,
name, (visible ? 1 : 0),
x, y, width, height, fixedOpacity, fixedZOrder );
}
}
}
static void wstISimpleShellGetSurfaces(struct wl_client *client, struct wl_resource *resource)
{
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
struct simple_shell_surface_id *surface_id, *tmp;
if ( shell ) {
wl_list_for_each_safe(surface_id, tmp, &shell->surfaces, link)
wstISimpleShellGetStatus(client, resource, surface_id->surfaceId );
wl_simple_shell_send_get_surfaces_done( resource );
}
}
static void wstISimpleShellSetFocus(struct wl_client *client, struct wl_resource *resource,
uint32_t surfaceId)
{
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
if (shell && shell->callbacks && shell->callbacks->set_focus)
shell->callbacks->set_focus(shell->userData, surfaceId);
}
static void wstISimpleShellSetScale(struct wl_client *client, struct wl_resource *resource,
uint32_t surfaceId, wl_fixed_t scaleX, wl_fixed_t scaleY)
{
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
float fScaleX= wl_fixed_to_double(scaleX);
float fScaleY= wl_fixed_to_double(scaleY);
weston_log("weston-simpleshell: wstSimpleShellSetScale: surfaceId %u scaleX %f scaleY %f\n",
surfaceId, fScaleX, fScaleY);
if (shell && shell->callbacks && shell->callbacks->set_scale)
shell->callbacks->set_scale(shell->userData, surfaceId, fScaleX, fScaleY);
}
static void wstISimpleShellSetKeyIntercept(struct wl_client * client, struct wl_resource * resource,
uint32_t surfaceId, uint32_t keyCode, uint32_t modifiers) {
weston_log("intercept key keycode:%d, surfaceId %d, modifiers %d\n", keyCode, surfaceId, modifiers);
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
if (shell && shell->callbacks)
shell->callbacks->set_key_intercept(shell->userData, surfaceId, keyCode, modifiers);
}
static void
wstISimpleShellSetMultiKeyIntercept(struct wl_client * client,
struct wl_resource * resource,
uint32_t surfaceId,
struct wl_array * keyCode,
struct wl_array * modifiers)
{
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
size_t size;
uint32_t *key_code, *modifier;
if (!keyCode || !modifiers || keyCode->size != modifiers->size)
return;
size = keyCode->size / sizeof(uint32_t);
key_code = (uint32_t *)keyCode->data;
modifier = (uint32_t *)modifiers->data;
if (shell && shell->callbacks && shell->callbacks->set_key_intercept) {
while (size--) {
shell->callbacks->set_key_intercept(shell->userData, surfaceId, *key_code, *modifier);
key_code++;
modifier++;
}
}
}
static void
wstISimpleShellRemoveMultiKeyIntercept(struct wl_client * client,
struct wl_resource * resource,
uint32_t surfaceId,
struct wl_array * keyCode,
struct wl_array * modifiers)
{
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
size_t size;
uint32_t *key_code, *modifier;
if (!keyCode || !modifiers || keyCode->size != modifiers->size)
return;
size = keyCode->size / sizeof(uint32_t);
key_code = (uint32_t *)keyCode->data;
modifier = (uint32_t *)modifiers->data;
if (shell && shell->callbacks && shell->callbacks->remove_key_intercept) {
while (size--) {
shell->callbacks->remove_key_intercept(shell->userData, surfaceId, *key_code, *modifier);
key_code++;
modifier++;
}
}
}
static void
wstISimpleShellApplyAppsZorder(struct wl_client * client,
struct wl_resource * resource,
struct wl_array * appList)
{
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
uint32_t *id;
size_t size;
int zorder = WESTON_ZORDER_DEFAULT;
if (!appList || !appList->size)
return;
id = (uint32_t *)appList->data;
size = appList->size / sizeof(uint32_t);
if (shell && shell->callbacks && shell->callbacks->set_zorder) {
while (size--) {
shell->callbacks->set_zorder(shell->userData, *id, (float)zorder / WESTON_ZORDER_MAX);
wstSimpleShellBroadcastSurfaceUpdate(client, shell, *id );
zorder += WESTON_ZORDER_INTERVAL;
id++;
}
}
}
static void
wstISimpleShellSendMultiKey(struct wl_client * client,
struct wl_resource * resource,
uint32_t surfaceId,
struct wl_array * keyCode,
struct wl_array * modifiers)
{
struct wl_simple_shell *shell =
(struct wl_simple_shell*)wl_resource_get_user_data(resource);
size_t size;
uint32_t *key_code, *modifier;
if (!keyCode || !modifiers || keyCode->size != modifiers->size)
return;
size = keyCode->size / sizeof(uint32_t);
key_code = (uint32_t *)keyCode->data;
modifier = (uint32_t *)modifiers->data;
if (shell && shell->callbacks && shell->callbacks->send_key) {
while (size--) {
shell->callbacks->send_key(shell->userData, surfaceId, *key_code, *modifier);
key_code++;
modifier++;
}
}
}
static void destroy_shell(struct wl_resource *resource)
{
struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
struct shell_info *info, *tmp;
if ( shell ) {
wl_list_for_each_safe(info, tmp, &shell->shells, link) {
if (info->resource == resource) {
wl_list_remove(&info->link);
free(info);
break;
}
}
}
}
static void wstSimpleShellBind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
{
struct wl_simple_shell *shell = (struct wl_simple_shell*)data;
struct wl_resource *resource;
struct shell_info *info;
if ( shell ) {
info = zalloc(sizeof *info);
if (info == NULL)
return;
resource= wl_resource_create(client, &wl_simple_shell_interface, MIN(version, 1), id);
if (!resource) {
wl_client_post_no_memory(client);
free(info);
return;
}
wl_resource_set_implementation(resource, &simple_shell_interface, shell, destroy_shell);
info->client= client;
info->resource= resource;
wl_list_insert(&shell->shells, &info->link);
}
}
static void wstSimpleShellBroadcastCreation( struct wl_simple_shell *shell, uint32_t surfaceId )
{
const char *name= 0;
struct shell_info *info, *tmp;
if (!shell || !shell->callbacks)
return;
// Get any name the creator may have assigned the surface
if (shell->callbacks->get_name)
shell->callbacks->get_name( shell->userData, surfaceId, &name );
if ( !name )
name= (const char *)DEFAULT_NAME;
weston_log("broadcast for surfaceId %x name %s\n", surfaceId, name);
// Broadcast the surface creation announcement
wl_list_for_each_safe(info, tmp, &shell->shells, link) {
wl_simple_shell_send_surface_created( info->resource, surfaceId, name );
}
}
static int wstSimpleShellTimeOut( void *data )
{
bool more = true;
long long now;
long long delay;
struct pending_broadcast_info *pendingInfo;
struct wl_simple_shell *shell = (struct wl_simple_shell*)data;
while ( more ) {
if (!wl_list_empty(&shell->pendingCreateBroadcast)) {
pendingInfo = wl_container_of( shell->pendingCreateBroadcast.next, pendingInfo, link);
wl_list_remove( shell->pendingCreateBroadcast.next );
wstSimpleShellBroadcastCreation( shell, pendingInfo->surfaceId );
free(pendingInfo);
if (!wl_list_empty(&shell->pendingCreateBroadcast)) {
pendingInfo = wl_container_of( shell->pendingCreateBroadcast.next, pendingInfo, link);
now = getCurrentTimeMillis();
delay = now - pendingInfo->creationTime;
if ( delay >= BROADCAST_DELAY ) {
continue;
} else {
delay = BROADCAST_DELAY - delay;
wl_event_source_timer_update( shell->delayTimer, delay );
more = false;
}
}
} else {
break;
}
}
return 0;
}
static void
WstSimpleShellDestroySurface(struct wl_listener *listener, void *data)
{
struct weston_surface *surface = (struct weston_surface *)data;
struct simple_shell_destroy_info *info =
container_of(listener,
struct simple_shell_destroy_info, destroy_surface_listener);
if (!surface || !info)
return;
WstSimpleShellNotifySurfaceDestroyed(info->shell, NULL, surface->surface_id);
wl_list_remove(&info->destroy_surface_listener.link);
free(info);
}
static void
WstSimpleShellCreateSurface(struct wl_listener *listener, void *data)
{
struct weston_surface *surface = (struct weston_surface *)data;
struct simple_shell_destroy_info *info;
struct wl_simple_shell *shell =
container_of(listener,
struct wl_simple_shell, create_surface_listener);
struct wl_client *client = wl_resource_get_client(surface->resource);
if (!shell)
return;
info = zalloc(sizeof *info);
if (info == NULL)
return;
info->shell = shell;
info->destroy_surface_listener.notify = WstSimpleShellDestroySurface;
wl_signal_add(&surface->destroy_signal,
&info->destroy_surface_listener);
surface->zorder = WESTON_ZORDER_DEFAULT;
surface->visible = true;
WstSimpleShellNotifySurfaceCreated(shell,
client, surface->resource, surface->surface_id);
}
WL_EXPORT struct wl_simple_shell* WstSimpleShellInit( struct wl_display *display,
struct wayland_simple_shell_callbacks *callbacks,
void *userData )
{
struct wl_simple_shell *shell= 0;
struct wl_event_loop *loop= 0;
struct weston_compositor *compositor = (struct weston_compositor *)userData;
weston_log("weston-simpleshell: WstSimpleShellInit: enter: display %p\n", display );
shell= (struct wl_simple_shell*)calloc( 1, sizeof(struct wl_simple_shell) );
if ( !shell )
goto exit;
shell->display= display;
shell->callbacks= callbacks;
shell->userData= userData;
wl_list_init(&shell->shells);
wl_list_init(&shell->surfaces);
wl_list_init(&shell->pendingCreateBroadcast);
loop= wl_display_get_event_loop(shell->display);
if ( !loop ) {
free( shell );
shell= 0;
goto exit;
}
shell->delayTimer= wl_event_loop_add_timer( loop, wstSimpleShellTimeOut, shell );
if ( !shell->delayTimer ) {
free( shell );
shell= 0;
goto exit;
}
shell->wl_simple_shell_global= wl_global_create(display, &wl_simple_shell_interface, 1, shell, wstSimpleShellBind );
shell->create_surface_listener.notify = WstSimpleShellCreateSurface;
wl_signal_add(&compositor->create_surface_signal,
&shell->create_surface_listener);
exit:
weston_log("weston-simpleshell: WstSimpleShellInit: exit: display %p shell %p\n", display, shell);
return shell;
}
static void clear_pending_create_broadcast(struct wl_simple_shell *shell)
{
struct pending_broadcast_info *info, *tmp;
wl_list_for_each_safe(info, tmp, &shell->pendingCreateBroadcast, link) {
wl_list_remove(&info->link);
free(info);
}
}
static void clear_surface_id(struct wl_simple_shell *shell)
{
struct simple_shell_surface_id *info, *tmp;
wl_list_for_each_safe(info, tmp, &shell->surfaces, link) {
wl_list_remove(&info->link);
free(info);
}
}
static void clear_shell_info(struct wl_simple_shell *shell)
{
struct shell_info *info, *tmp;
wl_list_for_each_safe(info, tmp, &shell->shells, link) {
wl_list_remove(&info->link);
free(info);
}
}
void WstSimpleShellUninit( struct wl_simple_shell *shell )
{
if ( shell ) {
if ( shell->delayTimer ) {
wl_event_source_remove( shell->delayTimer );
shell->delayTimer= 0;
}
wl_global_destroy( shell->wl_simple_shell_global );
clear_pending_create_broadcast(shell);
clear_surface_id(shell);
clear_shell_info(shell);
free( shell );
}
}
void WstSimpleShellNotifySurfaceCreated( struct wl_simple_shell *shell,
struct wl_client *client,
struct wl_resource *surface_resource,
uint32_t surfaceId )
{
bool creatorNotified= false;
struct simple_shell_surface_id *surface_id;
struct shell_info *info, *tmp;
if (!shell)
return;
surface_id = zalloc(sizeof *surface_id);
if (surface_id == NULL)
return;
// Add surface to list
surface_id->surfaceId = surfaceId;
wl_list_insert(&shell->surfaces, &surface_id->link);
weston_log("WstSimpleShellNotifySurfaceCreated: %d\n", surfaceId);
// Provide surface creator with surfaceId
wl_list_for_each_safe(info, tmp, &shell->shells, link) {
if (info->client == client) {
long long now;
struct pending_broadcast_info *pendingInfo;
wl_simple_shell_send_surface_id( info->resource, surface_resource, surfaceId );
pendingInfo = zalloc(sizeof *pendingInfo);
if (pendingInfo == NULL) {
wl_list_remove(&surface_id->link);
free(surface_id);
return;
}
creatorNotified= true;
// Perform the surface creation broadcast after an asynchronous
// delay to give the surface creator time to assign a name
now = getCurrentTimeMillis();
pendingInfo->creationTime = now;
pendingInfo->surfaceId = surfaceId;
wl_list_insert(&shell->pendingCreateBroadcast, &pendingInfo->link);
if (wl_list_length(&shell->pendingCreateBroadcast) == 1)
wl_event_source_timer_update( shell->delayTimer, BROADCAST_DELAY );
break;
}
}
if ( !creatorNotified )
wstSimpleShellBroadcastCreation( shell, surfaceId );
}
void WstSimpleShellNotifySurfaceDestroyed( struct wl_simple_shell *shell, struct wl_client *client, uint32_t surfaceId )
{
const char *name;
struct shell_info *info, *shelltmp;
struct simple_shell_surface_id *surface_id, *surfacetmp;
WST_UNUSED(client);
if (!shell || !shell->callbacks)
return;
// Get any name the creator may have assigned the surface
if (shell->callbacks->get_name)
shell->callbacks->get_name( shell->userData, surfaceId, &name );
if ( !name )
name= (const char *)DEFAULT_NAME;
// Broadcast the surface destruction announcement
wl_list_for_each_safe(info, shelltmp, &shell->shells, link)
wl_simple_shell_send_surface_destroyed(info->resource, surfaceId, name);
// Remove surface from list
wl_list_for_each_safe(surface_id, surfacetmp, &shell->surfaces, link) {
if (surface_id->surfaceId == surfaceId) {
wl_list_remove(&surface_id->link);
free(surface_id);
break;
}
}
//Remove surface intercept key
if (shell->callbacks->remove_key_intercept)
shell->callbacks->remove_key_intercept(shell->userData, surfaceId, 0, 0);
}