1 /*******************************************************************************
2  * Copyright (c) 2000, 2008 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 module org.eclipse.swt.dnd.ImageTransfer;
12 
13 import org.eclipse.swt.SWT;
14 import org.eclipse.swt.graphics.Image;
15 import org.eclipse.swt.graphics.ImageData;
16 import org.eclipse.swt.internal.Converter;
17 import org.eclipse.swt.internal.gtk.OS;
18 import org.eclipse.swt.widgets.Display;
19 import org.eclipse.swt.dnd.ByteArrayTransfer;
20 import org.eclipse.swt.dnd.TransferData;
21 import org.eclipse.swt.dnd.DND;
22 
23 import java.lang.all;
24 
25 /**
26  * The class <code>ImageTransfer</code> provides a platform specific mechanism
27  * for converting an Image represented as a java <code>ImageData</code> to a 
28  * platform specific representation of the data and vice versa.
29  *
30  * <p>An example of a java <code>ImageData</code> is shown below:</p>
31  *
32  * <code><pre>
33  *     Image image = new Image(display, "C:\temp\img1.gif");
34  *     ImageData imgData = image.getImageData();
35  * </code></pre>
36  *
37  * @see Transfer
38  * 
39  * @since 3.4
40  */
41 public class ImageTransfer : ByteArrayTransfer {
42 
43     private static ImageTransfer _instance;
44 
45     private static const String JPEG = "image/jpge"; //$NON-NLS-1$
46     private static int JPEG_ID;
47     private static const String PNG = "image/png"; //$NON-NLS-1$
48     private static int PNG_ID;
49     private static const String BMP = "image/bmp"; //$NON-NLS-1$
50     private static int BMP_ID;
51     private static const String EPS = "image/eps"; //$NON-NLS-1$
52     private static int EPS_ID;
53     private static const String PCX = "image/pcx"; //$NON-NLS-1$
54     private static int PCX_ID;
55     private static const String PPM = "image/ppm"; //$NON-NLS-1$
56     private static int PPM_ID;
57     private static const String RGB = "image/ppm"; //$NON-NLS-1$
58     private static int RGB_ID;
59     private static const String TGA = "image/tga"; //$NON-NLS-1$
60     private static int TGA_ID;
61     private static const String XBM = "image/xbm"; //$NON-NLS-1$
62     private static int XBM_ID;
63     private static const String XPM = "image/xpm"; //$NON-NLS-1$
64     private static int XPM_ID;
65     private static const String XV = "image/xv"; //$NON-NLS-1$
66     private static int XV_ID;
67 
68 static this(){
69     JPEG_ID = registerType(JPEG);
70     PNG_ID = registerType(PNG);
71     BMP_ID = registerType(BMP);
72     EPS_ID = registerType(EPS);
73     PCX_ID = registerType(PCX);
74     PPM_ID = registerType(PPM);
75     RGB_ID = registerType(RGB);
76     TGA_ID = registerType(TGA);
77     XBM_ID = registerType(XBM);
78     XPM_ID = registerType(XPM);
79     XV_ID = registerType(XV);
80     _instance = new ImageTransfer();
81 }
82 
83 private this() {
84 }
85 
86 /**
87  * Returns the singleton instance of the ImageTransfer class.
88  *
89  * @return the singleton instance of the ImageTransfer class
90  */
91 public static ImageTransfer getInstance () {
92     return _instance;
93 }
94 
95 /**
96  * This implementation of <code>javaToNative</code> converts an ImageData object represented
97  * by java <code>ImageData</code> to a platform specific representation.
98  *
99  * @param object a java <code>ImageData</code> containing the ImageData to be converted
100  * @param transferData an empty <code>TransferData</code> object that will
101  *      be filled in on return with the platform specific format of the data
102  * 
103  * @see Transfer#nativeToJava
104  */
105 override
106 public void javaToNative(Object object, TransferData transferData) {
107     if (!checkImage(object) || !isSupportedType(transferData)) {
108         DND.error(DND.ERROR_INVALID_DATA);
109     }
110     if (OS.GTK_VERSION < OS.buildVERSION (2, 4, 0)) return;
111 
112     ImageData imgData = cast(ImageData)object;
113     if (imgData is null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
114     Image image = new Image(Display.getCurrent(), imgData);
115     auto pixmap = image.pixmap;
116     int width = imgData.width;
117     int height = imgData.height;
118     auto pixbuf = OS.gdk_pixbuf_new(OS.GDK_COLORSPACE_RGB, true, 8, width, height);
119     if (pixbuf is null) SWT.error(SWT.ERROR_NO_HANDLES);
120     auto colormap = OS.gdk_colormap_get_system();
121     OS.gdk_pixbuf_get_from_drawable(pixbuf, pixmap, colormap, 0, 0, 0, 0, width, height);
122 
123     String typeStr = "";
124     if (transferData.type is  cast(void*)JPEG_ID) typeStr = "jpeg";
125     if (transferData.type is  cast(void*)PNG_ID) typeStr = "png";
126     if (transferData.type is  cast(void*)BMP_ID) typeStr = "bmp";
127     if (transferData.type is  cast(void*)EPS_ID) typeStr = "eps";
128     if (transferData.type is  cast(void*)PCX_ID) typeStr = "pcx";
129     if (transferData.type is  cast(void*)PPM_ID) typeStr = "ppm";
130     if (transferData.type is  cast(void*)RGB_ID) typeStr = "rgb";
131     if (transferData.type is  cast(void*)TGA_ID) typeStr = "tga";
132     if (transferData.type is  cast(void*)XBM_ID) typeStr = "xbm";
133     if (transferData.type is  cast(void*)XPM_ID) typeStr = "xpm";
134     if (transferData.type is  cast(void*)XV_ID) typeStr = "xv";
135     auto type = typeStr.ptr;
136     char* buffer;
137     size_t len;
138     if (type is null) return;
139     OS.gdk_pixbuf_save_to_buffer0(pixbuf, &buffer, &len, type, null);
140     OS.g_object_unref(pixbuf);
141     image.dispose();
142     transferData.pValue = buffer;
143     transferData.length = cast(int)/*64bit*/((len + 3) / 4 * 4);
144     transferData.result = 1;
145     transferData.format = 32;
146 }
147 
148 /**
149  * This implementation of <code>nativeToJava</code> converts a platform specific
150  * representation of an image to java <code>ImageData</code>.  
151  * 
152  * @param transferData the platform specific representation of the data to be converted
153  * @return a java <code>ImageData</code> of the image if the conversion was successful;
154  *      otherwise null
155  * 
156  * @see Transfer#javaToNative
157  */
158 override
159 public Object nativeToJava(TransferData transferData) {
160     ImageData imgData = null;
161     if (transferData.length > 0)
162     {
163         auto loader = OS.gdk_pixbuf_loader_new();
164         OS.gdk_pixbuf_loader_write(loader, transferData.pValue, transferData.length, null);
165         OS.gdk_pixbuf_loader_close(loader, null);
166         auto pixbuf = OS.gdk_pixbuf_loader_get_pixbuf(loader);
167         if (pixbuf !is null) {
168             OS.g_object_ref(pixbuf);
169             GdkPixmap* pixmap_return;
170             OS.gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap_return, null, 0);
171             auto handle = pixmap_return;
172             if (handle is null) SWT.error(SWT.ERROR_NO_HANDLES);
173             OS.g_object_unref(loader);
174             Image img = Image.gtk_new(Display.getCurrent(), SWT.BITMAP, handle, null);
175             imgData = img.getImageData();
176             img.dispose();
177         }
178     }
179     return imgData;
180 }
181 
182 override
183 protected int[] getTypeIds(){
184     return [JPEG_ID, PNG_ID, BMP_ID, EPS_ID, PCX_ID, PPM_ID, RGB_ID, TGA_ID, XBM_ID, XPM_ID, XV_ID];
185 }
186 
187 override
188 protected String[] getTypeNames(){
189     return [JPEG, PNG, BMP, EPS, PCX, PPM, RGB, TGA, XBM, XPM, XV];
190 }
191 
192 bool checkImage(Object object) {
193     if (object is null || !( null !is cast(ImageData)object )) return false;
194     return true;
195 }
196 
197 override
198 protected bool validate(Object object) {
199     return checkImage(object);
200 }
201 }