/*
 * Copyright 1998-2001 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

#if sparc

/* #define DGA_DEBUG */

#ifdef DGA_DEBUG
#define DEBUG_PRINT(x)  printf x
#else
#define DEBUG_PRINT(x)
#endif

#include <dga/dga.h>
#include <unistd.h>     /* ioctl */
#include <stdlib.h>
#include <sys/mman.h>   /* mmap */
#include <sys/visual_io.h>
#include <string.h>

/* X11 */
#include <X11/Xlib.h>

#include "jni.h"
#include "jdga.h"
#include "jdgadevice.h"

#include <dlfcn.h>

#define min(x, y)       ((x) < (y) ? (x) : (y))
#define max(x, y)       ((x) > (y) ? (x) : (y))

typedef struct _SolarisDgaLibInfo SolarisDgaLibInfo;

struct _SolarisDgaLibInfo {
    /* The general (non-device specific) information */
    unsigned long       count;
    Drawable            drawable;
    Drawable            virtual_drawable;

    /* The device specific memory mapping information */
    SolarisJDgaDevInfo  *devInfo;
    SolarisJDgaWinInfo  winInfo;
};

typedef Bool IsXineramaOnFunc(Display *display);
typedef Drawable GetVirtualDrawableFunc(Display *display, Drawable drawable);

#define MAX_CACHED_INFO 16
static SolarisDgaLibInfo cachedInfo[MAX_CACHED_INFO];
static jboolean needsSync = JNI_FALSE;

#define MAX_FB_TYPES 16
static SolarisJDgaDevInfo devicesInfo[MAX_FB_TYPES];

static IsXineramaOnFunc *IsXineramaOn = NULL;
static GetVirtualDrawableFunc GetVirtualDrawableStub;

Drawable GetVirtualDrawableStub(Display *display, Drawable drawable) {
    return drawable;
}
static GetVirtualDrawableFunc * GetVirtualDrawable = GetVirtualDrawableStub;

static void Solaris_DGA_XineramaInit(Display *display) {
    void * handle = 0;
    if (IsXineramaOn == NULL) {
        handle = dlopen("libxinerama.so", RTLD_NOW);
        if (handle != 0) {
            void *sym = dlsym(handle, "IsXineramaOn");
            IsXineramaOn = (IsXineramaOnFunc *)sym;
            if (IsXineramaOn != 0 && (*IsXineramaOn)(display)) {
                sym = dlsym(handle, "GetVirtualDrawable");
                if (sym != 0) {
                    GetVirtualDrawable = (GetVirtualDrawableFunc *)sym;
                }
            } else {
                dlclose(handle);
            }
        }
    }
}

static SolarisJDgaDevInfo * getDevInfo(Dga_drawable dgadraw) {
    void *handle = 0;
    struct vis_identifier visid;
    int fd;
    char libName[64];
    int i;
    SolarisJDgaDevInfo *curDevInfo = devicesInfo;

    fd = dga_draw_devfd(dgadraw);
    if (ioctl(fd, VIS_GETIDENTIFIER, &visid) != 1) {
        /* check in the devices list */
        for (i = 0; (i < MAX_FB_TYPES) && (curDevInfo->visidName);
             i++, curDevInfo++) {
            if (strcmp(visid.name, curDevInfo->visidName) == 0) {
                /* we already have such a device, return it */
                return curDevInfo;
            }
        }
        if (i == MAX_FB_TYPES) {
            /* we're out of slots, return NULL */
            return NULL;
        }

        strcpy(libName, "libjdga");
        strcat(libName, visid.name);
        strcat(libName,".so");
        /* we use RTLD_NOW because of bug 4032715 */
        handle = dlopen(libName, RTLD_NOW);
        if (handle != 0) {
            JDgaStatus ret = JDGA_FAILED;
            void *sym = dlsym(handle, "SolarisJDgaDevOpen");
            if (sym != 0) {
                curDevInfo->majorVersion = JDGALIB_MAJOR_VERSION;
                curDevInfo->minorVersion = JDGALIB_MINOR_VERSION;
                ret = (*(SolarisJDgaDevOpenFunc *)sym)(curDevInfo);
            }
            if (ret == JDGA_SUCCESS) {
                curDevInfo->visidName = strdup(visid.name);
                return curDevInfo;
            }
            dlclose(handle);
        }
    }
    return NULL;
}
static int
mmap_dgaDev(SolarisDgaLibInfo *libInfo, Dga_drawable dgadraw)
{

    if (!libInfo->devInfo) {
        libInfo->devInfo = getDevInfo(dgadraw);
        if (!libInfo->devInfo) {
            return JDGA_FAILED;
        }
    }
    return (*libInfo->devInfo->function->winopen)(&(libInfo->winInfo));
}

static void
unmap_dgaDev(SolarisDgaLibInfo *pDevInfo)
{
    DEBUG_PRINT(("winclose() called\n"));
   (*pDevInfo->devInfo->function->winclose)(&(pDevInfo->winInfo));
}

static jboolean
Solaris_DGA_Available(Display *display)
{
    Window root;
    int screen;
    Dga_drawable dgaDrawable;
    SolarisJDgaDevInfo * devinfo;

    /* return true if any screen supports DGA and we
     have a library for this type of framebuffer */
    for (screen = 0; screen < XScreenCount(display); screen++) {
        root = RootWindow(display, screen);

        dgaDrawable = XDgaGrabDrawable(display, root);
        if (dgaDrawable != 0) {
            devinfo = getDevInfo(dgaDrawable);
            XDgaUnGrabDrawable(dgaDrawable);
            if (devinfo != NULL) {
                return JNI_TRUE;
            }
        }
    }
    return JNI_FALSE;
}

static JDgaLibInitFunc          Solaris_DGA_LibInit;
static JDgaGetLockFunc          Solaris_DGA_GetLock;
static JDgaReleaseLockFunc      Solaris_DGA_ReleaseLock;
static JDgaXRequestSentFunc     Solaris_DGA_XRequestSent;
static JDgaLibDisposeFunc       Solaris_DGA_LibDispose;
static int firstInitDone = 0;

#pragma weak JDgaLibInit = Solaris_DGA_LibInit

static JDgaStatus
Solaris_DGA_LibInit(JNIEnv *env, JDgaLibInfo *ppInfo)
{
    /* Note: DGA_INIT can be called multiple times according to docs */
    DEBUG_PRINT(("DGA_INIT called\n"));
    DGA_INIT();

    if (!Solaris_DGA_Available(ppInfo->display)) {
        return JDGA_FAILED;
    }
    Solaris_DGA_XineramaInit(ppInfo->display);

    ppInfo->pGetLock = Solaris_DGA_GetLock;
    ppInfo->pReleaseLock = Solaris_DGA_ReleaseLock;
    ppInfo->pXRequestSent = Solaris_DGA_XRequestSent;
    ppInfo->pLibDispose = Solaris_DGA_LibDispose;

    return JDGA_SUCCESS;
}

static JDgaStatus
Solaris_DGA_GetLock(JNIEnv *env, Display *display, void **dgaDev,
                        Drawable drawable, JDgaSurfaceInfo *pSurface,
                        jint lox, jint loy, jint hix, jint hiy)
{
    SolarisDgaLibInfo *pDevInfo;
    SolarisDgaLibInfo *pCachedInfo = cachedInfo;
    int vis;
    int dlox, dloy, dhix, dhiy;
    int i;
    int type, site;
    unsigned long k;
    Drawable prev_virtual_drawable = 0;
    Dga_drawable dgaDrawable;

    if (*dgaDev) {
        if (((SolarisDgaLibInfo *)(*dgaDev))->drawable != drawable) {
            *dgaDev = 0;
        }
    }

    if (*dgaDev == 0) {
        pCachedInfo = cachedInfo;
        for (i = 0 ; (i < MAX_CACHED_INFO) && (pCachedInfo->drawable) ;
             i++, pCachedInfo++) {
            if (pCachedInfo->drawable == drawable) {
                *dgaDev = pCachedInfo;
                break;
            }
        }
        if (*dgaDev == 0) {
            if (i < MAX_CACHED_INFO) { /* slot can be used for new info */
                 *dgaDev = pCachedInfo;
            } else {
                pCachedInfo = cachedInfo;
                /* find the least used slot but does not handle an overflow of
                   the counter */
                for (i = 0, k = 0xffffffff; i < MAX_CACHED_INFO ;
                     i++, pCachedInfo++) {
                    if (k > pCachedInfo->count) {
                        k = pCachedInfo->count;
                        *dgaDev = pCachedInfo;
                    }
                    pCachedInfo->count = 0; /* reset all counters */
                }
                pCachedInfo = *dgaDev;
                if (pCachedInfo->winInfo.dgaDraw != 0) {
                    XDgaUnGrabDrawable(pCachedInfo->winInfo.dgaDraw);
                }
                pCachedInfo->winInfo.dgaDraw = 0;
                /* the slot might be used for another device */
                pCachedInfo->devInfo = 0;
            }
        }
    }

    pDevInfo = *dgaDev;
    pDevInfo->drawable = drawable;

    prev_virtual_drawable = pDevInfo->virtual_drawable;
    pDevInfo->virtual_drawable = GetVirtualDrawable(display, drawable);
    if (pDevInfo->virtual_drawable == NULL) {
        /* this usually means that the drawable is spanned across
           screens in xinerama mode - we can't handle this for now */
        return JDGA_FAILED;
    } else {
        /* check if the drawable has been moved to another screen
           since last time */
        if (pDevInfo->winInfo.dgaDraw != 0 &&
            pDevInfo->virtual_drawable != prev_virtual_drawable) {
            XDgaUnGrabDrawable(pDevInfo->winInfo.dgaDraw);
            pDevInfo->winInfo.dgaDraw = 0;
        }
    }

    pDevInfo->count++;

    if (pDevInfo->winInfo.dgaDraw == 0) {
        pDevInfo->winInfo.dgaDraw = XDgaGrabDrawable(display, pDevInfo->virtual_drawable);
        if (pDevInfo->winInfo.dgaDraw == 0) {
            DEBUG_PRINT(("DgaGrabDrawable failed for 0x%08x\n", drawable));
            return JDGA_UNAVAILABLE;
        }
        type = dga_draw_type(pDevInfo->winInfo.dgaDraw);
        if (type != DGA_DRAW_PIXMAP &&
            mmap_dgaDev(pDevInfo, pDevInfo->winInfo.dgaDraw) != JDGA_SUCCESS) {
            DEBUG_PRINT(("memory map failed for 0x%08x (depth = %d)\n",
                         drawable, dga_draw_depth(pDevInfo->winInfo.dgaDraw)));
            XDgaUnGrabDrawable(pDevInfo->winInfo.dgaDraw);
            pDevInfo->winInfo.dgaDraw = 0;
            return JDGA_UNAVAILABLE;
        }
    } else {
        type = dga_draw_type(pDevInfo->winInfo.dgaDraw);
    }

    if (needsSync) {
        XSync(display, False);
        needsSync = JNI_FALSE;
    }

    dgaDrawable = pDevInfo->winInfo.dgaDraw;

    DGA_DRAW_LOCK(dgaDrawable, -1);

    site = dga_draw_site(dgaDrawable);
    if (type == DGA_DRAW_PIXMAP) {
        if (site == DGA_SITE_SYSTEM) {
            pDevInfo->winInfo.mapDepth = dga_draw_depth(dgaDrawable);
            pDevInfo->winInfo.mapAddr = dga_draw_address(dgaDrawable);
            dga_draw_bbox(dgaDrawable, &dlox, &dloy, &dhix, &dhiy);
            pDevInfo->winInfo.mapWidth = dhix;
            pDevInfo->winInfo.mapHeight = dhiy;
            if (pDevInfo->winInfo.mapDepth == 8) {
                pDevInfo->winInfo.mapLineStride = dga_draw_linebytes(dgaDrawable);
                pDevInfo->winInfo.mapPixelStride = 1;
            } else {
                pDevInfo->winInfo.mapLineStride = dga_draw_linebytes(dgaDrawable)/4;
                pDevInfo->winInfo.mapPixelStride = 4;
            }
        } else {
            XDgaUnGrabDrawable(dgaDrawable);
            pDevInfo->winInfo.dgaDraw = 0;
            return JDGA_UNAVAILABLE;
        }
    } else {
        if (site == DGA_SITE_NULL) {
            DEBUG_PRINT(("zombie drawable = 0x%08x\n", dgaDrawable));
            DGA_DRAW_UNLOCK(dgaDrawable);
            unmap_dgaDev(pDevInfo);
            XDgaUnGrabDrawable(dgaDrawable);
            pDevInfo->winInfo.dgaDraw = 0;
            return JDGA_UNAVAILABLE;
        }
        dga_draw_bbox(dgaDrawable, &dlox, &dloy, &dhix, &dhiy);
    }

    /* get the screen address of the drawable */
    dhix += dlox;
    dhiy += dloy;
    DEBUG_PRINT(("window at (%d, %d) => (%d, %d)\n", dlox, dloy, dhix, dhiy));
    pSurface->window.lox = dlox;
    pSurface->window.loy = dloy;
    pSurface->window.hix = dhix;
    pSurface->window.hiy = dhiy;

            /* translate rendering coordinates relative to device bbox */
    lox += dlox;
    loy += dloy;
    hix += dlox;
    hiy += dloy;
    DEBUG_PRINT(("render at (%d, %d) => (%d, %d)\n", lox, loy, hix, hiy));

    vis = dga_draw_visibility(dgaDrawable);
    switch (vis) {
    case DGA_VIS_UNOBSCURED:
        pSurface->visible.lox = max(dlox, lox);
        pSurface->visible.loy = max(dloy, loy);
        pSurface->visible.hix = min(dhix, hix);
        pSurface->visible.hiy = min(dhiy, hiy);
        DEBUG_PRINT(("unobscured vis at (%d, %d) => (%d, %d)\n",
                     pSurface->visible.lox,
                     pSurface->visible.loy,
                     pSurface->visible.hix,
                     pSurface->visible.hiy));
        break;
    case DGA_VIS_PARTIALLY_OBSCURED: {
        /*
         * fix for #4305271
         * the dga_draw_clipinfo call returns the clipping bounds
         * in short ints, but use only full size ints for all comparisons.
         */
        short *ptr;
        int x0, y0, x1, y1;
        int cliplox, cliploy, cliphix, cliphiy;

        /*
         * iterate to find out whether the clipped blit draws to a
         * single clipping rectangle
         */
        cliplox = cliphix = lox;
        cliploy = cliphiy = loy;
        ptr = dga_draw_clipinfo(dgaDrawable);
        while (*ptr != DGA_Y_EOL) {
            y0 = *ptr++;
            y1 = *ptr++;
            DEBUG_PRINT(("DGA y range loy=%d hiy=%d\n", y0, y1));
            if (y0 < loy) {
                y0 = loy;
            }
            if (y1 > hiy) {
                y1 = hiy;
            }
            while (*ptr != DGA_X_EOL) {
                x0 = *ptr++;
                x1 = *ptr++;
                DEBUG_PRINT(("  DGA x range lox=%d hix=%d\n", x0, x1));
                if (x0 < lox) {
                    x0 = lox;
                }
                if (x1 > hix) {
                    x1 = hix;
                }
                if (x0 < x1 && y0 < y1) {
                    if (cliploy == cliphiy) {
                                /* First rectangle intersection */
                        cliplox = x0;
                        cliploy = y0;
                        cliphix = x1;
                        cliphiy = y1;
                    } else {
                                /* Can we merge this rect with previous? */
                        if (cliplox == x0 && cliphix == x1 &&
                            cliploy <= y1 && cliphiy >= y0)
                            {
                                /* X ranges match, Y ranges touch */
                                /* => absorb the Y ranges together */
                                cliploy = min(cliploy, y0);
                                cliphiy = max(cliphiy, y1);
                            } else if (cliploy == y0 && cliphiy == y1 &&
                                       cliplox <= x1 && cliphix >= x0)
                                {
                                    /* Y ranges match, X ranges touch */
                                    /* => Absorb the X ranges together */
                                    cliplox = min(cliplox, x0);
                                    cliphix = max(cliphix, x1);
                                } else {
                                    /* Assertion: any other combination */
                                    /* means non-rectangular intersect */
                                    DGA_DRAW_UNLOCK(dgaDrawable);
                                    return JDGA_FAILED;
                                }
                    }
                }
            }
            ptr++; /* advance past DGA_X_EOL */
        }
        DEBUG_PRINT(("DGA drawable fits\n"));
        pSurface->visible.lox = cliplox;
        pSurface->visible.loy = cliploy;
        pSurface->visible.hix = cliphix;
        pSurface->visible.hiy = cliphiy;
        break;
    }
    case DGA_VIS_FULLY_OBSCURED:
        pSurface->visible.lox =
            pSurface->visible.hix = lox;
        pSurface->visible.loy =
            pSurface->visible.hiy = loy;
        DEBUG_PRINT(("fully obscured vis\n"));
        break;
    default:
        DEBUG_PRINT(("unknown visibility = %d!\n", vis));
        DGA_DRAW_UNLOCK(dgaDrawable);
        return JDGA_FAILED;
    }

    pSurface->basePtr = pDevInfo->winInfo.mapAddr;
    pSurface->surfaceScan = pDevInfo->winInfo.mapLineStride;
    pSurface->surfaceWidth = pDevInfo->winInfo.mapWidth;
    pSurface->surfaceHeight = pDevInfo->winInfo.mapHeight;
    pSurface->surfaceDepth = pDevInfo->winInfo.mapDepth;

    return JDGA_SUCCESS;
}

static JDgaStatus
Solaris_DGA_ReleaseLock(JNIEnv *env, void *dgaDev, Drawable drawable)
{
    SolarisDgaLibInfo *pDevInfo = (SolarisDgaLibInfo *) dgaDev;

    if (pDevInfo != 0 && pDevInfo->drawable == drawable &&
        pDevInfo->winInfo.dgaDraw != 0) {
        DGA_DRAW_UNLOCK(pDevInfo->winInfo.dgaDraw);
    }
    return JDGA_SUCCESS;
}

static void
Solaris_DGA_XRequestSent(JNIEnv *env, void *dgaDev, Drawable drawable)
{
    needsSync = JNI_TRUE;
}

static void
Solaris_DGA_LibDispose(JNIEnv *env)
{
    SolarisDgaLibInfo *pCachedInfo = cachedInfo;
    SolarisJDgaDevInfo *curDevInfo = devicesInfo;
    int i;

    for (i = 0 ; (i < MAX_CACHED_INFO) && (pCachedInfo->drawable) ;
         i++, pCachedInfo++) {
        if (pCachedInfo->winInfo.dgaDraw != 0) {
            if (dga_draw_type(pCachedInfo->winInfo.dgaDraw) == DGA_DRAW_WINDOW &&
                pCachedInfo->winInfo.mapDepth != 0) {
                unmap_dgaDev(pCachedInfo);
            }
            XDgaUnGrabDrawable(pCachedInfo->winInfo.dgaDraw);
            pCachedInfo->winInfo.dgaDraw = 0;
        }
    }
    for (i = 0; (i < MAX_FB_TYPES) && (curDevInfo->visidName);
         i++, curDevInfo++) {
        curDevInfo->function->devclose(curDevInfo);
        free(curDevInfo->visidName);
    }
}
#endif
