/*
 * 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;
}
