001: /*
002: * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.awt;
027:
028: import java.awt.AWTException;
029: import java.awt.BufferCapabilities;
030: import java.awt.Component;
031: import java.awt.Graphics;
032: import java.awt.GraphicsConfiguration;
033: import java.awt.GraphicsDevice;
034: import java.awt.GraphicsEnvironment;
035: import java.awt.Image;
036: import java.awt.ImageCapabilities;
037: import java.awt.Rectangle;
038: import java.awt.Toolkit;
039: import java.awt.Transparency;
040: import java.awt.Window;
041: import java.awt.geom.AffineTransform;
042: import java.awt.image.BufferedImage;
043: import java.awt.image.ColorModel;
044: import java.awt.image.DirectColorModel;
045: import java.awt.image.Raster;
046: import java.awt.image.VolatileImage;
047: import java.awt.image.WritableRaster;
048:
049: import sun.awt.windows.WComponentPeer;
050: import sun.awt.image.OffScreenImage;
051: import sun.awt.image.SunVolatileImage;
052: import sun.awt.image.SurfaceManager;
053: import sun.java2d.SurfaceData;
054: import sun.java2d.InvalidPipeException;
055: import sun.java2d.loops.RenderLoops;
056: import sun.java2d.loops.SurfaceType;
057: import sun.java2d.loops.CompositeType;
058: import sun.java2d.windows.Win32SurfaceData;
059: import sun.java2d.windows.WinBackBuffer;
060: import sun.java2d.windows.WindowsFlags;
061:
062: /**
063: * This is an implementation of a GraphicsConfiguration object for a
064: * single Win32 visual.
065: *
066: * @see GraphicsEnvironment
067: * @see GraphicsDevice
068: * @version 10 Feb 1997
069: */
070: public class Win32GraphicsConfig extends GraphicsConfiguration
071: implements DisplayChangedListener,
072: SurfaceManager.ProxiedGraphicsConfig {
073: protected Win32GraphicsDevice screen;
074: protected int visual; //PixelFormatID
075: protected RenderLoops solidloops;
076: private static BufferCapabilities bufferCaps;
077: private static ImageCapabilities imageCaps;
078:
079: private static native void initIDs();
080:
081: static {
082: initIDs();
083: }
084:
085: /**
086: * Returns a Win32GraphicsConfiguration object with the given device
087: * and PixelFormat. Note that this method does NOT check to ensure that
088: * the returned Win32GraphicsConfig will correctly support rendering into a
089: * Java window. This method is provided so that client code can do its
090: * own checking as to the appropriateness of a particular PixelFormat.
091: * Safer access to Win32GraphicsConfigurations is provided by
092: * Win32GraphicsDevice.getConfigurations().
093: */
094: public static Win32GraphicsConfig getConfig(
095: Win32GraphicsDevice device, int pixFormatID) {
096: return new Win32GraphicsConfig(device, pixFormatID);
097: }
098:
099: /**
100: * @deprecated as of JDK version 1.3
101: * replaced by <code>getConfig()</code>
102: */
103: @Deprecated
104: public Win32GraphicsConfig(GraphicsDevice device, int visualnum) {
105: this .screen = (Win32GraphicsDevice) device;
106: this .visual = visualnum;
107: ((Win32GraphicsDevice) device).addDisplayChangedListener(this );
108: }
109:
110: /**
111: * Return the graphics device associated with this configuration.
112: */
113: public GraphicsDevice getDevice() {
114: return screen;
115: }
116:
117: /**
118: * Return the PixelFormatIndex this GraphicsConfig uses
119: */
120: public int getVisual() {
121: return visual;
122: }
123:
124: public Object getProxyKey() {
125: return screen;
126: }
127:
128: /**
129: * Return the RenderLoops this type of destination uses for
130: * solid fills and strokes.
131: */
132: private SurfaceType sTypeOrig = null;
133:
134: public synchronized RenderLoops getSolidLoops(SurfaceType stype) {
135: if (solidloops == null || sTypeOrig != stype) {
136: solidloops = SurfaceData.makeRenderLoops(
137: SurfaceType.OpaqueColor, CompositeType.SrcNoEa,
138: stype);
139: sTypeOrig = stype;
140: }
141: return solidloops;
142: }
143:
144: /**
145: * Returns the color model associated with this configuration.
146: */
147: public synchronized ColorModel getColorModel() {
148: return screen.getColorModel();
149: }
150:
151: /**
152: * Returns a new color model for this configuration. This call
153: * is only used internally, by images and components that are
154: * associated with the graphics device. When attributes of that
155: * device change (for example, when the device palette is updated),
156: * then this device-based color model will be updated internally
157: * to reflect the new situation.
158: */
159: public ColorModel getDeviceColorModel() {
160: return screen.getDynamicColorModel();
161: }
162:
163: /**
164: * Returns the color model associated with this configuration that
165: * supports the specified transparency.
166: */
167: public ColorModel getColorModel(int transparency) {
168: switch (transparency) {
169: case Transparency.OPAQUE:
170: return getColorModel();
171: case Transparency.BITMASK:
172: return new DirectColorModel(25, 0xff0000, 0xff00, 0xff,
173: 0x1000000);
174: case Transparency.TRANSLUCENT:
175: return getTranslucentColorModel();
176: default:
177: return null;
178: }
179: }
180:
181: private static final int DCM_4444_RED_MASK = 0x0f00;
182: private static final int DCM_4444_GRN_MASK = 0x00f0;
183: private static final int DCM_4444_BLU_MASK = 0x000f;
184: private static final int DCM_4444_ALP_MASK = 0xf000;
185: static ColorModel translucentCM = null;
186:
187: public static ColorModel getTranslucentColorModel() {
188: if (WindowsFlags.getD3DTexBpp() == 16) {
189: if (translucentCM == null) {
190: translucentCM = new DirectColorModel(16,
191: DCM_4444_RED_MASK, DCM_4444_GRN_MASK,
192: DCM_4444_BLU_MASK, DCM_4444_ALP_MASK);
193: }
194: return translucentCM;
195: } else {
196: return ColorModel.getRGBdefault();
197: }
198: }
199:
200: /**
201: * Returns the default Transform for this configuration. This
202: * Transform is typically the Identity transform for most normal
203: * screens. Device coordinates for screen and printer devices will
204: * have the origin in the upper left-hand corner of the target region of
205: * the device, with X coordinates
206: * increasing to the right and Y coordinates increasing downwards.
207: * For image buffers, this Transform will be the Identity transform.
208: */
209: public AffineTransform getDefaultTransform() {
210: return new AffineTransform();
211: }
212:
213: /**
214: *
215: * Returns a Transform that can be composed with the default Transform
216: * of a Graphics2D so that 72 units in user space will equal 1 inch
217: * in device space.
218: * Given a Graphics2D, g, one can reset the transformation to create
219: * such a mapping by using the following pseudocode:
220: * <pre>
221: * GraphicsConfiguration gc = g.getGraphicsConfiguration();
222: *
223: * g.setTransform(gc.getDefaultTransform());
224: * g.transform(gc.getNormalizingTransform());
225: * </pre>
226: * Note that sometimes this Transform will be identity (e.g. for
227: * printers or metafile output) and that this Transform is only
228: * as accurate as the information supplied by the underlying system.
229: * For image buffers, this Transform will be the Identity transform,
230: * since there is no valid distance measurement.
231: */
232: public AffineTransform getNormalizingTransform() {
233: Win32GraphicsEnvironment ge = (Win32GraphicsEnvironment) GraphicsEnvironment
234: .getLocalGraphicsEnvironment();
235: double xscale = ge.getXResolution() / 72.0;
236: double yscale = ge.getYResolution() / 72.0;
237: return new AffineTransform(xscale, 0.0, 0.0, yscale, 0.0, 0.0);
238: }
239:
240: public String toString() {
241: return (super .toString() + "[dev=" + screen + ",pixfmt="
242: + visual + "]");
243: }
244:
245: private native Rectangle getBounds(int screen);
246:
247: public Rectangle getBounds() {
248: return getBounds(screen.getScreen());
249: }
250:
251: private static class DDrawBufferCapabilities extends
252: BufferCapabilities {
253: public DDrawBufferCapabilities(ImageCapabilities imageCaps) {
254: super (imageCaps, imageCaps, FlipContents.PRIOR);
255: }
256:
257: public boolean isFullScreenRequired() {
258: return true;
259: }
260:
261: public boolean isMultiBufferAvailable() {
262: return true;
263: }
264: }
265:
266: private static class DDrawImageCapabilities extends
267: ImageCapabilities {
268: public DDrawImageCapabilities() {
269: super (true);
270: }
271:
272: public boolean isTrueVolatile() {
273: return true;
274: }
275: }
276:
277: public BufferCapabilities getBufferCapabilities() {
278: if (bufferCaps == null) {
279: if (WindowsFlags.isDDEnabled()) {
280: bufferCaps = new DDrawBufferCapabilities(
281: getImageCapabilities());
282: } else {
283: bufferCaps = super .getBufferCapabilities();
284: }
285: }
286: return bufferCaps;
287: }
288:
289: public ImageCapabilities getImageCapabilities() {
290: if (imageCaps == null) {
291: if (WindowsFlags.isDDEnabled()) {
292: imageCaps = new DDrawImageCapabilities();
293: } else {
294: imageCaps = super .getImageCapabilities();
295: }
296: }
297: return imageCaps;
298: }
299:
300: public synchronized void displayChanged() {
301: solidloops = null;
302: }
303:
304: public void paletteChanged() {
305: }
306:
307: /**
308: * The following methods are invoked from WComponentPeer.java rather
309: * than having the Win32-dependent implementations hardcoded in that
310: * class. This way the appropriate actions are taken based on the peer's
311: * GraphicsConfig, whether it is a Win32GraphicsConfig or a
312: * WGLGraphicsConfig.
313: */
314:
315: /**
316: * Creates a new SurfaceData that will be associated with the given
317: * WComponentPeer.
318: */
319: public SurfaceData createSurfaceData(WComponentPeer peer,
320: int numBackBuffers) {
321: return Win32SurfaceData.createData(peer, numBackBuffers);
322: }
323:
324: /**
325: * Creates a new hidden-acceleration image of the given width and height
326: * that is associated with the target Component.
327: */
328: public Image createAcceleratedImage(Component target, int width,
329: int height) {
330: ColorModel model = getColorModel(Transparency.OPAQUE);
331: WritableRaster wr = model.createCompatibleWritableRaster(width,
332: height);
333: return new OffScreenImage(target, model, wr, model
334: .isAlphaPremultiplied());
335: }
336:
337: /**
338: * The following methods correspond to the multibuffering methods in
339: * WComponentPeer.java...
340: */
341:
342: private boolean isFullScreenExclusive(Component target) {
343: Win32GraphicsDevice gd = (Win32GraphicsDevice) getDevice();
344: while (target != null && !(target instanceof Window)) {
345: target = target.getParent();
346: }
347: return (target == gd.getFullScreenWindow() && gd
348: .isDDEnabledOnDevice());
349: }
350:
351: /**
352: * Checks that the requested configuration is natively supported; if not,
353: * an AWTException is thrown.
354: */
355: public void assertOperationSupported(Component target,
356: int numBuffers, BufferCapabilities caps)
357: throws AWTException {
358: if (!isFullScreenExclusive(target)) {
359: throw new AWTException(
360: "The operation requested is only supported on a full-screen"
361: + " exclusive window");
362: }
363: }
364:
365: /**
366: * Creates a backbuffer for the given peer and returns the image wrapper.
367: */
368: public VolatileImage createBackBuffer(WComponentPeer peer) {
369: // Create the back buffer object
370: return new WinBackBuffer((Component) peer.getTarget(),
371: (Win32SurfaceData) peer.getSurfaceData());
372: }
373:
374: /**
375: * Performs the native flip operation for the given target Component.
376: */
377: public void flip(WComponentPeer peer, Component target,
378: VolatileImage backBuffer,
379: BufferCapabilities.FlipContents flipAction) {
380: int width = target.getWidth();
381: int height = target.getHeight();
382: if (flipAction == BufferCapabilities.FlipContents.COPIED) {
383: Graphics g = target.getGraphics();
384: g.drawImage(backBuffer, 0, 0, width, height, null);
385: g.dispose();
386: return;
387: }
388: Win32SurfaceData sd = (Win32SurfaceData) peer.getSurfaceData();
389: try {
390: sd.flip(((WinBackBuffer) backBuffer).getHWSurfaceData());
391: } catch (sun.java2d.InvalidPipeException e) {
392: // copy software surface to the screen via gdi blit
393: Graphics g = target.getGraphics();
394: g.drawImage(backBuffer, 0, 0, width, height, null);
395: g.dispose();
396: }
397: if (flipAction == BufferCapabilities.FlipContents.BACKGROUND) {
398: Graphics g = backBuffer.getGraphics();
399: g.setColor(target.getBackground());
400: g.fillRect(0, 0, width, height);
401: g.dispose();
402: }
403: }
404: }
|