// $Id: LUTutil-X11.cpp,v 1.15 2007/11/06 00:37:41 hvengel Exp $
//  Little cms Profiler
// Copyright (C) 2007 Hal Engel
//
// THIS SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
//
// IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
// INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
// OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
// LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
// OF THIS SOFTWARE.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// Version 1.11

// FIXME needs to be updated to also support RandR 1.2
// This will need to support the current xf86VidMode extension
// calls and RandR 1.2 gamma calls for some time.
// When RandR 1.2 calls are available they sould be used in
// preference to xf86VidMode extension

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <time.h>
#include <string.h>

// X11 stuff
#include <X11/Xlib.h>
#include <X11/extensions/xf86vmode.h>

// #include <qapplication.h>

// #include "X11/extensions/randr.h"
// #include "X11/extensions/randrproto.h"
// #include <X11/extensions/Xrender.h>

#include "LUTutil.h"

gamma_ramp::gamma_ramp(int Screen, int leftIn, int topIn)
{
    
    // left and top are not used on X11
    
    display = Screen;
    screen = Screen;
    top = topIn;
    left = leftIn;
    
    size = getGammaRampSize();
    if (size > 0)
    {
        // now allocate the arrays
        ramp_buffer = new ramp_type_private[size*3];

        red = new ramp_type[size];
        green = new ramp_type[size];
        blue = new ramp_type[size];
    }
    else
    {
        ramp_buffer = 0;
        red = 0;
        green = 0;
        blue = 0;
    }
    // gamma_ramp -> size = 0 indicates
    // that the call to new gamma_ramp failed
}

gamma_ramp::~gamma_ramp()
{
    if (ramp_buffer != 0)
    {
        delete[] red;
        delete[] green;
        delete[] blue;
        delete[] ramp_buffer;
    }
}

int gamma_ramp::getGammaRampSize()
{
    int size = 0;
    int event_base;
    int error_base;
    Display *dpy;

    if ((dpy = XOpenDisplay(":0")) == NULL)
    {
        printf("failed to open display :0\n");
    }
    else
    {
        if (XF86VidModeQueryExtension(dpy, &event_base, &error_base) ==0)
        {
            printf("XF86VidModeQueryExtension failed\n");
        }
        else
        {
            if (!XF86VidModeGetGammaRampSize(dpy, display, &size))
            {
                printf("failed to get XF86VidModeGetGammaRampSize\n");
            }
//             else
//             {
//                 printf("ramdac_size = %i\n", size);
//             }
        }
        XCloseDisplay (dpy);
    }
    return size; // will be 0 if failed
}

void gamma_ramp::getGammaRamp()
{
    int event_base;
    int error_base;
    Display *dpy;

    if ((dpy = XOpenDisplay(":0")) == NULL)
    {
        printf("failed to open display :0\n");
    }
    else
    {
        if (XF86VidModeQueryExtension(dpy, &event_base, &error_base) ==0)
        {
            printf("XF86VidModeQueryExtension failed\n");
        }
        else
        {
            XF86VidModeGetGammaRamp(dpy, display, size,
                                    &ramp_buffer[0], &ramp_buffer[size],
                                    &ramp_buffer[size*2]);
            this -> convertPrivShort2ramp_type();
        }
        XCloseDisplay (dpy);
    }
}

void gamma_ramp::setGammaRamp()
{
    int event_base;
    int error_base;
    Display *dpy;

    this -> convert_ramp_type2short();

    if ((dpy = XOpenDisplay(":0")) == NULL)
    {
        printf("failed to open display :0\n");
    }
    else
    {
        if (XF86VidModeQueryExtension(dpy, &event_base, &error_base) ==0)
        {
            printf("XF86VidModeQueryExtension failed\n");
        }
        else
        {
            // printf("Screen count = %i", XScreenCount(dpy));
            XF86VidModeSetGammaRamp(dpy, display, size,
                                    &ramp_buffer[0], &ramp_buffer[size],
                                    &ramp_buffer[size*2]);
        }
        XCloseDisplay (dpy);
    }
}

