1 /* 2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * 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.Graphics; 32 import java.awt.GraphicsConfiguration; 33 import java.awt.GraphicsDevice; 34 import java.awt.GraphicsEnvironment; 35 import java.awt.Image; 36 import java.awt.ImageCapabilities; 37 import java.awt.Rectangle; 38 import java.awt.Toolkit; 39 import java.awt.Transparency; 40 import java.awt.Window; 41 import java.awt.geom.AffineTransform; 42 import java.awt.image.BufferedImage; 43 import java.awt.image.ColorModel; 44 import java.awt.image.DirectColorModel; 45 import java.awt.image.Raster; 46 import java.awt.image.VolatileImage; 47 import java.awt.image.WritableRaster; 48 49 import sun.awt.windows.WComponentPeer; 50 import sun.awt.image.OffScreenImage; 51 import sun.awt.image.SunVolatileImage; 52 import sun.awt.image.SurfaceManager; 53 import sun.java2d.SurfaceData; 54 import sun.java2d.InvalidPipeException; 55 import sun.java2d.loops.RenderLoops; 56 import sun.java2d.loops.SurfaceType; 57 import sun.java2d.loops.CompositeType; 58 import sun.java2d.windows.GDIWindowSurfaceData; 59 60 /** 61 * This is an implementation of a GraphicsConfiguration object for a 62 * single Win32 visual. 63 * 64 * @see GraphicsEnvironment 65 * @see GraphicsDevice 66 */ 67 public class Win32GraphicsConfig extends GraphicsConfiguration 68 implements DisplayChangedListener, SurfaceManager.ProxiedGraphicsConfig 69 { 70 protected Win32GraphicsDevice screen; 71 protected int visual; //PixelFormatID 72 protected RenderLoops solidloops; 73 74 private static native void initIDs(); 75 76 static { 77 initIDs(); 78 } 79 80 /** 81 * Returns a Win32GraphicsConfiguration object with the given device 82 * and PixelFormat. Note that this method does NOT check to ensure that 83 * the returned Win32GraphicsConfig will correctly support rendering into a 84 * Java window. This method is provided so that client code can do its 85 * own checking as to the appropriateness of a particular PixelFormat. 86 * Safer access to Win32GraphicsConfigurations is provided by 87 * Win32GraphicsDevice.getConfigurations(). 88 */ 89 public static Win32GraphicsConfig getConfig(Win32GraphicsDevice device, 90 int pixFormatID) 91 { 92 return new Win32GraphicsConfig(device, pixFormatID); 93 } 94 95 /** 96 * @deprecated as of JDK version 1.3 97 * replaced by <code>getConfig()</code> 98 */ 99 @Deprecated 100 public Win32GraphicsConfig(GraphicsDevice device, int visualnum) { 101 this.screen = (Win32GraphicsDevice)device; 102 this.visual = visualnum; 103 ((Win32GraphicsDevice)device).addDisplayChangedListener(this); 104 } 105 106 /** 107 * Return the graphics device associated with this configuration. 108 */ 109 public Win32GraphicsDevice getDevice() { 110 return screen; 111 } 112 113 /** 114 * Return the PixelFormatIndex this GraphicsConfig uses 115 */ 116 public int getVisual() { 117 return visual; 118 } 119 120 public Object getProxyKey() { 121 return screen; 122 } 123 124 /** 125 * Return the RenderLoops this type of destination uses for 126 * solid fills and strokes. 127 */ 128 private SurfaceType sTypeOrig = null; 129 public synchronized RenderLoops getSolidLoops(SurfaceType stype) { 130 if (solidloops == null || sTypeOrig != stype) { 131 solidloops = SurfaceData.makeRenderLoops(SurfaceType.OpaqueColor, 132 CompositeType.SrcNoEa, 133 stype); 134 sTypeOrig = stype; 135 } 136 return solidloops; 137 } 138 139 /** 140 * Returns the color model associated with this configuration. 141 */ 142 public synchronized ColorModel getColorModel() { 143 return screen.getColorModel(); 144 } 145 146 /** 147 * Returns a new color model for this configuration. This call 148 * is only used internally, by images and components that are 149 * associated with the graphics device. When attributes of that 150 * device change (for example, when the device palette is updated), 151 * then this device-based color model will be updated internally 152 * to reflect the new situation. 153 */ 154 public ColorModel getDeviceColorModel() { 155 return screen.getDynamicColorModel(); 156 } 157 158 /** 159 * Returns the color model associated with this configuration that 160 * supports the specified transparency. 161 */ 162 public ColorModel getColorModel(int transparency) { 163 switch (transparency) { 164 case Transparency.OPAQUE: 165 return getColorModel(); 166 case Transparency.BITMASK: 167 return new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000); 168 case Transparency.TRANSLUCENT: 169 return ColorModel.getRGBdefault(); 170 default: 171 return null; 172 } 173 } 174 175 /** 176 * Returns the default Transform for this configuration. This 177 * Transform is typically the Identity transform for most normal 178 * screens. Device coordinates for screen and printer devices will 179 * have the origin in the upper left-hand corner of the target region of 180 * the device, with X coordinates 181 * increasing to the right and Y coordinates increasing downwards. 182 * For image buffers, this Transform will be the Identity transform. 183 */ 184 public AffineTransform getDefaultTransform() { 185 double scaleX = screen.getDefaultScaleX(); 186 double scaleY = screen.getDefaultScaleY(); 187 return AffineTransform.getScaleInstance(scaleX, scaleY); 188 } 189 190 /** 191 * 192 * Returns a Transform that can be composed with the default Transform 193 * of a Graphics2D so that 72 units in user space will equal 1 inch 194 * in device space. 195 * Given a Graphics2D, g, one can reset the transformation to create 196 * such a mapping by using the following pseudocode: 197 * <pre> 198 * GraphicsConfiguration gc = g.getGraphicsConfiguration(); 199 * 200 * g.setTransform(gc.getDefaultTransform()); 201 * g.transform(gc.getNormalizingTransform()); 202 * </pre> 203 * Note that sometimes this Transform will be identity (e.g. for 204 * printers or metafile output) and that this Transform is only 205 * as accurate as the information supplied by the underlying system. 206 * For image buffers, this Transform will be the Identity transform, 207 * since there is no valid distance measurement. 208 */ 209 public AffineTransform getNormalizingTransform() { 210 Win32GraphicsEnvironment ge = (Win32GraphicsEnvironment) 211 GraphicsEnvironment.getLocalGraphicsEnvironment(); 212 double xscale = ge.getXResolution() / 72.0; 213 double yscale = ge.getYResolution() / 72.0; 214 return new AffineTransform(xscale, 0.0, 0.0, yscale, 0.0, 0.0); 215 } 216 217 public String toString() { 218 return (super.toString()+"[dev="+screen+",pixfmt="+visual+"]"); 219 } 220 221 private native Rectangle getBounds(int screen); 222 223 public Rectangle getBounds() { 224 return getBounds(screen.getScreen()); 225 } 226 227 public synchronized void displayChanged() { 228 solidloops = null; 229 } 230 231 public void paletteChanged() {} 232 233 /** 234 * The following methods are invoked from WComponentPeer.java rather 235 * than having the Win32-dependent implementations hardcoded in that 236 * class. This way the appropriate actions are taken based on the peer's 237 * GraphicsConfig, whether it is a Win32GraphicsConfig or a 238 * WGLGraphicsConfig. 239 */ 240 241 /** 242 * Creates a new SurfaceData that will be associated with the given 243 * WComponentPeer. 244 */ 245 public SurfaceData createSurfaceData(WComponentPeer peer, 246 int numBackBuffers) 247 { 248 return GDIWindowSurfaceData.createData(peer); 249 } 250 251 /** 252 * Creates a new managed image of the given width and height 253 * that is associated with the target Component. 254 */ 255 public Image createAcceleratedImage(Component target, 256 int width, int height) 257 { 258 ColorModel model = getColorModel(Transparency.OPAQUE); 259 WritableRaster wr = 260 model.createCompatibleWritableRaster(width, height); 261 return new OffScreenImage(target, model, wr, 262 model.isAlphaPremultiplied()); 263 } 264 265 /** 266 * The following methods correspond to the multibuffering methods in 267 * WComponentPeer.java... 268 */ 269 270 /** 271 * Checks that the requested configuration is natively supported; if not, 272 * an AWTException is thrown. 273 */ 274 public void assertOperationSupported(Component target, 275 int numBuffers, 276 BufferCapabilities caps) 277 throws AWTException 278 { 279 // the default pipeline doesn't support flip buffer strategy 280 throw new AWTException( 281 "The operation requested is not supported"); 282 } 283 284 /** 285 * This method is called from WComponentPeer when a surface data is replaced 286 * REMIND: while the default pipeline doesn't support flipping, it may 287 * happen that the accelerated device may have this graphics config 288 * (like if the device restoration failed when one device exits fs mode 289 * while others remain). 290 */ 291 public VolatileImage createBackBuffer(WComponentPeer peer) { 292 Component target = (Component)peer.getTarget(); 293 return new SunVolatileImage(target, 294 target.getWidth(), target.getHeight(), 295 Boolean.TRUE); 296 } 297 298 /** 299 * Performs the native flip operation for the given target Component. 300 * 301 * REMIND: we should really not get here because that would mean that 302 * a FLIP BufferStrategy has been created, and one could only be created 303 * if accelerated pipeline is present but in some rare (and transitional) 304 * cases it may happen that the accelerated graphics device may have a 305 * default graphics configuraiton, so this is just a precaution. 306 */ 307 public void flip(WComponentPeer peer, 308 Component target, VolatileImage backBuffer, 309 int x1, int y1, int x2, int y2, 310 BufferCapabilities.FlipContents flipAction) 311 { 312 if (flipAction == BufferCapabilities.FlipContents.COPIED || 313 flipAction == BufferCapabilities.FlipContents.UNDEFINED) { 314 Graphics g = peer.getGraphics(); 315 try { 316 g.drawImage(backBuffer, 317 x1, y1, x2, y2, 318 x1, y1, x2, y2, 319 null); 320 } finally { 321 g.dispose(); 322 } 323 } else if (flipAction == BufferCapabilities.FlipContents.BACKGROUND) { 324 Graphics g = backBuffer.getGraphics(); 325 try { 326 g.setColor(target.getBackground()); 327 g.fillRect(0, 0, 328 backBuffer.getWidth(), 329 backBuffer.getHeight()); 330 } finally { 331 g.dispose(); 332 } 333 } 334 // the rest of the flip actions are not supported 335 } 336 337 @Override 338 public boolean isTranslucencyCapable() { 339 //XXX: worth checking if 8-bit? Anyway, it doesn't hurt. 340 return true; 341 } 342 }