001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Oleg V. Khaschansky
019: * @version $Revision$
020: */package org.apache.harmony.awt.gl.linux;
021:
022: import org.apache.harmony.awt.nativebridge.linux.X11;
023: import org.apache.harmony.awt.nativebridge.linux.X11Defs;
024: import org.apache.harmony.awt.nativebridge.Int8Pointer;
025:
026: import java.awt.image.*;
027: import java.awt.*;
028:
029: import org.apache.harmony.awt.gl.GLVolatileImage;
030: import org.apache.harmony.awt.gl.Surface;
031: import org.apache.harmony.awt.gl.Utils;
032: import org.apache.harmony.awt.internal.nls.Messages;
033:
034: public class XVolatileImage extends GLVolatileImage {
035: private static final X11 x11 = X11.getInstance();
036: private static final ImageCapabilities ic = new ImageCapabilities(
037: true);
038:
039: private long pixmap;
040: private XGraphicsConfiguration xconf;
041: Surface surface;
042:
043: int width, height;
044:
045: XVolatileImage(XGraphicsConfiguration xconf, int w, int h) {
046: this .xconf = xconf;
047: width = w;
048: height = h;
049: long display = xconf.dev.display;
050: pixmap = x11.XCreatePixmap(display, x11.XRootWindow(display,
051: xconf.dev.screen), w, h, xconf.info.get_depth());
052:
053: surface = new PixmapSurface(display, pixmap, xconf.info.lock(),
054: w, h);
055: xconf.info.unlock();
056: }
057:
058: public long getPixmap() {
059: return pixmap;
060: }
061:
062: public int getHeight() {
063: return height;
064: }
065:
066: public int getWidth() {
067: return width;
068: }
069:
070: public boolean contentsLost() {
071: return false;
072: }
073:
074: public Graphics2D createGraphics() {
075: return new XGraphics2D(this , 0, 0, width, height);
076: }
077:
078: public int validate(GraphicsConfiguration graphicsConfiguration) {
079: if (graphicsConfiguration.equals(xconf))
080: return IMAGE_OK;
081: else
082: return IMAGE_INCOMPATIBLE;
083: }
084:
085: public ImageCapabilities getCapabilities() {
086: return ic;
087: }
088:
089: public BufferedImage getSnapshot() {
090: long xImagePtr = 0L;
091: X11.XImage xImage;
092:
093: if (x11.XImageByteOrder(xconf.dev.display) == X11Defs.LSBFirst) {
094: xImagePtr = x11.XGetImage(xconf.dev.display, pixmap, 0, 0,
095: width, height, ~(0L), // All bits set to 1, should be same as XAllPlanes() result
096: X11Defs.ZPixmap);
097:
098: if (xImagePtr == 0) // Check obtained XImage pointer
099: return null;
100:
101: xImage = x11.createXImage(xImagePtr);
102:
103: } else {
104: xImagePtr = x11.XGetImage(xconf.dev.display, pixmap, 0, 0,
105: 1, 1, ~(0L), // All bits set to 1, should be same as XAllPlanes() result
106: X11Defs.ZPixmap);
107:
108: if (xImagePtr == 0) // Check obtained XImage pointer
109: return null;
110:
111: X11.XImage xTmpImage = x11.createXImage(xImagePtr);
112: X11.Visual visual = xconf.info.get_visual();
113:
114: xImagePtr = x11.XCreateImage(xconf.dev.display, visual
115: .lock(), xTmpImage.get_depth(), xTmpImage
116: .get_format(), xTmpImage.get_xoffset(),
117: Utils.memaccess.malloc(height * width
118: * xTmpImage.get_bytes_per_line()), width,
119: height, xTmpImage.get_bitmap_pad(), 0);
120: visual.unlock();
121:
122: xImage = x11.createXImage(xImagePtr);
123: xImage.set_byte_order(X11Defs.LSBFirst);
124:
125: xTmpImage.get_f().destroy_image(xTmpImage);
126:
127: xImage = x11.XGetSubImage(xconf.dev.display, pixmap, 0, 0,
128: width, height, ~(0L), // All bits set to 1, should be same as XAllPlanes() result
129: X11Defs.ZPixmap, xImage, 0, 0);
130: }
131:
132: BufferedImage res = biFromXImage(xImage, xconf);
133:
134: // Cleanup
135: xImage.get_f().destroy_image(xImage);
136:
137: return res;
138: }
139:
140: public static BufferedImage biFromXImage(X11.XImage xImage,
141: XGraphicsConfiguration xconf) {
142: int width = xImage.get_width();
143: int height = xImage.get_height();
144:
145: ColorModel cm = xconf.getColorModel();
146: SampleModel sm;
147: DataBuffer db;
148: int scanlineStride, dataType;
149: int bpp = xImage.get_bits_per_pixel();
150: Int8Pointer dataPtr = xImage.get_data();
151:
152: switch (bpp) {
153: case 32: {
154: dataType = DataBuffer.TYPE_INT;
155: scanlineStride = xImage.get_bytes_per_line() >> 2;
156: int size = scanlineStride * height;
157:
158: // Create data buffer
159: int[] data = new int[size];
160: Utils.memaccess.getInt(dataPtr.lock(), data, xImage
161: .get_xoffset(), size);
162: dataPtr.unlock();
163: db = new DataBufferInt(data, size);
164:
165: break;
166: }
167: case 16: {
168: dataType = DataBuffer.TYPE_USHORT;
169: scanlineStride = xImage.get_bytes_per_line() >> 1;
170: int size = scanlineStride * height;
171:
172: // Create data buffer
173: short[] data = new short[size];
174: Utils.memaccess.getShort(dataPtr.lock(), data, xImage
175: .get_xoffset(), size);
176: dataPtr.unlock();
177: db = new DataBufferShort(data, size);
178:
179: break;
180: }
181: case 8:
182: case 4:
183: case 2:
184: case 1: {
185: dataType = DataBuffer.TYPE_BYTE;
186: scanlineStride = xImage.get_bytes_per_line();
187: int size = scanlineStride * height;
188:
189: // Create data buffer
190: byte[] data = new byte[size];
191: Utils.memaccess.getByte(dataPtr.lock(), data, xImage
192: .get_xoffset(), size);
193: dataPtr.unlock();
194: db = new DataBufferByte(data, size);
195:
196: break;
197: }
198: default: {
199: // awt.0A=Cannot use SinglePixedPackedSampleModel for bpp = {0}
200: throw new InternalError(Messages.getString(
201: "awt.0A", xImage.get_bits_per_pixel())); //$NON-NLS-1$
202: }
203: }
204:
205: if (cm instanceof DirectColorModel) { // TrueColor / DirectColor
206: // Because XGetImage doesn't set masks we have to get them right from the visual info
207: int bitMasks[] = ((DirectColorModel) cm).getMasks();
208:
209: // Now create sample model
210: sm = new SinglePixelPackedSampleModel(dataType, width,
211: height, scanlineStride, bitMasks);
212:
213: } else if (cm instanceof IndexColorModel
214: || cm instanceof ComponentColorModel) { // PseudoColor, StaticGray, etc.
215: if (bpp >= 8) {
216: sm = new PixelInterleavedSampleModel(dataType, width,
217: height, 1, scanlineStride, new int[] { 0 });
218: } else {
219: sm = new MultiPixelPackedSampleModel(dataType, width,
220: height, bpp, scanlineStride, 0);
221: }
222: } else {
223: // awt.0B=Wrong color model created for drawable
224: throw new InternalError(Messages.getString("awt.0B")); //$NON-NLS-1$
225: }
226:
227: return new BufferedImage(cm, Raster.createWritableRaster(sm,
228: db, new Point(0, 0)), false, null);
229: }
230:
231: public Object getProperty(String name, ImageObserver observer) {
232: return UndefinedProperty;
233: }
234:
235: public int getWidth(ImageObserver observer) {
236: return width;
237: }
238:
239: public int getHeight(ImageObserver observer) {
240: return height;
241: }
242:
243: public void finalize() {
244: surface.dispose();
245: x11.XFreePixmap(xconf.dev.display, pixmap);
246: }
247:
248: public Surface getImageSurface() {
249: return surface;
250: }
251: }
|