/*
 * Copyright © 2016 Quentin "Sardem FF7" Glidic
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
/*
 * (C) Copyright 2014, Fuji Xerox Co.,Ltd.  All rights reserved.
 * File name : fx-client.c
 * Title : shell client
 */
#include "config.h"

#include <string.h>
#include <assert.h>
#include "compositor.h"
#include "fx-client.h"

/* Typedefs */
struct fx_shell_client {
    struct weston_fx_shell *
        weston_fx_shell;
    struct wl_client *
        client;
    struct wl_resource *
        resource;
    struct wl_list
        surface_list;
    struct wl_signal
        destroy_signal;
};

/* Procedures */
void
fx_shell_client_add_destroy_listener(
        struct fx_shell_client *shell_client,
        struct wl_listener *listener )
{
    wl_signal_add(
            &shell_client->destroy_signal,
            listener );
}
static void
fx_shell_client_destroy( struct wl_resource *resource )
{
    struct fx_shell_client *shell_client
        = wl_resource_get_user_data( resource );
    struct wl_list *list = &shell_client->surface_list;
    struct wl_list *link, *tmp;

    wl_signal_emit(
            &shell_client->destroy_signal,
            shell_client );
    for ( link = list->next, tmp = link->next;
          link != list;
          link = tmp, tmp = link->next ) {
        wl_list_remove( link );
        wl_list_init( link );
    }
    free( shell_client );
}

struct fx_shell_client *
fx_shell_client_create(
        struct weston_fx_shell *weston_fx_shell,
        struct wl_client *client,
        wl_dispatcher_func_t dispatcher,
        const struct wl_interface *interface,
        const void *implementation,
        uint32_t version,
        uint32_t id )
{
    struct fx_shell_client *shell_client;

    shell_client = zalloc( sizeof ( struct fx_shell_client ) );
    if ( shell_client == NULL ) {
        wl_client_post_no_memory( client );
        return NULL;
    }

    shell_client->weston_fx_shell = weston_fx_shell;
    shell_client->client = client;

    wl_list_init( &shell_client->surface_list );
    wl_signal_init( &shell_client->destroy_signal );

    if ( client == NULL ) {
        return shell_client;
    }
    shell_client->resource = wl_resource_create(
            client,
            interface,
            1,
            id );
    if ( shell_client->resource == NULL ) {
        wl_client_post_no_memory( client );
        free( shell_client );
        return NULL;
    }
    if ( dispatcher != NULL ) {
        wl_resource_set_dispatcher(
                shell_client->resource,
                dispatcher,
                fx_shell_client_destroy,
                shell_client,
                fx_shell_client_destroy );
    } else {
        wl_resource_set_implementation(
                shell_client->resource,
                implementation,
                shell_client,
                fx_shell_client_destroy );
    }
    return shell_client;
}

struct weston_fx_shell *
fx_shell_client_get_weston_fx_shell( struct fx_shell_client *shell_client )
{
    return shell_client->weston_fx_shell;
}
struct wl_resource *
fx_shell_client_get_resource( struct fx_shell_client *shell_client )
{
    return shell_client->resource;
}
struct wl_list *
fx_shell_client_get_surface_list( struct fx_shell_client *shell_client )
{
    return &shell_client->surface_list;
}
WL_EXPORT struct wl_client *
fx_shell_client_get_client( struct fx_shell_client *shell_client )
{
    return shell_client->client;
}

