/*
 * Copyright (c) 2008 NVIDIA, Corporation
 *
 * 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.
 */

#define _GNU_SOURCE 1
#include "sysdeps.h"
#include <string.h>

#define NEED_REPLIES
#include <stdlib.h>
#include <X11/Xlibint.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#include "va_nvctrl.h"

#define NV_CONTROL_ERRORS 0
#define NV_CONTROL_EVENTS 5
#define NV_CONTROL_NAME "NV-CONTROL"

#define NV_CTRL_TARGET_TYPE_X_SCREEN   0
#define NV_CTRL_TARGET_TYPE_GPU        1
#define NV_CTRL_TARGET_TYPE_FRAMELOCK  2
#define NV_CTRL_TARGET_TYPE_VCSC       3 /* Visual Computing System */

#define NV_CTRL_STRING_NVIDIA_DRIVER_VERSION                    3  /* R--G */

#define X_nvCtrlQueryExtension                      0
#define X_nvCtrlIsNv                                1
#define X_nvCtrlQueryStringAttribute                4

typedef struct {
    CARD8 reqType;
    CARD8 nvReqType;
    CARD16 length B16;
} xnvCtrlQueryExtensionReq;
#define sz_xnvCtrlQueryExtensionReq 4

typedef struct {
    BYTE type;   /* X_Reply */
    CARD8 padb1;
    CARD16 sequenceNumber B16;
    CARD32 length B32;
    CARD16 major B16;
    CARD16 minor B16;
    CARD32 padl4 B32;
    CARD32 padl5 B32;
    CARD32 padl6 B32;
    CARD32 padl7 B32;
    CARD32 padl8 B32;
} xnvCtrlQueryExtensionReply;
#define sz_xnvCtrlQueryExtensionReply 32

typedef struct {
    CARD8 reqType;
    CARD8 nvReqType;
    CARD16 length B16;
    CARD32 screen B32;
} xnvCtrlIsNvReq;
#define sz_xnvCtrlIsNvReq 8

typedef struct {
    BYTE type;   /* X_Reply */
    CARD8 padb1;
    CARD16 sequenceNumber B16;
    CARD32 length B32;
    CARD32 isnv B32;
    CARD32 padl4 B32;
    CARD32 padl5 B32;
    CARD32 padl6 B32;
    CARD32 padl7 B32;
    CARD32 padl8 B32;
} xnvCtrlIsNvReply;
#define sz_xnvCtrlIsNvReply 32

typedef struct {
    CARD8 reqType;
    CARD8 nvReqType;
    CARD16 length B16;
    CARD16 target_id B16;    /* X screen number or GPU number */
    CARD16 target_type B16;  /* X screen or GPU */
    CARD32 display_mask B32;
    CARD32 attribute B32;
} xnvCtrlQueryStringAttributeReq;
#define sz_xnvCtrlQueryStringAttributeReq 16

typedef struct {
    BYTE type;
    BYTE pad0;
    CARD16 sequenceNumber B16;
    CARD32 length B32;
    CARD32 flags B32;
    CARD32 n B32;    /* Length of string */
    CARD32 pad4 B32;
    CARD32 pad5 B32;
    CARD32 pad6 B32;
    CARD32 pad7 B32;
} xnvCtrlQueryStringAttributeReply;
#define sz_xnvCtrlQueryStringAttributeReply 32

#define NVCTRL_EXT_NEED_CHECK          (XPointer)(~0)
#define NVCTRL_EXT_NEED_NOTHING        (XPointer)(0)
#define NVCTRL_EXT_NEED_TARGET_SWAP    (XPointer)(1)

static XExtensionInfo _nvctrl_ext_info_data;
static XExtensionInfo *nvctrl_ext_info = &_nvctrl_ext_info_data;
static /* const */ char *nvctrl_extension_name = NV_CONTROL_NAME;

#define XNVCTRLCheckExtension(dpy,i,val) \
  XextCheckExtension (dpy, i, nvctrl_extension_name, val)
#define XNVCTRLSimpleCheckExtension(dpy,i) \
  XextSimpleCheckExtension (dpy, i, nvctrl_extension_name)

static int close_display();
static /* const */ XExtensionHooks nvctrl_extension_hooks = {
    NULL,                               /* create_gc */
    NULL,                               /* copy_gc */
    NULL,                               /* flush_gc */
    NULL,                               /* free_gc */
    NULL,                               /* create_font */
    NULL,                               /* free_font */
    close_display,                      /* close_display */
    NULL,                               /* wire_to_event */
    NULL,                               /* event_to_wire */
    NULL,                               /* error */
    NULL,                               /* error_string */
};

static XEXT_GENERATE_FIND_DISPLAY(find_display, nvctrl_ext_info,
                                  nvctrl_extension_name,
                                  &nvctrl_extension_hooks,
                                  NV_CONTROL_EVENTS, NVCTRL_EXT_NEED_CHECK)

static XEXT_GENERATE_CLOSE_DISPLAY(close_display, nvctrl_ext_info)

static Bool XNVCTRLQueryVersion(Display *dpy, int *major, int *minor);

/*
 * NV-CONTROL versions 1.8 and 1.9 pack the target_type and target_id
 * fields in reversed order.  In order to talk to one of these servers,
 * we need to swap these fields.
 */
static void XNVCTRLCheckTargetData(Display *dpy, XExtDisplayInfo *info,
                                   int *target_type, int *target_id)
{
    /* Find out what the server's NV-CONTROL version is and
     * setup for swapping if we need to.
     */
    if (info->data == NVCTRL_EXT_NEED_CHECK) {
        int major, minor;

        if (XNVCTRLQueryVersion(dpy, &major, &minor)) {
            if (major == 1 &&
                (minor == 8 || minor == 9)) {
                info->data = NVCTRL_EXT_NEED_TARGET_SWAP;
            } else {
                info->data = NVCTRL_EXT_NEED_NOTHING;
            }
        } else {
            info->data = NVCTRL_EXT_NEED_NOTHING;
        }
    }

    /* We need to swap the target_type and target_id */
    if (info->data == NVCTRL_EXT_NEED_TARGET_SWAP) {
        int tmp;
        tmp = *target_type;
        *target_type = *target_id;
        *target_id = tmp;
    }
}


static Bool XNVCTRLQueryExtension(
    Display *dpy,
    int *event_basep,
    int *error_basep
)
{
    XExtDisplayInfo *info = find_display(dpy);

    if (XextHasExtension(info)) {
        if (event_basep) *event_basep = info->codes->first_event;
        if (error_basep) *error_basep = info->codes->first_error;
        return True;
    } else {
        return False;
    }
}


static Bool XNVCTRLQueryVersion(
    Display *dpy,
    int *major,
    int *minor
)
{
    XExtDisplayInfo *info = find_display(dpy);
    xnvCtrlQueryExtensionReply rep;
    xnvCtrlQueryExtensionReq   *req;

    if (!XextHasExtension(info))
        return False;

    XNVCTRLCheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(nvCtrlQueryExtension, req);
    req->reqType = info->codes->major_opcode;
    req->nvReqType = X_nvCtrlQueryExtension;
    if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
        UnlockDisplay(dpy);
        SyncHandle();
        return False;
    }
    if (major) *major = rep.major;
    if (minor) *minor = rep.minor;
    UnlockDisplay(dpy);
    SyncHandle();
    return True;
}


static Bool XNVCTRLIsNvScreen(
    Display *dpy,
    int screen
)
{
    XExtDisplayInfo *info = find_display(dpy);
    xnvCtrlIsNvReply rep;
    xnvCtrlIsNvReq   *req;
    Bool isnv;

    if (!XextHasExtension(info))
        return False;

    XNVCTRLCheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(nvCtrlIsNv, req);
    req->reqType = info->codes->major_opcode;
    req->nvReqType = X_nvCtrlIsNv;
    req->screen = screen;
    if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
        UnlockDisplay(dpy);
        SyncHandle();
        return False;
    }
    isnv = rep.isnv;
    UnlockDisplay(dpy);
    SyncHandle();
    return isnv;
}


static Bool XNVCTRLQueryTargetStringAttribute(
    Display *dpy,
    int target_type,
    int target_id,
    unsigned int display_mask,
    unsigned int attribute,
    char **ptr
)
{
    XExtDisplayInfo *info = find_display(dpy);
    xnvCtrlQueryStringAttributeReply rep;
    xnvCtrlQueryStringAttributeReq   *req;
    Bool exists;
    int length, numbytes, slop;

    if (!ptr) return False;

    if (!XextHasExtension(info))
        return False;

    XNVCTRLCheckExtension(dpy, info, False);
    XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);

    LockDisplay(dpy);
    GetReq(nvCtrlQueryStringAttribute, req);
    req->reqType = info->codes->major_opcode;
    req->nvReqType = X_nvCtrlQueryStringAttribute;
    req->target_type = target_type;
    req->target_id = target_id;
    req->display_mask = display_mask;
    req->attribute = attribute;
    if (!_XReply(dpy, (xReply *) &rep, 0, False)) {
        UnlockDisplay(dpy);
        SyncHandle();
        return False;
    }
    length = rep.length;
    numbytes = rep.n;
    slop = numbytes & 3;
    *ptr = (char *) Xmalloc(numbytes);
    if (! *ptr) {
        _XEatData(dpy, length);
        UnlockDisplay(dpy);
        SyncHandle();
        return False;
    } else {
        _XRead(dpy, (char *) *ptr, numbytes);
        if (slop) _XEatData(dpy, 4 - slop);
    }
    exists = rep.flags;
    UnlockDisplay(dpy);
    SyncHandle();
    return exists;
}

static Bool XNVCTRLQueryStringAttribute(
    Display *dpy,
    int screen,
    unsigned int display_mask,
    unsigned int attribute,
    char **ptr
)
{
    return XNVCTRLQueryTargetStringAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN,
            screen, display_mask,
            attribute, ptr);
}


Bool VA_NVCTRLQueryDirectRenderingCapable(Display *dpy, int screen,
        Bool *isCapable)
{
    int event_base;
    int error_base;

    if (isCapable)
        *isCapable = False;

    if (!XNVCTRLQueryExtension(dpy, &event_base, &error_base))
        return False;

    if (isCapable && XNVCTRLIsNvScreen(dpy, screen))
        *isCapable = True;

    return True;
}

Bool VA_NVCTRLGetClientDriverName(Display *dpy, int screen,
                                  int *ddxDriverMajorVersion, int *ddxDriverMinorVersion,
                                  int *ddxDriverPatchVersion, char **clientDriverName)
{
    if (ddxDriverMajorVersion)
        *ddxDriverMajorVersion = 0;
    if (ddxDriverMinorVersion)
        *ddxDriverMinorVersion = 0;
    if (ddxDriverPatchVersion)
        *ddxDriverPatchVersion = 0;
    if (clientDriverName)
        *clientDriverName = NULL;

    char *nvidia_driver_version = NULL;
    if (!XNVCTRLQueryStringAttribute(dpy, screen, 0, NV_CTRL_STRING_NVIDIA_DRIVER_VERSION, &nvidia_driver_version))
        return False;

    char *end, *str = nvidia_driver_version;
    unsigned long v = strtoul(str, &end, 10);
    if (end && end != str) {
        if (ddxDriverMajorVersion)
            *ddxDriverMajorVersion = v;
        if (*(str = end) == '.') {
            v = strtoul(str + 1, &end, 10);
            if (end && end != str && (*end == '.' || *end == '\0')) {
                if (ddxDriverMinorVersion)
                    *ddxDriverMinorVersion = v;
                if (*(str = end) == '.') {
                    v = strtoul(str + 1, &end, 10);
                    if (end && end != str && *end == '\0') {
                        if (ddxDriverPatchVersion)
                            *ddxDriverPatchVersion = v;
                    }
                }
            }
        }
    }
    Xfree(nvidia_driver_version);

    if (clientDriverName)
        *clientDriverName = strdup("nvidia");

    return True;
}
