/*
 * va_wayland_drm.c - Wayland/DRM helpers
 *
 * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
 *
 * 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, sub license, 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 NON-INFRINGEMENT.
 * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS 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.
 */

#include "sysdeps.h"
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <sys/stat.h>
#include <xf86drm.h>
#include "va_drmcommon.h"
#include "drm/va_drm_utils.h"
#include "va_wayland_drm.h"
#include "va_wayland_private.h"
#include "wayland-drm-client-protocol.h"

typedef struct va_wayland_drm_context {
    struct va_wayland_context   base;
    struct wl_event_queue      *queue;
    struct wl_drm              *drm;
    uint32_t                    drm_name;
    struct wl_registry         *registry;
    unsigned int                is_authenticated        : 1;
} VADisplayContextWaylandDRM;

static void
drm_handle_device(void *data, struct wl_drm *drm, const char *device)
{
    VADisplayContextP const pDisplayContext = data;
    VADriverContextP const ctx = pDisplayContext->pDriverContext;
    VADisplayContextWaylandDRM * const wl_drm_ctx = pDisplayContext->opaque;
    struct drm_state * const drm_state = ctx->drm_state;
    drm_magic_t magic;
    struct stat st;
    int fd = -1;

    fd = open(device, O_RDWR);
    if (fd < 0) {
        va_wayland_error("failed to open %s: %s (errno %d)",
                         device, strerror(errno), errno);
        return;
    }

    if (fstat(fd, &st) < 0) {
        va_wayland_error("failed to identify %s: %s (errno %d)",
                         device, strerror(errno), errno);
        close(fd);
        return;
    }

    if (!S_ISCHR(st.st_mode)) {
        va_wayland_error("%s is not a device", device);
        close(fd);
        return;
    }

    drm_state->fd = fd;
    drmGetMagic(drm_state->fd, &magic);
    wl_drm_authenticate(wl_drm_ctx->drm, magic);
}

static void
drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
{
}

static void
drm_handle_authenticated(void *data, struct wl_drm *drm)
{
    VADisplayContextP const pDisplayContext = data;
    VADriverContextP const ctx = pDisplayContext->pDriverContext;
    VADisplayContextWaylandDRM * const wl_drm_ctx = pDisplayContext->opaque;
    struct drm_state * const drm_state = ctx->drm_state;

    wl_drm_ctx->is_authenticated = 1;
    drm_state->auth_type         = VA_DRM_AUTH_CUSTOM;
}

static void
drm_handle_capabilities(void *data, struct wl_drm *wl_drm, uint32_t value)
{
    VADisplayContextP const pDisplayContext = data;
    VADriverContextP const ctx = pDisplayContext->pDriverContext;
    struct VADriverVTableWayland *vtable = ctx->vtable_wayland;

    vtable->has_prime_sharing = !!(value & WL_DRM_CAPABILITY_PRIME);
}

static const struct wl_drm_listener drm_listener = {
    drm_handle_device,
    drm_handle_format,
    drm_handle_authenticated,
    drm_handle_capabilities,
};

static VAStatus
va_DisplayContextGetNumCandidates(
    VADisplayContextP pDisplayContext,
    int *candidate_index
)
{
    VADriverContextP const ctx = pDisplayContext->pDriverContext;

    return VA_DRM_GetNumCandidates(ctx, candidate_index);
}

static VAStatus
va_DisplayContextGetDriverNameByIndex(
    VADisplayContextP pDisplayContext,
    char            **driver_name_ptr,
    int             candidate_index
)
{
    VADriverContextP const ctx = pDisplayContext->pDriverContext;

    return VA_DRM_GetDriverName(ctx, driver_name_ptr, candidate_index);
}

static VAStatus
va_DisplayContextGetDriverName(
    VADisplayContextP pDisplayContext,
    char            **driver_name_ptr
)
{
    VADriverContextP const ctx = pDisplayContext->pDriverContext;

    return VA_DRM_GetDriverName(ctx, driver_name_ptr, 0);
}

void
va_wayland_drm_destroy(VADisplayContextP pDisplayContext)
{
    VADriverContextP const ctx = pDisplayContext->pDriverContext;
    struct va_wayland_drm_context * const wl_drm_ctx = pDisplayContext->opaque;
    struct drm_state * const drm_state = ctx->drm_state;
    struct VADriverVTableWayland *vtable = ctx->vtable_wayland;

    vtable->has_prime_sharing = 0;
    vtable->wl_interface = NULL;

    wl_drm_ctx->is_authenticated = 0;

    if (drm_state) {
        if (drm_state->fd >= 0) {
            close(drm_state->fd);
            drm_state->fd = -1;
        }
        free(ctx->drm_state);
        ctx->drm_state = NULL;
    }
}

static void
registry_handle_global(
    void               *data,
    struct wl_registry *registry,
    uint32_t            name,
    const char         *interface,
    uint32_t            version
)
{
    VADisplayContextP const pDisplayContext = data;
    struct va_wayland_drm_context * const wl_drm_ctx = pDisplayContext->opaque;

    if (strcmp(interface, "wl_drm") == 0) {
        /* bind to at most version 2, but also support version 1 if
         * compositor does not have v2
         */
        wl_drm_ctx->drm_name = name;
        wl_drm_ctx->drm =
            wl_registry_bind(wl_drm_ctx->registry, name, &wl_drm_interface,
                             (version < 2) ? version : 2);

        if (wl_drm_ctx->drm
            && wl_drm_add_listener(wl_drm_ctx->drm, &drm_listener, pDisplayContext) != 0) {
            va_wayland_error("could not add listener to wl_drm");
            wl_drm_destroy(wl_drm_ctx->drm);
            wl_drm_ctx->drm = NULL;
        }
    }
}

static void
registry_handle_global_remove(
    void               *data,
    struct wl_registry *registry,
    uint32_t            name
)
{
    struct va_wayland_drm_context *wl_drm_ctx = data;

    if (wl_drm_ctx->drm && name == wl_drm_ctx->drm_name) {
        wl_drm_destroy(wl_drm_ctx->drm);
        wl_drm_ctx->drm = NULL;
    }
}

static const struct wl_registry_listener registry_listener = {
    registry_handle_global,
    registry_handle_global_remove
};

static bool
wayland_roundtrip_queue(struct wl_display *display,
                         struct wl_event_queue *queue)
{
    if (wl_display_roundtrip_queue(display, queue) < 0) {
        int err = wl_display_get_error(display);
        va_wayland_error("Wayland roundtrip error: %s (errno %d)", strerror(err), err);
        return false;
    } else {
        return true;
    }
}

bool
va_wayland_drm_create(VADisplayContextP pDisplayContext)
{
    bool result = false;
    VADriverContextP const ctx = pDisplayContext->pDriverContext;
    struct va_wayland_drm_context *wl_drm_ctx;
    struct drm_state *drm_state;
    struct VADriverVTableWayland *vtable = ctx->vtable_wayland;
    struct wl_display *wrapped_display = NULL;

    vtable->wl_interface = NULL;

    wl_drm_ctx = malloc(sizeof(*wl_drm_ctx));
    if (!wl_drm_ctx) {
        va_wayland_error("could not allocate wl_drm_ctx");
        goto end;
    }
    wl_drm_ctx->base.destroy            = va_wayland_drm_destroy;
    wl_drm_ctx->queue                   = NULL;
    wl_drm_ctx->drm                     = NULL;
    wl_drm_ctx->registry                = NULL;
    wl_drm_ctx->is_authenticated        = 0;
    pDisplayContext->opaque             = wl_drm_ctx;
    pDisplayContext->vaGetDriverName    = va_DisplayContextGetDriverName;
    pDisplayContext->vaGetNumCandidates  = va_DisplayContextGetNumCandidates;
    pDisplayContext->vaGetDriverNameByIndex = va_DisplayContextGetDriverNameByIndex;

    drm_state = calloc(1, sizeof(struct drm_state));
    if (!drm_state) {
        va_wayland_error("could not allocate drm_state");
        goto end;
    }
    drm_state->fd        = -1;
    drm_state->auth_type = 0;
    ctx->drm_state       = drm_state;
    vtable->has_prime_sharing = 0;

    /* Use wrapped wl_display with private event queue to prevent
     * thread safety issues with applications that e.g. run an event pump
     * parallel to libva initialization.
     * Using the default queue, events might get lost and crashes occur
     * because wl_display_roundtrip is not thread-safe with respect to the
     * same queue.
     */
    wl_drm_ctx->queue = wl_display_create_queue(ctx->native_dpy);
    if (!wl_drm_ctx->queue) {
        va_wayland_error("could not create Wayland event queue");
        goto end;
    }

    wrapped_display = wl_proxy_create_wrapper(ctx->native_dpy);
    if (!wrapped_display) {
        va_wayland_error("could not create Wayland proxy wrapper");
        goto end;
    }

    /* All created objects will inherit this queue */
    wl_proxy_set_queue((struct wl_proxy *) wrapped_display, wl_drm_ctx->queue);
    wl_drm_ctx->registry = wl_display_get_registry(wrapped_display);
    if (!wl_drm_ctx->registry) {
        va_wayland_error("could not create wl_registry");
        goto end;
    }
    if (wl_registry_add_listener(wl_drm_ctx->registry, &registry_listener, pDisplayContext) != 0) {
        va_wayland_error("could not add listener to wl_registry");
        goto end;
    }
    if (!wayland_roundtrip_queue(ctx->native_dpy, wl_drm_ctx->queue))
        goto end;

    /* registry_handle_global should have been called by the
     * wl_display_roundtrip_queue above
     */

    /* Do not print an error, the compositor might just not support wl_drm */
    if (!wl_drm_ctx->drm)
        goto end;
    if (!wayland_roundtrip_queue(ctx->native_dpy, wl_drm_ctx->queue))
        goto end;
    if (drm_state->fd < 0) {
        va_wayland_error("did not get DRM device");
        goto end;
    }

    if (!wayland_roundtrip_queue(ctx->native_dpy, wl_drm_ctx->queue))
        goto end;

    if (!wl_drm_ctx->is_authenticated) {
        va_wayland_error("Wayland compositor did not respond to DRM authentication");
        goto end;
    }

    vtable->wl_interface = &wl_drm_interface;
    result = true;

end:
    if (wrapped_display) {
        wl_proxy_wrapper_destroy(wrapped_display);
        wrapped_display = NULL;
    }

    if (wl_drm_ctx) {
        if (wl_drm_ctx->drm) {
            wl_drm_destroy(wl_drm_ctx->drm);
            wl_drm_ctx->drm = NULL;
        }

        if (wl_drm_ctx->registry) {
            wl_registry_destroy(wl_drm_ctx->registry);
            wl_drm_ctx->registry = NULL;
        }

        if (wl_drm_ctx->queue) {
            wl_event_queue_destroy(wl_drm_ctx->queue);
            wl_drm_ctx->queue = NULL;
        }
    }

    return result;
}
