/*
 * Copyright © 2013 Ran Benita
 *
 * 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.
 */

#include "x11-priv.h"

XKB_EXPORT int
xkb_x11_setup_xkb_extension(xcb_connection_t *conn,
                            uint16_t major_xkb_version,
                            uint16_t minor_xkb_version,
                            enum xkb_x11_setup_xkb_extension_flags flags,
                            uint16_t *major_xkb_version_out,
                            uint16_t *minor_xkb_version_out,
                            uint8_t *base_event_out,
                            uint8_t *base_error_out)
{
    uint8_t base_event, base_error;
    uint16_t server_major, server_minor;

    if (flags & ~(XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS)) {
        /* log_err_func(ctx, "unrecognized flags: %#x\n", flags); */
        return 0;
    }

    {
        const xcb_query_extension_reply_t *reply =
            xcb_get_extension_data(conn, &xcb_xkb_id);
        if (!reply) {
            /* log_err_func(ctx, "failed to query for XKB extension\n"); */
            return 0;
        }

        if (!reply->present) {
            /* log_err_func(ctx, "failed to start using XKB extension: not available in server\n"); */
            return 0;
        }

        base_event = reply->first_event;
        base_error = reply->first_error;
    }

    {
        xcb_generic_error_t *error = NULL;
        xcb_xkb_use_extension_cookie_t cookie =
            xcb_xkb_use_extension(conn, major_xkb_version, minor_xkb_version);
        xcb_xkb_use_extension_reply_t *reply =
            xcb_xkb_use_extension_reply(conn, cookie, &error);

        if (!reply) {
            /* log_err_func(ctx, */
            /*              "failed to start using XKB extension: error code %d\n", */
            /*              error ? error->error_code : -1); */
            free(error);
            return 0;
        }

        if (!reply->supported) {
            /* log_err_func(ctx, */
            /*              "failed to start using XKB extension: server doesn't support version %d.%d\n", */
            /*              major_xkb_version, minor_xkb_version); */
            free(reply);
            return 0;
        }

        server_major = reply->serverMajor;
        server_minor = reply->serverMinor;

        free(reply);
    }

    /*
    * The XkbUseExtension() in libX11 has a *bunch* of legacy stuff, but
    * it doesn't seem like any of it is useful to us.
    */

    if (major_xkb_version_out)
        *major_xkb_version_out = server_major;
    if (minor_xkb_version_out)
        *minor_xkb_version_out = server_minor;
    if (base_event_out)
        *base_event_out = base_event;
    if (base_error_out)
        *base_error_out = base_error;

    return 1;
}

XKB_EXPORT int32_t
xkb_x11_get_core_keyboard_device_id(xcb_connection_t *conn)
{
    int32_t device_id;
    xcb_xkb_get_device_info_cookie_t cookie =
        xcb_xkb_get_device_info(conn, XCB_XKB_ID_USE_CORE_KBD,
                                0, 0, 0, 0, 0, 0);
    xcb_xkb_get_device_info_reply_t *reply =
        xcb_xkb_get_device_info_reply(conn, cookie, NULL);

    if (!reply)
        return -1;

    device_id = reply->deviceID;
    free(reply);
    return device_id;
}

bool
get_atom_name(xcb_connection_t *conn, xcb_atom_t atom, char **out)
{
    xcb_get_atom_name_cookie_t cookie;
    xcb_get_atom_name_reply_t *reply;
    int length;
    char *name;

    if (atom == 0) {
        *out = NULL;
        return true;
    }

    cookie = xcb_get_atom_name(conn, atom);
    reply = xcb_get_atom_name_reply(conn, cookie, NULL);
    if (!reply)
        return false;

    length = xcb_get_atom_name_name_length(reply);
    name = xcb_get_atom_name_name(reply);

    *out = strndup(name, length);
    if (!*out) {
        free(reply);
        return false;
    }

    free(reply);
    return true;
}

bool
adopt_atoms(struct xkb_context *ctx, xcb_connection_t *conn,
            const xcb_atom_t *from, xkb_atom_t *to, const size_t count)
{
    enum { SIZE = 128 };
    xcb_get_atom_name_cookie_t cookies[SIZE];
    const size_t num_batches = ROUNDUP(count, SIZE) / SIZE;

    /* Send and collect the atoms in batches of reasonable SIZE. */
    for (size_t batch = 0; batch < num_batches; batch++) {
        const size_t start = batch * SIZE;
        const size_t stop = min((batch + 1) * SIZE, count);

        /* Send. */
        for (size_t i = start; i < stop; i++)
            if (from[i] != XCB_ATOM_NONE)
                cookies[i % SIZE] = xcb_get_atom_name(conn, from[i]);

        /* Collect. */
        for (size_t i = start; i < stop; i++) {
            xcb_get_atom_name_reply_t *reply;

            if (from[i] == XCB_ATOM_NONE) {
                to[i] = XKB_ATOM_NONE;
                continue;
            }

            reply = xcb_get_atom_name_reply(conn, cookies[i % SIZE], NULL);
            if (!reply)
                goto err_discard;

            to[i] = xkb_atom_intern(ctx,
                                    xcb_get_atom_name_name(reply),
                                    xcb_get_atom_name_name_length(reply));
            free(reply);

            if (to[i] == XKB_ATOM_NONE)
                goto err_discard;

            continue;

            /*
             * If we don't discard the uncollected replies, they just
             * sit in the XCB queue waiting forever. Sad.
             */
err_discard:
            for (size_t j = i + 1; j < stop; j++)
                if (from[j] != XCB_ATOM_NONE)
                    xcb_discard_reply(conn, cookies[j % SIZE].sequence);
            return false;
        }
    }

    return true;
}

bool
adopt_atom(struct xkb_context *ctx, xcb_connection_t *conn, xcb_atom_t atom,
           xkb_atom_t *out)
{
    return adopt_atoms(ctx, conn, &atom, out, 1);
}
