001: /*
002: * Copyright 1996-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.windows;
027:
028: import java.awt.datatransfer.DataFlavor;
029: import java.awt.datatransfer.Transferable;
030: import java.awt.datatransfer.UnsupportedFlavorException;
031:
032: import java.io.IOException;
033:
034: import java.util.Iterator;
035: import java.util.Map;
036:
037: import sun.awt.datatransfer.SunClipboard;
038: import sun.awt.datatransfer.DataTransferer;
039:
040: /**
041: * A class which interfaces with the Windows clipboard in order to support
042: * data transfer via Clipboard operations. Most of the work is provided by
043: * sun.awt.datatransfer.DataTransferer.
044: *
045: * @author Tom Ball
046: * @author David Mendenhall
047: * @author Danila Sinopalnikov
048: * @author Alexander Gerasimov
049: * @version 1.36, 06/05/07
050: *
051: * @since JDK1.1
052: */
053: public class WClipboard extends SunClipboard {
054:
055: private boolean isClipboardViewerRegistered;
056:
057: public WClipboard() {
058: super ("System");
059: }
060:
061: public long getID() {
062: return 0;
063: }
064:
065: protected void setContentsNative(Transferable contents) {
066:
067: // Don't use delayed Clipboard rendering for the Transferable's data.
068: // If we did that, we would call Transferable.getTransferData on
069: // the Toolkit thread, which is a security hole.
070: //
071: // Get all of the target formats into which the Transferable can be
072: // translated. Then, for each format, translate the data and post
073: // it to the Clipboard.
074: Map formatMap = WDataTransferer.getInstance()
075: .getFormatsForTransferable(contents, flavorMap);
076:
077: openClipboard(this );
078:
079: try {
080: for (Iterator iter = formatMap.keySet().iterator(); iter
081: .hasNext();) {
082: Long lFormat = (Long) iter.next();
083: long format = lFormat.longValue();
084: DataFlavor flavor = (DataFlavor) formatMap.get(lFormat);
085:
086: try {
087: byte[] bytes = WDataTransferer.getInstance()
088: .translateTransferable(contents, flavor,
089: format);
090: publishClipboardData(format, bytes);
091: } catch (IOException e) {
092: // Fix 4696186: don't print exception if data with
093: // javaJVMLocalObjectMimeType failed to serialize.
094: // May remove this if-check when 5078787 is fixed.
095: if (!(flavor
096: .isMimeTypeEqual(DataFlavor.javaJVMLocalObjectMimeType) && e instanceof java.io.NotSerializableException)) {
097: e.printStackTrace();
098: }
099: }
100: }
101: } finally {
102: closeClipboard();
103: }
104: }
105:
106: private void lostSelectionOwnershipImpl() {
107: lostOwnershipImpl();
108: }
109:
110: /**
111: * Currently delayed data rendering is not used for the Windows clipboard,
112: * so there is no native context to clear.
113: */
114: protected void clearNativeContext() {
115: }
116:
117: /**
118: * Call the Win32 OpenClipboard function. If newOwner is non-null,
119: * we also call EmptyClipboard and take ownership.
120: *
121: * @throws IllegalStateException if the clipboard has not been opened
122: */
123: public native void openClipboard(SunClipboard newOwner)
124: throws IllegalStateException;
125:
126: /**
127: * Call the Win32 CloseClipboard function if we have clipboard ownership,
128: * does nothing if we have not ownership.
129: */
130: public native void closeClipboard();
131:
132: /**
133: * Call the Win32 SetClipboardData function.
134: */
135: private native void publishClipboardData(long format, byte[] bytes);
136:
137: private static native void init();
138:
139: static {
140: init();
141: }
142:
143: protected native long[] getClipboardFormats();
144:
145: protected native byte[] getClipboardData(long format)
146: throws IOException;
147:
148: protected void registerClipboardViewerChecked() {
149: if (!isClipboardViewerRegistered) {
150: registerClipboardViewer();
151: isClipboardViewerRegistered = true;
152: }
153: }
154:
155: private native void registerClipboardViewer();
156:
157: /**
158: * The clipboard viewer (it's the toolkit window) is not unregistered
159: * until the toolkit window disposing since MSDN suggests removing
160: * the window from the clipboard viewer chain just before it is destroyed.
161: */
162: protected void unregisterClipboardViewerChecked() {
163: }
164:
165: /**
166: * Upcall from native code.
167: */
168: private void handleContentsChanged() {
169: if (!areFlavorListenersRegistered()) {
170: return;
171: }
172:
173: long[] formats = null;
174: try {
175: openClipboard(null);
176: formats = getClipboardFormats();
177: } catch (IllegalStateException exc) {
178: // do nothing to handle the exception, call checkChange(null)
179: } finally {
180: closeClipboard();
181: }
182: checkChange(formats);
183: }
184:
185: /**
186: * The clipboard must be opened.
187: *
188: * @since 1.5
189: */
190: protected Transferable createLocaleTransferable(long[] formats)
191: throws IOException {
192: boolean found = false;
193: for (int i = 0; i < formats.length; i++) {
194: if (formats[i] == WDataTransferer.CF_LOCALE) {
195: found = true;
196: break;
197: }
198: }
199: if (!found) {
200: return null;
201: }
202:
203: byte[] localeData = null;
204: try {
205: localeData = getClipboardData(WDataTransferer.CF_LOCALE);
206: } catch (IOException ioexc) {
207: return null;
208: }
209:
210: final byte[] localeDataFinal = localeData;
211:
212: return new Transferable() {
213: public DataFlavor[] getTransferDataFlavors() {
214: return new DataFlavor[] { DataTransferer.javaTextEncodingFlavor };
215: }
216:
217: public boolean isDataFlavorSupported(DataFlavor flavor) {
218: return flavor
219: .equals(DataTransferer.javaTextEncodingFlavor);
220: }
221:
222: public Object getTransferData(DataFlavor flavor)
223: throws UnsupportedFlavorException {
224: if (isDataFlavorSupported(flavor)) {
225: return localeDataFinal;
226: }
227: throw new UnsupportedFlavorException(flavor);
228: }
229: };
230: }
231:
232: }
|