jdk/src/solaris/classes/sun/awt/X11GraphicsConfig.java
changeset 2 90ce3da70b43
child 438 2ae294e4518c
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package sun.awt;
       
    27 
       
    28 import java.awt.AWTException;
       
    29 import java.awt.BufferCapabilities;
       
    30 import java.awt.Component;
       
    31 import java.awt.Toolkit;
       
    32 import java.awt.GraphicsConfiguration;
       
    33 import java.awt.GraphicsDevice;
       
    34 import java.awt.Image;
       
    35 import java.awt.ImageCapabilities;
       
    36 import java.awt.image.DataBuffer;
       
    37 import java.awt.Transparency;
       
    38 import java.awt.image.BufferedImage;
       
    39 import java.awt.image.ColorModel;
       
    40 import java.awt.image.DirectColorModel;
       
    41 import java.awt.image.ImageProducer;
       
    42 import java.awt.image.IndexColorModel;
       
    43 import java.awt.image.Raster;
       
    44 import java.awt.image.VolatileImage;
       
    45 import java.awt.image.WritableRaster;
       
    46 import java.awt.geom.AffineTransform;
       
    47 import java.awt.Rectangle;
       
    48 import sun.java2d.Disposer;
       
    49 import sun.java2d.DisposerRecord;
       
    50 import sun.java2d.SurfaceData;
       
    51 import sun.java2d.loops.RenderLoops;
       
    52 import sun.java2d.loops.SurfaceType;
       
    53 import sun.java2d.loops.CompositeType;
       
    54 import sun.java2d.x11.X11SurfaceData;
       
    55 import sun.awt.image.OffScreenImage;
       
    56 import sun.awt.image.SunVolatileImage;
       
    57 import sun.awt.image.SurfaceManager;
       
    58 import sun.awt.X11ComponentPeer;
       
    59 
       
    60 /**
       
    61  * This is an implementation of a GraphicsConfiguration object for a
       
    62  * single X11 visual.
       
    63  *
       
    64  * @see GraphicsEnvironment
       
    65  * @see GraphicsDevice
       
    66  */
       
    67 public class X11GraphicsConfig extends GraphicsConfiguration
       
    68     implements SurfaceManager.ProxiedGraphicsConfig
       
    69 {
       
    70     protected X11GraphicsDevice screen;
       
    71     protected int visual;
       
    72     int depth;
       
    73     int colormap;
       
    74     ColorModel colorModel;
       
    75     long aData;
       
    76     boolean doubleBuffer;
       
    77     private Object disposerReferent = new Object();
       
    78     private BufferCapabilities bufferCaps;
       
    79     private static ImageCapabilities imageCaps =
       
    80         new ImageCapabilities(X11SurfaceData.isAccelerationEnabled());
       
    81 
       
    82     // will be set on native level from init()
       
    83     protected int bitsPerPixel;
       
    84 
       
    85     protected SurfaceType surfaceType;
       
    86 
       
    87     public RenderLoops solidloops;
       
    88 
       
    89     public static X11GraphicsConfig getConfig(X11GraphicsDevice device,
       
    90                                               int visualnum, int depth,
       
    91                                               int colormap,
       
    92                                               boolean doubleBuffer)
       
    93     {
       
    94         return new X11GraphicsConfig(device, visualnum, depth, colormap, doubleBuffer);
       
    95     }
       
    96 
       
    97     /*
       
    98      * Note this method is currently here for backward compatability
       
    99      * as this was the method used in jdk 1.2 beta4 to create the
       
   100      * X11GraphicsConfig objects. Java3D code had called this method
       
   101      * explicitly so without this, if a user tries to use JDK1.2 fcs
       
   102      * with Java3D beta1, a NoSuchMethod execption is thrown and
       
   103      * the program exits. REMOVE this method after Java3D fcs is
       
   104      * released!
       
   105      */
       
   106     public static X11GraphicsConfig getConfig(X11GraphicsDevice device,
       
   107                                               int visualnum, int depth,
       
   108                                               int colormap, int type)
       
   109     {
       
   110         return new X11GraphicsConfig(device, visualnum, depth, colormap, false);
       
   111     }
       
   112 
       
   113     private native int getNumColors();
       
   114     private native void init(int visualNum, int screen);
       
   115     private native ColorModel makeColorModel();
       
   116 
       
   117     protected X11GraphicsConfig(X11GraphicsDevice device,
       
   118                                 int visualnum, int depth,
       
   119                                 int colormap, boolean doubleBuffer)
       
   120     {
       
   121         this.screen = device;
       
   122         this.visual = visualnum;
       
   123         this.doubleBuffer = doubleBuffer;
       
   124         this.depth = depth;
       
   125         this.colormap = colormap;
       
   126         init (visualnum, screen.getScreen());
       
   127 
       
   128         // add a record to the Disposer so that we destroy the native
       
   129         // AwtGraphicsConfigData when this object goes away (i.e. after a
       
   130         // display change event)
       
   131         long x11CfgData = getAData();
       
   132         Disposer.addRecord(disposerReferent,
       
   133                            new X11GCDisposerRecord(x11CfgData));
       
   134     }
       
   135 
       
   136     /**
       
   137      * Return the graphics device associated with this configuration.
       
   138      */
       
   139     public GraphicsDevice getDevice() {
       
   140         return screen;
       
   141     }
       
   142 
       
   143     /**
       
   144      * Returns the visual id associated with this configuration.
       
   145      */
       
   146     public int getVisual () {
       
   147         return visual;
       
   148     }
       
   149 
       
   150 
       
   151     /**
       
   152      * Returns the depth associated with this configuration.
       
   153      */
       
   154     public int getDepth () {
       
   155         return depth;
       
   156     }
       
   157 
       
   158     /**
       
   159      * Returns the colormap associated with this configuration.
       
   160      */
       
   161     public int getColormap () {
       
   162         return colormap;
       
   163     }
       
   164 
       
   165     /**
       
   166      * Returns a number of bits allocated per pixel
       
   167      * (might be different from depth)
       
   168      */
       
   169     public int getBitsPerPixel() {
       
   170         return bitsPerPixel;
       
   171     }
       
   172 
       
   173     public synchronized SurfaceType getSurfaceType() {
       
   174         if (surfaceType != null) {
       
   175             return surfaceType;
       
   176         }
       
   177 
       
   178         surfaceType = X11SurfaceData.getSurfaceType(this, Transparency.OPAQUE);
       
   179         return surfaceType;
       
   180     }
       
   181 
       
   182     public Object getProxyKey() {
       
   183         return screen.getProxyKeyFor(getSurfaceType());
       
   184     }
       
   185 
       
   186     /**
       
   187      * Return the RenderLoops this type of destination uses for
       
   188      * solid fills and strokes.
       
   189      */
       
   190     public synchronized RenderLoops getSolidLoops(SurfaceType stype) {
       
   191         if (solidloops == null) {
       
   192             solidloops = SurfaceData.makeRenderLoops(SurfaceType.OpaqueColor,
       
   193                                                      CompositeType.SrcNoEa,
       
   194                                                      stype);
       
   195         }
       
   196         return solidloops;
       
   197     }
       
   198 
       
   199     /**
       
   200      * Returns the color model associated with this configuration.
       
   201      */
       
   202     public synchronized ColorModel getColorModel() {
       
   203         if (colorModel == null)  {
       
   204             // Force SystemColors to be resolved before we create the CM
       
   205             java.awt.SystemColor.window.getRGB();
       
   206             // This method, makeColorModel(), can return null if the
       
   207             // toolkit is not initialized yet.
       
   208             // The toolkit will then call back to this routine after it
       
   209             // is initialized and makeColorModel() should return a non-null
       
   210             // colorModel.
       
   211             colorModel = makeColorModel();
       
   212             if (colorModel == null)
       
   213                 colorModel = Toolkit.getDefaultToolkit ().getColorModel ();
       
   214         }
       
   215 
       
   216         return colorModel;
       
   217     }
       
   218 
       
   219     /**
       
   220      * Returns the color model associated with this configuration that
       
   221      * supports the specified transparency.
       
   222      */
       
   223     public ColorModel getColorModel(int transparency) {
       
   224         switch (transparency) {
       
   225         case Transparency.OPAQUE:
       
   226             return getColorModel();
       
   227         case Transparency.BITMASK:
       
   228             return new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000);
       
   229         case Transparency.TRANSLUCENT:
       
   230             return ColorModel.getRGBdefault();
       
   231         default:
       
   232             return null;
       
   233         }
       
   234     }
       
   235 
       
   236     /**
       
   237      * Returns the default Transform for this configuration.  This
       
   238      * Transform is typically the Identity transform for most normal
       
   239      * screens.  Device coordinates for screen and printer devices will
       
   240      * have the origin in the upper left-hand corner of the target region of
       
   241      * the device, with X coordinates
       
   242      * increasing to the right and Y coordinates increasing downwards.
       
   243      * For image buffers, this Transform will be the Identity transform.
       
   244      */
       
   245     public AffineTransform getDefaultTransform() {
       
   246         return new AffineTransform();
       
   247     }
       
   248 
       
   249     /**
       
   250      *
       
   251      * Returns a Transform that can be composed with the default Transform
       
   252      * of a Graphics2D so that 72 units in user space will equal 1 inch
       
   253      * in device space.
       
   254      * Given a Graphics2D, g, one can reset the transformation to create
       
   255      * such a mapping by using the following pseudocode:
       
   256      * <pre>
       
   257      *      GraphicsConfiguration gc = g.getGraphicsConfiguration();
       
   258      *
       
   259      *      g.setTransform(gc.getDefaultTransform());
       
   260      *      g.transform(gc.getNormalizingTransform());
       
   261      * </pre>
       
   262      * Note that sometimes this Transform will be identity (e.g. for
       
   263      * printers or metafile output) and that this Transform is only
       
   264      * as accurate as the information supplied by the underlying system.
       
   265      * For image buffers, this Transform will be the Identity transform,
       
   266      * since there is no valid distance measurement.
       
   267      */
       
   268     public AffineTransform getNormalizingTransform() {
       
   269         double xscale = getXResolution(screen.getScreen()) / 72.0;
       
   270         double yscale = getYResolution(screen.getScreen()) / 72.0;
       
   271         return new AffineTransform(xscale, 0.0, 0.0, yscale, 0.0, 0.0);
       
   272     }
       
   273 
       
   274     private native double getXResolution(int screen);
       
   275     private native double getYResolution(int screen);
       
   276 
       
   277     public long getAData() {
       
   278         return aData;
       
   279     }
       
   280 
       
   281     public String toString() {
       
   282         return ("X11GraphicsConfig[dev="+screen+
       
   283                 ",vis=0x"+Integer.toHexString(visual)+
       
   284                 "]");
       
   285     }
       
   286 
       
   287     /*
       
   288      * Initialize JNI field and method IDs for fields that may be
       
   289      *  accessed from C.
       
   290      */
       
   291     private static native void initIDs();
       
   292 
       
   293     static {
       
   294         initIDs ();
       
   295     }
       
   296 
       
   297     public Rectangle getBounds() {
       
   298         return pGetBounds(screen.getScreen());
       
   299     }
       
   300 
       
   301     public native Rectangle pGetBounds(int screenNum);
       
   302 
       
   303     private static class XDBECapabilities extends BufferCapabilities {
       
   304         public XDBECapabilities() {
       
   305             super(imageCaps, imageCaps, FlipContents.UNDEFINED);
       
   306         }
       
   307     }
       
   308 
       
   309     public BufferCapabilities getBufferCapabilities() {
       
   310         if (bufferCaps == null) {
       
   311             if (doubleBuffer) {
       
   312                 bufferCaps = new XDBECapabilities();
       
   313             } else {
       
   314                 bufferCaps = super.getBufferCapabilities();
       
   315             }
       
   316         }
       
   317         return bufferCaps;
       
   318     }
       
   319 
       
   320     public ImageCapabilities getImageCapabilities() {
       
   321         return imageCaps;
       
   322     }
       
   323 
       
   324     public boolean isDoubleBuffered() {
       
   325         return doubleBuffer;
       
   326     }
       
   327 
       
   328     private static native void dispose(long x11ConfigData);
       
   329 
       
   330     private static class X11GCDisposerRecord implements DisposerRecord {
       
   331         private long x11ConfigData;
       
   332         public X11GCDisposerRecord(long x11CfgData) {
       
   333             this.x11ConfigData = x11CfgData;
       
   334         }
       
   335         public synchronized void dispose() {
       
   336             if (x11ConfigData != 0L) {
       
   337                 X11GraphicsConfig.dispose(x11ConfigData);
       
   338                 x11ConfigData = 0L;
       
   339             }
       
   340         }
       
   341     }
       
   342 
       
   343     /**
       
   344      * The following methods are invoked from {M,X}Toolkit.java and
       
   345      * X11ComponentPeer.java rather than having the X11-dependent
       
   346      * implementations hardcoded in those classes.  This way the appropriate
       
   347      * actions are taken based on the peer's GraphicsConfig, whether it is
       
   348      * an X11GraphicsConfig or a GLXGraphicsConfig.
       
   349      */
       
   350 
       
   351     /**
       
   352      * Creates a new SurfaceData that will be associated with the given
       
   353      * X11ComponentPeer.
       
   354      */
       
   355     public SurfaceData createSurfaceData(X11ComponentPeer peer) {
       
   356         return X11SurfaceData.createData(peer);
       
   357     }
       
   358 
       
   359     /**
       
   360      * Creates a new hidden-acceleration image of the given width and height
       
   361      * that is associated with the target Component.
       
   362      */
       
   363     public Image createAcceleratedImage(Component target,
       
   364                                         int width, int height)
       
   365     {
       
   366         // As of 1.7 we no longer create pmoffscreens here...
       
   367         ColorModel model = getColorModel(Transparency.OPAQUE);
       
   368         WritableRaster wr =
       
   369             model.createCompatibleWritableRaster(width, height);
       
   370         return new OffScreenImage(target, model, wr,
       
   371                                   model.isAlphaPremultiplied());
       
   372     }
       
   373 
       
   374     /**
       
   375      * The following methods correspond to the multibuffering methods in
       
   376      * X11ComponentPeer.java...
       
   377      */
       
   378 
       
   379     private native long createBackBuffer(long window, int swapAction);
       
   380     private native void swapBuffers(long window, int swapAction);
       
   381 
       
   382     /**
       
   383      * Attempts to create an XDBE-based backbuffer for the given peer.  If
       
   384      * the requested configuration is not natively supported, an AWTException
       
   385      * is thrown.  Otherwise, if the backbuffer creation is successful, a
       
   386      * handle to the native backbuffer is returned.
       
   387      */
       
   388     public long createBackBuffer(X11ComponentPeer peer,
       
   389                                  int numBuffers, BufferCapabilities caps)
       
   390         throws AWTException
       
   391     {
       
   392         if (!X11GraphicsDevice.isDBESupported()) {
       
   393             throw new AWTException("Page flipping is not supported");
       
   394         }
       
   395         if (numBuffers > 2) {
       
   396             throw new AWTException(
       
   397                 "Only double or single buffering is supported");
       
   398         }
       
   399         BufferCapabilities configCaps = getBufferCapabilities();
       
   400         if (!configCaps.isPageFlipping()) {
       
   401             throw new AWTException("Page flipping is not supported");
       
   402         }
       
   403 
       
   404         long window = peer.getContentWindow();
       
   405         int swapAction = getSwapAction(caps.getFlipContents());
       
   406 
       
   407         return createBackBuffer(window, swapAction);
       
   408     }
       
   409 
       
   410     /**
       
   411      * Destroys the backbuffer object represented by the given handle value.
       
   412      */
       
   413     public native void destroyBackBuffer(long backBuffer);
       
   414 
       
   415     /**
       
   416      * Creates a VolatileImage that essentially wraps the target Component's
       
   417      * backbuffer, using the provided backbuffer handle.
       
   418      */
       
   419     public VolatileImage createBackBufferImage(Component target,
       
   420                                                long backBuffer)
       
   421     {
       
   422         return new SunVolatileImage(target,
       
   423                                     target.getWidth(), target.getHeight(),
       
   424                                     new Long(backBuffer));
       
   425     }
       
   426 
       
   427     /**
       
   428      * Performs the native XDBE flip operation for the given target Component.
       
   429      */
       
   430     public void flip(X11ComponentPeer peer,
       
   431                      Component target, VolatileImage xBackBuffer,
       
   432                      BufferCapabilities.FlipContents flipAction)
       
   433     {
       
   434         long window = peer.getContentWindow();
       
   435         int swapAction = getSwapAction(flipAction);
       
   436         swapBuffers(window, swapAction);
       
   437     }
       
   438 
       
   439     /**
       
   440      * Maps the given FlipContents constant to the associated XDBE swap
       
   441      * action constant.
       
   442      */
       
   443     private static int getSwapAction(
       
   444         BufferCapabilities.FlipContents flipAction) {
       
   445         if (flipAction == BufferCapabilities.FlipContents.BACKGROUND) {
       
   446             return 0x01;
       
   447         } else if (flipAction == BufferCapabilities.FlipContents.PRIOR) {
       
   448             return 0x02;
       
   449         } else if (flipAction == BufferCapabilities.FlipContents.COPIED) {
       
   450             return 0x03;
       
   451         } else {
       
   452             return 0x00; // UNDEFINED
       
   453         }
       
   454     }
       
   455 }