/*
 * Copyright (c) 1997, 2024, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.awt;

import java.awt.AWTException;
import java.awt.BufferCapabilities;
import java.awt.Component;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.Image;
import java.awt.ImageCapabilities;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DirectColorModel;
import java.awt.image.VolatileImage;
import java.awt.image.WritableRaster;

import sun.awt.image.OffScreenImage;
import sun.awt.image.SunVolatileImage;
import sun.awt.image.SurfaceManager;
import sun.awt.image.VolatileSurfaceManager;
import sun.java2d.Disposer;
import sun.java2d.DisposerRecord;
import sun.java2d.SurfaceData;
import sun.java2d.loops.CompositeType;
import sun.java2d.loops.RenderLoops;
import sun.java2d.loops.SurfaceType;
import sun.java2d.pipe.Region;
import sun.java2d.x11.X11SurfaceData;
import sun.java2d.x11.X11VolatileSurfaceManager;

/**
 * This is an implementation of a GraphicsConfiguration object for a
 * single X11 visual.
 *
 * @see java.awt.GraphicsEnvironment
 * @see GraphicsDevice
 */
public class X11GraphicsConfig extends GraphicsConfiguration
    implements SurfaceManager.ProxiedGraphicsConfig, SurfaceManager.Factory
{
    private final X11GraphicsDevice device;
    protected int visual;
    int depth;
    int colormap;
    ColorModel colorModel;
    long aData;
    boolean doubleBuffer;
    private Object disposerReferent = new Object();
    private BufferCapabilities bufferCaps;
    private static ImageCapabilities imageCaps =
        new ImageCapabilities(X11SurfaceData.isAccelerationEnabled());

    // will be set on native level from init()
    protected int bitsPerPixel;

    protected SurfaceType surfaceType;

    public RenderLoops solidloops;

    public static X11GraphicsConfig getConfig(X11GraphicsDevice device,
                                              int visualnum, int depth,
                                              int colormap,
                                              boolean doubleBuffer)
    {
        return new X11GraphicsConfig(device, visualnum, depth, colormap, doubleBuffer);
    }

    /*
     * Note this method is currently here for backward compatibility
     * as this was the method used in jdk 1.2 beta4 to create the
     * X11GraphicsConfig objects. Java3D code had called this method
     * explicitly so without this, if a user tries to use JDK1.2 fcs
     * with Java3D beta1, a NoSuchMethod exception is thrown and
     * the program exits. REMOVE this method after Java3D fcs is
     * released!
     */
    public static X11GraphicsConfig getConfig(X11GraphicsDevice device,
                                              int visualnum, int depth,
                                              int colormap, int type)
    {
        return new X11GraphicsConfig(device, visualnum, depth, colormap, false);
    }

    private native int getNumColors();
    private native void init(int visualNum, int screen);
    private native ColorModel makeColorModel();

    protected X11GraphicsConfig(X11GraphicsDevice device,
                                int visualnum, int depth,
                                int colormap, boolean doubleBuffer)
    {
        this.device = device;
        this.visual = visualnum;
        this.doubleBuffer = doubleBuffer;
        this.depth = depth;
        this.colormap = colormap;
        init (visualnum, device.getScreen());

        // add a record to the Disposer so that we destroy the native
        // AwtGraphicsConfigData when this object goes away (i.e. after a
        // display change event)
        long x11CfgData = getAData();
        Disposer.addRecord(disposerReferent,
                           new X11GCDisposerRecord(x11CfgData));
    }

    /**
     * Return the graphics device associated with this configuration.
     */
    @Override
    public X11GraphicsDevice getDevice() {
        return device;
    }

    /**
     * Returns the visual id associated with this configuration.
     */
    public int getVisual () {
        return visual;
    }


    /**
     * Returns the depth associated with this configuration.
     */
    public int getDepth () {
        return depth;
    }

    /**
     * Returns the colormap associated with this configuration.
     */
    public int getColormap () {
        return colormap;
    }

    /**
     * Returns a number of bits allocated per pixel
     * (might be different from depth)
     */
    public int getBitsPerPixel() {
        return bitsPerPixel;
    }

    public synchronized SurfaceType getSurfaceType() {
        if (surfaceType != null) {
            return surfaceType;
        }

        surfaceType = X11SurfaceData.getSurfaceType(this, Transparency.OPAQUE);
        return surfaceType;
    }

    @Override
    public SurfaceManager.ProxyCache getSurfaceDataProxyCache() {
        return device.getProxyCacheFor(getSurfaceType());
    }

    /**
     * Return the RenderLoops this type of destination uses for
     * solid fills and strokes.
     */
    public synchronized RenderLoops getSolidLoops(SurfaceType stype) {
        if (solidloops == null) {
            solidloops = SurfaceData.makeRenderLoops(SurfaceType.OpaqueColor,
                                                     CompositeType.SrcNoEa,
                                                     stype);
        }
        return solidloops;
    }

    /**
     * Returns the color model associated with this configuration.
     */
    @Override
    public synchronized ColorModel getColorModel() {
        if (colorModel == null)  {
            // Force SystemColors to be resolved before we create the CM
            java.awt.SystemColor.window.getRGB();
            // This method, makeColorModel(), can return null if the
            // toolkit is not initialized yet.
            // The toolkit will then call back to this routine after it
            // is initialized and makeColorModel() should return a non-null
            // colorModel.
            colorModel = makeColorModel();
            if (colorModel == null)
                colorModel = Toolkit.getDefaultToolkit ().getColorModel ();
        }

        return colorModel;
    }

    /**
     * Returns the color model associated with this configuration that
     * supports the specified transparency.
     */
    @Override
    public ColorModel getColorModel(int transparency) {
        switch (transparency) {
        case Transparency.OPAQUE:
            return getColorModel();
        case Transparency.BITMASK:
            return new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000);
        case Transparency.TRANSLUCENT:
            return ColorModel.getRGBdefault();
        default:
            return null;
        }
    }

    public static DirectColorModel createDCM32(int rMask, int gMask, int bMask,
                                               int aMask, boolean aPre) {
        return new DirectColorModel(
            ColorSpace.getInstance(ColorSpace.CS_sRGB),
            32, rMask, gMask, bMask, aMask, aPre, DataBuffer.TYPE_INT);
    }

    public static ComponentColorModel createABGRCCM() {
        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
        int[] nBits = {8, 8, 8, 8};
        int[] bOffs = {3, 2, 1, 0};
        return new ComponentColorModel(cs, nBits, true, true,
                                       Transparency.TRANSLUCENT,
                                       DataBuffer.TYPE_BYTE);
    }

    /**
     * Returns the default Transform for this configuration.  This
     * Transform is typically the Identity transform for most normal
     * screens.  Device coordinates for screen and printer devices will
     * have the origin in the upper left-hand corner of the target region of
     * the device, with X coordinates
     * increasing to the right and Y coordinates increasing downwards.
     * For image buffers, this Transform will be the Identity transform.
     */
    @Override
    public AffineTransform getDefaultTransform() {
        double scale = getScale();
        return AffineTransform.getScaleInstance(scale, scale);
    }

    public int getScale() {
        return getDevice().getScaleFactor();
    }

    public int scaleUp(int x) {
        return Region.clipRound(x * (double)getScale());
    }

    public int scaleDown(int x) {
        return Region.clipRound(x / (double)getScale());
    }

    /**
     *
     * Returns a Transform that can be composed with the default Transform
     * of a Graphics2D so that 72 units in user space will equal 1 inch
     * in device space.
     * Given a Graphics2D, g, one can reset the transformation to create
     * such a mapping by using the following pseudocode:
     * <pre>
     *      GraphicsConfiguration gc = g.getGraphicsConfiguration();
     *
     *      g.setTransform(gc.getDefaultTransform());
     *      g.transform(gc.getNormalizingTransform());
     * </pre>
     * Note that sometimes this Transform will be identity (e.g. for
     * printers or metafile output) and that this Transform is only
     * as accurate as the information supplied by the underlying system.
     * For image buffers, this Transform will be the Identity transform,
     * since there is no valid distance measurement.
     */
    @Override
    public AffineTransform getNormalizingTransform() {
        double xscale = getXResolution(device.getScreen()) / 72.0;
        double yscale = getYResolution(device.getScreen()) / 72.0;
        return new AffineTransform(xscale, 0.0, 0.0, yscale, 0.0, 0.0);
    }

    private native double getXResolution(int screen);
    private native double getYResolution(int screen);

    public long getAData() {
        return aData;
    }

    @Override
    public String toString() {
        return ("X11GraphicsConfig[dev="+device+
                ",vis=0x"+Integer.toHexString(visual)+
                "]");
    }

    /*
     * Initialize JNI field and method IDs for fields that may be
     *  accessed from C.
     */
    private static native void initIDs();

    static {
        initIDs ();
    }

    @Override
    public final Rectangle getBounds() {
        return device.getBounds();
    }

    private static final class XDBECapabilities extends BufferCapabilities {
        public XDBECapabilities() {
            super(imageCaps, imageCaps, FlipContents.UNDEFINED);
        }
    }

    @Override
    public BufferCapabilities getBufferCapabilities() {
        if (bufferCaps == null) {
            if (doubleBuffer) {
                bufferCaps = new XDBECapabilities();
            } else {
                bufferCaps = super.getBufferCapabilities();
            }
        }
        return bufferCaps;
    }

    @Override
    public ImageCapabilities getImageCapabilities() {
        return imageCaps;
    }

    public boolean isDoubleBuffered() {
        return doubleBuffer;
    }

    private static native void dispose(long x11ConfigData);

    private static final class X11GCDisposerRecord implements DisposerRecord {
        private long x11ConfigData;
        public X11GCDisposerRecord(long x11CfgData) {
            this.x11ConfigData = x11CfgData;
        }
        @Override
        public synchronized void dispose() {
            if (x11ConfigData != 0L) {
                X11GraphicsConfig.dispose(x11ConfigData);
                x11ConfigData = 0L;
            }
        }
    }

    /**
     * The following methods are invoked from {M,X}Toolkit.java and
     * X11ComponentPeer.java rather than having the X11-dependent
     * implementations hardcoded in those classes.  This way the appropriate
     * actions are taken based on the peer's GraphicsConfig, whether it is
     * an X11GraphicsConfig or a GLXGraphicsConfig.
     */

    /**
     * Creates a new SurfaceData that will be associated with the given
     * X11ComponentPeer.
     */
    public SurfaceData createSurfaceData(X11ComponentPeer peer) {
        return X11SurfaceData.createData(peer);
    }

    /**
     * Creates a new hidden-acceleration image of the given width and height
     * that is associated with the target Component.
     */
    public Image createAcceleratedImage(Component target,
                                        int width, int height)
    {
        // As of 1.7 we no longer create pmoffscreens here...
        ColorModel model = getColorModel(Transparency.OPAQUE);
        WritableRaster wr =
            model.createCompatibleWritableRaster(width, height);
        return new OffScreenImage(target, model, wr,
                                  model.isAlphaPremultiplied());
    }

    /**
     * The following methods correspond to the multibuffering methods in
     * X11ComponentPeer.java...
     */

    private native long createBackBuffer(long window, int swapAction);
    private native void swapBuffers(long window, int swapAction);

    /**
     * Attempts to create an XDBE-based backbuffer for the given peer.  If
     * the requested configuration is not natively supported, an AWTException
     * is thrown.  Otherwise, if the backbuffer creation is successful, a
     * handle to the native backbuffer is returned.
     */
    public long createBackBuffer(X11ComponentPeer peer,
                                 int numBuffers, BufferCapabilities caps)
        throws AWTException
    {
        if (!X11GraphicsDevice.isDBESupported()) {
            throw new AWTException("Page flipping is not supported");
        }
        if (numBuffers > 2) {
            throw new AWTException(
                "Only double or single buffering is supported");
        }
        BufferCapabilities configCaps = getBufferCapabilities();
        if (!configCaps.isPageFlipping()) {
            throw new AWTException("Page flipping is not supported");
        }

        long window = peer.getContentWindow();
        int swapAction = getSwapAction(caps.getFlipContents());

        return createBackBuffer(window, swapAction);
    }

    /**
     * Destroys the backbuffer object represented by the given handle value.
     */
    public native void destroyBackBuffer(long backBuffer);

    /**
     * Creates a VolatileImage that essentially wraps the target Component's
     * backbuffer, using the provided backbuffer handle.
     */
    public VolatileImage createBackBufferImage(Component target,
                                               long backBuffer)
    {
        // it is possible for the component to have size 0x0, adjust it to
        // be at least 1x1 to avoid IAE
        int w = Math.max(1, target.getWidth());
        int h = Math.max(1, target.getHeight());
        return new SunVolatileImage(target,
                                    w, h,
                                    Long.valueOf(backBuffer));
    }

    /**
     * Performs the native XDBE flip operation for the given target Component.
     */
    public void flip(X11ComponentPeer peer,
                     Component target, VolatileImage xBackBuffer,
                     int x1, int y1, int x2, int y2,
                     BufferCapabilities.FlipContents flipAction)
    {
        long window = peer.getContentWindow();
        int swapAction = getSwapAction(flipAction);
        swapBuffers(window, swapAction);
    }

    /**
     * Maps the given FlipContents constant to the associated XDBE swap
     * action constant.
     */
    private static int getSwapAction(
        BufferCapabilities.FlipContents flipAction) {
        if (flipAction == BufferCapabilities.FlipContents.BACKGROUND) {
            return 0x01;
        } else if (flipAction == BufferCapabilities.FlipContents.PRIOR) {
            return 0x02;
        } else if (flipAction == BufferCapabilities.FlipContents.COPIED) {
            return 0x03;
        } else {
            return 0x00; // UNDEFINED
        }
    }

    @Override
    public boolean isTranslucencyCapable() {
        return isTranslucencyCapable(getAData());
    }

    private native boolean isTranslucencyCapable(long x11ConfigData);

    @Override
    public VolatileSurfaceManager createVolatileManager(SunVolatileImage image,
                                                        Object context) {
        return new X11VolatileSurfaceManager(image, context);
    }
}
