--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,792 @@
+/*
+ * Copyright 1999-2007 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.
+ */
+
+package sun.java2d.x11;
+
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Rectangle;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.color.ColorSpace;
+import java.awt.Transparency;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DirectColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.image.Raster;
+import java.awt.peer.ComponentPeer;
+
+import sun.awt.SunHints;
+import sun.awt.SunToolkit;
+import sun.awt.X11ComponentPeer;
+import sun.awt.X11GraphicsConfig;
+import sun.awt.image.PixelConverter;
+import sun.font.X11TextRenderer;
+import sun.java2d.InvalidPipeException;
+import sun.java2d.SunGraphics2D;
+import sun.java2d.SurfaceData;
+import sun.java2d.SurfaceDataProxy;
+import sun.java2d.loops.SurfaceType;
+import sun.java2d.loops.CompositeType;
+import sun.java2d.loops.RenderLoops;
+import sun.java2d.loops.GraphicsPrimitive;
+import sun.java2d.loops.XORComposite;
+import sun.java2d.loops.Blit;
+import sun.java2d.pipe.ValidatePipe;
+import sun.java2d.pipe.PixelToShapeConverter;
+import sun.java2d.pipe.TextPipe;
+import sun.java2d.pipe.Region;
+
+public abstract class X11SurfaceData extends SurfaceData {
+ X11ComponentPeer peer;
+ X11GraphicsConfig graphicsConfig;
+ private RenderLoops solidloops;
+
+ protected int depth;
+
+ private static native void initIDs(Class xorComp, boolean tryDGA);
+ protected native void initSurface(int depth, int width, int height,
+ long drawable);
+ native boolean isDrawableValid();
+ protected native void flushNativeSurface();
+
+ public static final String
+ DESC_INT_BGR_X11 = "Integer BGR Pixmap";
+ public static final String
+ DESC_INT_RGB_X11 = "Integer RGB Pixmap";
+ public static final String
+ DESC_BYTE_IND_OPQ_X11 = "Byte Indexed Opaque Pixmap";
+
+ public static final String
+ DESC_INT_BGR_X11_BM = "Integer BGR Pixmap with 1-bit transp";
+ public static final String
+ DESC_INT_RGB_X11_BM = "Integer RGB Pixmap with 1-bit transp";
+ public static final String
+ DESC_BYTE_IND_X11_BM = "Byte Indexed Pixmap with 1-bit transp";
+
+ public static final String
+ DESC_BYTE_GRAY_X11 = "Byte Gray Opaque Pixmap";
+ public static final String
+ DESC_INDEX8_GRAY_X11 = "Index8 Gray Opaque Pixmap";
+
+ public static final String
+ DESC_BYTE_GRAY_X11_BM = "Byte Gray Opaque Pixmap with 1-bit transp";
+ public static final String
+ DESC_INDEX8_GRAY_X11_BM = "Index8 Gray Opaque Pixmap with 1-bit transp";
+
+ public static final String
+ DESC_3BYTE_RGB_X11 = "3 Byte RGB Pixmap";
+ public static final String
+ DESC_3BYTE_BGR_X11 = "3 Byte BGR Pixmap";
+
+ public static final String
+ DESC_3BYTE_RGB_X11_BM = "3 Byte RGB Pixmap with 1-bit transp";
+ public static final String
+ DESC_3BYTE_BGR_X11_BM = "3 Byte BGR Pixmap with 1-bit transp";
+
+ public static final String
+ DESC_USHORT_555_RGB_X11 = "Ushort 555 RGB Pixmap";
+ public static final String
+ DESC_USHORT_565_RGB_X11 = "Ushort 565 RGB Pixmap";
+
+ public static final String
+ DESC_USHORT_555_RGB_X11_BM
+ = "Ushort 555 RGB Pixmap with 1-bit transp";
+ public static final String
+ DESC_USHORT_565_RGB_X11_BM
+ = "Ushort 565 RGB Pixmap with 1-bit transp";
+ public static final String
+ DESC_USHORT_INDEXED_X11 = "Ushort Indexed Pixmap";
+
+ public static final String
+ DESC_USHORT_INDEXED_X11_BM = "Ushort Indexed Pixmap with 1-bit transp";
+
+ public static final SurfaceType IntBgrX11 =
+ SurfaceType.IntBgr.deriveSubType(DESC_INT_BGR_X11);
+ public static final SurfaceType IntRgbX11 =
+ SurfaceType.IntRgb.deriveSubType(DESC_INT_RGB_X11);
+
+ public static final SurfaceType ThreeByteRgbX11 =
+ SurfaceType.ThreeByteRgb.deriveSubType(DESC_3BYTE_RGB_X11);
+ public static final SurfaceType ThreeByteBgrX11 =
+ SurfaceType.ThreeByteBgr.deriveSubType(DESC_3BYTE_BGR_X11);
+
+ public static final SurfaceType UShort555RgbX11 =
+ SurfaceType.Ushort555Rgb.deriveSubType(DESC_USHORT_555_RGB_X11);
+ public static final SurfaceType UShort565RgbX11 =
+ SurfaceType.Ushort565Rgb.deriveSubType(DESC_USHORT_565_RGB_X11);
+
+ public static final SurfaceType UShortIndexedX11 =
+ SurfaceType.UshortIndexed.deriveSubType(DESC_USHORT_INDEXED_X11);
+
+ public static final SurfaceType ByteIndexedOpaqueX11 =
+ SurfaceType.ByteIndexedOpaque.deriveSubType(DESC_BYTE_IND_OPQ_X11);
+
+ public static final SurfaceType ByteGrayX11 =
+ SurfaceType.ByteGray.deriveSubType(DESC_BYTE_GRAY_X11);
+ public static final SurfaceType Index8GrayX11 =
+ SurfaceType.Index8Gray.deriveSubType(DESC_INDEX8_GRAY_X11);
+
+ // Bitmap surface types
+ public static final SurfaceType IntBgrX11_BM =
+ SurfaceType.Custom.deriveSubType(DESC_INT_BGR_X11_BM,
+ PixelConverter.Xbgr.instance);
+ public static final SurfaceType IntRgbX11_BM =
+ SurfaceType.Custom.deriveSubType(DESC_INT_RGB_X11_BM,
+ PixelConverter.Xrgb.instance);
+
+ public static final SurfaceType ThreeByteRgbX11_BM =
+ SurfaceType.Custom.deriveSubType(DESC_3BYTE_RGB_X11_BM,
+ PixelConverter.Xbgr.instance);
+ public static final SurfaceType ThreeByteBgrX11_BM =
+ SurfaceType.Custom.deriveSubType(DESC_3BYTE_BGR_X11_BM,
+ PixelConverter.Xrgb.instance);
+
+ public static final SurfaceType UShort555RgbX11_BM =
+ SurfaceType.Custom.deriveSubType(DESC_USHORT_555_RGB_X11_BM,
+ PixelConverter.Ushort555Rgb.instance);
+ public static final SurfaceType UShort565RgbX11_BM =
+ SurfaceType.Custom.deriveSubType(DESC_USHORT_565_RGB_X11_BM,
+ PixelConverter.Ushort565Rgb.instance);
+
+ public static final SurfaceType UShortIndexedX11_BM =
+ SurfaceType.Custom.deriveSubType(DESC_USHORT_INDEXED_X11_BM);
+
+ public static final SurfaceType ByteIndexedX11_BM =
+ SurfaceType.Custom.deriveSubType(DESC_BYTE_IND_X11_BM);
+
+ public static final SurfaceType ByteGrayX11_BM =
+ SurfaceType.Custom.deriveSubType(DESC_BYTE_GRAY_X11_BM);
+ public static final SurfaceType Index8GrayX11_BM =
+ SurfaceType.Custom.deriveSubType(DESC_INDEX8_GRAY_X11_BM);
+
+
+ private static Boolean accelerationEnabled = null;
+
+ public Raster getRaster(int x, int y, int w, int h) {
+ throw new InternalError("not implemented yet");
+ }
+
+ protected X11Renderer x11pipe;
+ protected PixelToShapeConverter x11txpipe;
+ protected static TextPipe x11textpipe;
+ protected static boolean dgaAvailable;
+
+ static {
+ if (!GraphicsEnvironment.isHeadless()) {
+ // If a screen magnifier is present, don't attempt to use DGA
+ String magPresent = (String) java.security.AccessController.doPrivileged
+ (new sun.security.action.GetPropertyAction("javax.accessibility.screen_magnifier_present"));
+ boolean tryDGA = magPresent == null || !"true".equals(magPresent);
+
+ initIDs(XORComposite.class, tryDGA);
+
+ String xtextpipe = (String) java.security.AccessController.doPrivileged
+ (new sun.security.action.GetPropertyAction("sun.java2d.xtextpipe"));
+ if (xtextpipe == null || "true".startsWith(xtextpipe)) {
+ if ("true".equals(xtextpipe)) {
+ // Only verbose if they use the full string "true"
+ System.out.println("using X11 text renderer");
+ }
+ x11textpipe = new X11TextRenderer();
+ if (GraphicsPrimitive.tracingEnabled()) {
+ x11textpipe = ((X11TextRenderer) x11textpipe).traceWrap();
+ }
+ } else {
+ if ("false".equals(xtextpipe)) {
+ // Only verbose if they use the full string "false"
+ System.out.println("using DGA text renderer");
+ }
+ x11textpipe = solidTextRenderer;
+ }
+
+ dgaAvailable = isDgaAvailable();
+
+ if (isAccelerationEnabled()) {
+ X11PMBlitLoops.register();
+ X11PMBlitBgLoops.register();
+ }
+ }
+ }
+
+ /**
+ * Returns true if we can use DGA on any of the screens
+ */
+ public static native boolean isDgaAvailable();
+
+ public static boolean isAccelerationEnabled() {
+ if (accelerationEnabled == null) {
+
+ if (GraphicsEnvironment.isHeadless()) {
+ accelerationEnabled = Boolean.FALSE;
+ } else {
+ String prop =
+ (String) java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction("sun.java2d.pmoffscreen"));
+ if (prop != null) {
+ // true iff prop==true, false otherwise
+ accelerationEnabled = Boolean.valueOf(prop);
+ } else {
+ // use pixmaps if there is no dga, no matter local or remote
+ accelerationEnabled = Boolean.valueOf(!isDgaAvailable());
+ }
+ }
+ }
+ return accelerationEnabled.booleanValue();
+ }
+
+ @Override
+ public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
+ return X11SurfaceDataProxy.createProxy(srcData, graphicsConfig);
+ }
+
+ public void validatePipe(SunGraphics2D sg2d) {
+ if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON &&
+ sg2d.paintState <= sg2d.PAINT_ALPHACOLOR &&
+ (sg2d.compositeState <= sg2d.COMP_ISCOPY ||
+ sg2d.compositeState == sg2d.COMP_XOR))
+ {
+ if (x11txpipe == null) {
+ /*
+ * Note: this is thread-safe since x11txpipe is the
+ * second of the two pipes constructed in makePipes().
+ * In the rare case we are racing against another
+ * thread making new pipes, setting lazypipe is a
+ * safe alternative to waiting for the other thread.
+ */
+ sg2d.drawpipe = lazypipe;
+ sg2d.fillpipe = lazypipe;
+ sg2d.shapepipe = lazypipe;
+ sg2d.imagepipe = lazypipe;
+ sg2d.textpipe = lazypipe;
+ return;
+ }
+
+ if (sg2d.clipState == sg2d.CLIP_SHAPE) {
+ // Do this to init textpipe correctly; we will override the
+ // other non-text pipes below
+ // REMIND: we should clean this up eventually instead of
+ // having this work duplicated.
+ super.validatePipe(sg2d);
+ } else {
+ switch (sg2d.textAntialiasHint) {
+
+ case SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT:
+ /* equating to OFF which it is for us */
+ case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:
+ // Use X11 pipe even if DGA is available since DGA
+ // text slows everything down when mixed with X11 calls
+ if (sg2d.compositeState == sg2d.COMP_ISCOPY) {
+ sg2d.textpipe = x11textpipe;
+ } else {
+ sg2d.textpipe = solidTextRenderer;
+ }
+ break;
+
+ case SunHints.INTVAL_TEXT_ANTIALIAS_ON:
+ // Remind: may use Xrender for these when composite is
+ // copy as above, or if remote X11.
+ sg2d.textpipe = aaTextRenderer;
+ break;
+
+ default:
+ switch (sg2d.getFontInfo().aaHint) {
+
+ case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB:
+ case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB:
+ sg2d.textpipe = lcdTextRenderer;
+ break;
+
+ case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:
+ // Use X11 pipe even if DGA is available since DGA
+ // text slows everything down when mixed with X11 calls
+ if (sg2d.compositeState == sg2d.COMP_ISCOPY) {
+ sg2d.textpipe = x11textpipe;
+ } else {
+ sg2d.textpipe = solidTextRenderer;
+ }
+ break;
+
+ case SunHints.INTVAL_TEXT_ANTIALIAS_ON:
+ sg2d.textpipe = aaTextRenderer;
+ break;
+
+ default:
+ sg2d.textpipe = solidTextRenderer;
+ }
+ }
+ }
+
+ if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {
+ sg2d.drawpipe = x11txpipe;
+ sg2d.fillpipe = x11txpipe;
+ } else if (sg2d.strokeState != sg2d.STROKE_THIN){
+ sg2d.drawpipe = x11txpipe;
+ sg2d.fillpipe = x11pipe;
+ } else {
+ sg2d.drawpipe = x11pipe;
+ sg2d.fillpipe = x11pipe;
+ }
+ sg2d.shapepipe = x11pipe;
+ sg2d.imagepipe = imagepipe;
+
+ // This is needed for AA text.
+ // Note that even an X11TextRenderer can dispatch AA text
+ // if a GlyphVector overrides the AA setting.
+ // We use getRenderLoops() rather than setting solidloops
+ // directly so that we get the appropriate loops in XOR mode.
+ sg2d.loops = getRenderLoops(sg2d);
+ } else {
+ super.validatePipe(sg2d);
+ }
+ }
+
+ public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
+ if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR &&
+ sg2d.compositeState <= sg2d.COMP_ISCOPY)
+ {
+ return solidloops;
+ }
+ return super.getRenderLoops(sg2d);
+ }
+
+ public GraphicsConfiguration getDeviceConfiguration() {
+ return graphicsConfig;
+ }
+
+ /**
+ * Method for instantiating a Window SurfaceData
+ */
+ public static X11WindowSurfaceData createData(X11ComponentPeer peer) {
+ X11GraphicsConfig gc = getGC(peer);
+ return new X11WindowSurfaceData(peer, gc, gc.getSurfaceType());
+ }
+
+ /**
+ * Method for instantiating a Pixmap SurfaceData (offscreen)
+ */
+ public static X11PixmapSurfaceData createData(X11GraphicsConfig gc,
+ int width, int height,
+ ColorModel cm, Image image,
+ long drawable,
+ int transparency)
+ {
+ return new X11PixmapSurfaceData(gc, width, height, image,
+ getSurfaceType(gc, transparency),
+ cm, drawable, transparency);
+ }
+
+ /**
+ * Initializes the native Ops pointer.
+ */
+ private native void initOps(X11ComponentPeer peer,
+ X11GraphicsConfig gc, int depth);
+
+ protected X11SurfaceData(X11ComponentPeer peer,
+ X11GraphicsConfig gc,
+ SurfaceType sType,
+ ColorModel cm) {
+ super(sType, cm);
+ this.peer = peer;
+ this.graphicsConfig = gc;
+ this.solidloops = graphicsConfig.getSolidLoops(sType);
+ this.depth = cm.getPixelSize();
+ initOps(peer, graphicsConfig, depth);
+ if (isAccelerationEnabled()) {
+ setBlitProxyKey(gc.getProxyKey());
+ }
+ }
+
+ public static X11GraphicsConfig getGC(X11ComponentPeer peer) {
+ if (peer != null) {
+ return (X11GraphicsConfig) peer.getGraphicsConfiguration();
+ } else {
+ GraphicsEnvironment env =
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
+ GraphicsDevice gd = env.getDefaultScreenDevice();
+ return (X11GraphicsConfig)gd.getDefaultConfiguration();
+ }
+ }
+
+ /**
+ * Returns a boolean indicating whether or not a copyArea from
+ * the given rectangle source coordinates might be incomplete
+ * and result in X11 GraphicsExposure events being generated
+ * from XCopyArea.
+ * This method allows the SurfaceData copyArea method to determine
+ * if it needs to set the GraphicsExposures attribute of the X11 GC
+ * to True or False to receive or avoid the events.
+ * @return true if there is any chance that an XCopyArea from the
+ * given source coordinates could produce any X11
+ * Exposure events.
+ */
+ public abstract boolean canSourceSendExposures(int x, int y, int w, int h);
+
+ public boolean copyArea(SunGraphics2D sg2d,
+ int x, int y, int w, int h, int dx, int dy)
+ {
+ if (x11pipe == null) {
+ if (!isDrawableValid()) {
+ return true;
+ }
+ makePipes();
+ }
+ CompositeType comptype = sg2d.imageComp;
+ if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE &&
+ (CompositeType.SrcOverNoEa.equals(comptype) ||
+ CompositeType.SrcNoEa.equals(comptype)))
+ {
+ x += sg2d.transX;
+ y += sg2d.transY;
+ SunToolkit.awtLock();
+ try {
+ boolean needExposures = canSourceSendExposures(x, y, w, h);
+ long xgc = getBlitGC(sg2d.getCompClip(), needExposures);
+ x11pipe.devCopyArea(getNativeOps(), xgc,
+ x, y,
+ x + dx, y + dy,
+ w, h);
+ } finally {
+ SunToolkit.awtUnlock();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public static SurfaceType getSurfaceType(X11GraphicsConfig gc,
+ int transparency)
+ {
+ boolean transparent = (transparency == Transparency.BITMASK);
+ SurfaceType sType;
+ ColorModel cm = gc.getColorModel();
+ switch (cm.getPixelSize()) {
+ case 24:
+ if (gc.getBitsPerPixel() == 24) {
+ if (cm instanceof DirectColorModel) {
+ // 4517321: We will always use ThreeByteBgr for 24 bpp
+ // surfaces, regardless of the pixel masks reported by
+ // X11. Despite ambiguity in the X11 spec in how 24 bpp
+ // surfaces are treated, it appears that the best
+ // SurfaceType for these configurations (including
+ // some Matrox Millenium and ATI Radeon boards) is
+ // ThreeByteBgr.
+ sType = transparent ? X11SurfaceData.ThreeByteBgrX11_BM : X11SurfaceData.ThreeByteBgrX11;
+ } else {
+ throw new sun.java2d.InvalidPipeException("Unsupported bit " +
+ "depth/cm combo: " +
+ cm.getPixelSize() +
+ ", " + cm);
+ }
+ break;
+ }
+ // Fall through for 32 bit case
+ case 32:
+ if (cm instanceof DirectColorModel) {
+ if (((DirectColorModel)cm).getRedMask() == 0xff0000) {
+ sType = transparent ? X11SurfaceData.IntRgbX11_BM : X11SurfaceData.IntRgbX11;
+ } else {
+ sType = transparent ? X11SurfaceData.IntBgrX11_BM : X11SurfaceData.IntBgrX11;
+ }
+ } else {
+ throw new sun.java2d.InvalidPipeException("Unsupported bit " +
+ "depth/cm combo: " +
+ cm.getPixelSize() +
+ ", " + cm);
+ }
+ break;
+ case 15:
+ sType = transparent ? X11SurfaceData.UShort555RgbX11_BM : X11SurfaceData.UShort555RgbX11;
+ break;
+ case 16:
+ if ((cm instanceof DirectColorModel) &&
+ (((DirectColorModel)cm).getGreenMask() == 0x3e0))
+ {
+ // fix for 4352984: Riva128 on Linux
+ sType = transparent ? X11SurfaceData.UShort555RgbX11_BM : X11SurfaceData.UShort555RgbX11;
+ } else {
+ sType = transparent ? X11SurfaceData.UShort565RgbX11_BM : X11SurfaceData.UShort565RgbX11;
+ }
+ break;
+ case 12:
+ if (cm instanceof IndexColorModel) {
+ sType = transparent ?
+ X11SurfaceData.UShortIndexedX11_BM :
+ X11SurfaceData.UShortIndexedX11;
+ } else {
+ throw new sun.java2d.InvalidPipeException("Unsupported bit " +
+ "depth: " +
+ cm.getPixelSize() +
+ " cm="+cm);
+ }
+ break;
+ case 8:
+ if (cm.getColorSpace().getType() == ColorSpace.TYPE_GRAY &&
+ cm instanceof ComponentColorModel) {
+ sType = transparent ? X11SurfaceData.ByteGrayX11_BM : X11SurfaceData.ByteGrayX11;
+ } else if (cm instanceof IndexColorModel &&
+ isOpaqueGray((IndexColorModel)cm)) {
+ sType = transparent ? X11SurfaceData.Index8GrayX11_BM : X11SurfaceData.Index8GrayX11;
+ } else {
+ sType = transparent ? X11SurfaceData.ByteIndexedX11_BM : X11SurfaceData.ByteIndexedOpaqueX11;
+ }
+ break;
+ default:
+ throw new sun.java2d.InvalidPipeException("Unsupported bit " +
+ "depth: " +
+ cm.getPixelSize());
+ }
+ return sType;
+ }
+
+ public native void setInvalid();
+
+ public void invalidate() {
+ if (isValid()) {
+ setInvalid();
+ super.invalidate();
+ }
+ }
+
+ /**
+ * The following methods and variables are used to keep the Java-level
+ * context state in sync with the native X11 GC associated with this
+ * X11SurfaceData object.
+ */
+
+ private static native long XCreateGC(long pXSData);
+ private static native void XResetClip(long xgc);
+ private static native void XSetClip(long xgc,
+ int lox, int loy, int hix, int hiy,
+ Region complexclip);
+ private static native void XSetCopyMode(long xgc);
+ private static native void XSetXorMode(long xgc);
+ private static native void XSetForeground(long xgc, int pixel);
+ private static native void XSetGraphicsExposures(long xgc,
+ boolean needExposures);
+
+ private long xgc;
+ private Region validatedClip;
+ private XORComposite validatedXorComp;
+ private int xorpixelmod;
+ private int validatedPixel;
+ private boolean validatedExposures = true;
+
+ public final long getRenderGC(Region clip,
+ int compState, Composite comp,
+ int pixel)
+ {
+ return getGC(clip, compState, comp, pixel, validatedExposures);
+ }
+
+ public final long getBlitGC(Region clip, boolean needExposures) {
+ return getGC(clip, SunGraphics2D.COMP_ISCOPY, null,
+ validatedPixel, needExposures);
+ }
+
+ final long getGC(Region clip,
+ int compState, Composite comp,
+ int pixel, boolean needExposures)
+ {
+ // assert SunToolkit.isAWTLockHeldByCurrentThread();
+
+ if (!isValid()) {
+ throw new InvalidPipeException("bounds changed");
+ }
+
+ // validate clip
+ if (clip != validatedClip) {
+ validatedClip = clip;
+ if (clip != null) {
+ XSetClip(xgc,
+ clip.getLoX(), clip.getLoY(),
+ clip.getHiX(), clip.getHiY(),
+ (clip.isRectangular() ? null : clip));
+ } else {
+ XResetClip(xgc);
+ }
+ }
+
+ // validate composite
+ if (compState == SunGraphics2D.COMP_ISCOPY) {
+ if (validatedXorComp != null) {
+ validatedXorComp = null;
+ xorpixelmod = 0;
+ XSetCopyMode(xgc);
+ }
+ } else {
+ if (validatedXorComp != comp) {
+ validatedXorComp = (XORComposite)comp;
+ xorpixelmod = validatedXorComp.getXorPixel();
+ XSetXorMode(xgc);
+ }
+ }
+
+ // validate pixel
+ pixel ^= xorpixelmod;
+ if (pixel != validatedPixel) {
+ validatedPixel = pixel;
+ XSetForeground(xgc, pixel);
+ }
+
+ if (validatedExposures != needExposures) {
+ validatedExposures = needExposures;
+ XSetGraphicsExposures(xgc, needExposures);
+ }
+
+ return xgc;
+ }
+
+ public synchronized void makePipes() {
+ if (x11pipe == null) {
+ SunToolkit.awtLock();
+ try {
+ xgc = XCreateGC(getNativeOps());
+ } finally {
+ SunToolkit.awtUnlock();
+ }
+ x11pipe = X11Renderer.getInstance();
+ x11txpipe = new PixelToShapeConverter(x11pipe);
+ }
+ }
+
+ public static class X11WindowSurfaceData extends X11SurfaceData {
+ public X11WindowSurfaceData(X11ComponentPeer peer,
+ X11GraphicsConfig gc,
+ SurfaceType sType) {
+ super(peer, gc, sType, peer.getColorModel());
+ if (isDrawableValid()) {
+ makePipes();
+ }
+ }
+
+ public SurfaceData getReplacement() {
+ return peer.getSurfaceData();
+ }
+
+ public Rectangle getBounds() {
+ Rectangle r = peer.getBounds();
+ r.x = r.y = 0;
+ return r;
+ }
+
+ @Override
+ public boolean canSourceSendExposures(int x, int y, int w, int h) {
+ return true;
+ }
+
+ /**
+ * Returns destination Component associated with this SurfaceData.
+ */
+ public Object getDestination() {
+ return peer.getTarget();
+ }
+ }
+
+ public static class X11PixmapSurfaceData extends X11SurfaceData {
+
+ Image offscreenImage;
+ int width;
+ int height;
+ int transparency;
+
+ public X11PixmapSurfaceData(X11GraphicsConfig gc,
+ int width, int height,
+ Image image,
+ SurfaceType sType, ColorModel cm,
+ long drawable, int transparency)
+ {
+ super(null, gc, sType, cm);
+ this.width = width;
+ this.height = height;
+ offscreenImage = image;
+ this.transparency = transparency;
+ initSurface(depth, width, height, drawable);
+ makePipes();
+ }
+
+ public SurfaceData getReplacement() {
+ return restoreContents(offscreenImage);
+ }
+
+ /**
+ * Need this since the surface data is created with
+ * the color model of the target GC, which is always
+ * opaque. But in SunGraphics2D.blitSD we choose loops
+ * based on the transparency on the source SD, so
+ * it could choose wrong loop (blit instead of blitbg,
+ * for example).
+ */
+ public int getTransparency() {
+ return transparency;
+ }
+
+ public Rectangle getBounds() {
+ return new Rectangle(width, height);
+ }
+
+ @Override
+ public boolean canSourceSendExposures(int x, int y, int w, int h) {
+ return (x < 0 || y < 0 || (x+w) > width || (y+h) > height);
+ }
+
+ public void flush() {
+ /*
+ * We need to invalidate the surface before disposing the
+ * native Drawable and GC. This way if an application tries
+ * to render to an already flushed X11SurfaceData, we will notice
+ * in the validate() method above that it has been invalidated,
+ * and we will avoid using those native resources that have
+ * already been disposed.
+ */
+ invalidate();
+ flushNativeSurface();
+ }
+
+ /**
+ * Returns destination Image associated with this SurfaceData.
+ */
+ public Object getDestination() {
+ return offscreenImage;
+ }
+ }
+
+ private static LazyPipe lazypipe = new LazyPipe();
+
+ public static class LazyPipe extends ValidatePipe {
+ public boolean validate(SunGraphics2D sg2d) {
+ X11SurfaceData xsd = (X11SurfaceData) sg2d.surfaceData;
+ if (!xsd.isDrawableValid()) {
+ return false;
+ }
+ xsd.makePipes();
+ return super.validate(sg2d);
+ }
+ }
+}