# HG changeset patch # User lana # Date 1366219802 25200 # Node ID a954e407680cb1df0394f81057f3fe0039ff2b28 # Parent 7ded74ffea36c647914d76799c19be8f508b2297# Parent 6e3763e737b0f9ccc74e30ceb5be474f83a612e8 Merge diff -r 7ded74ffea36 -r a954e407680c src/macosx/classes/sun/lwawt/LWComponentPeer.java --- a/src/macosx/classes/sun/lwawt/LWComponentPeer.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/classes/sun/lwawt/LWComponentPeer.java Wed Apr 17 10:30:02 2013 -0700 @@ -336,7 +336,7 @@ return peerTreeLock; } - final T getTarget() { + public final T getTarget() { return target; } diff -r 7ded74ffea36 -r a954e407680c src/macosx/classes/sun/lwawt/macosx/CClipboard.java --- a/src/macosx/classes/sun/lwawt/macosx/CClipboard.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/classes/sun/lwawt/macosx/CClipboard.java Wed Apr 17 10:30:02 2013 -0700 @@ -110,4 +110,12 @@ public native void declareTypes(long[] formats, SunClipboard newOwner); public native void setData(byte[] data, long format); + + /** + * Invokes native check whether a change count on the general pasteboard is different + * than when we set it. The different count value means the current owner lost + * pasteboard ownership and someone else put data on the clipboard. + * @since 1.7 + */ + public native void checkPasteboard(); } diff -r 7ded74ffea36 -r a954e407680c src/macosx/classes/sun/lwawt/macosx/CCursorManager.java --- a/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java Wed Apr 17 10:30:02 2013 -0700 @@ -51,15 +51,6 @@ @Override protected Point getCursorPosition() { - synchronized(this) { - if (isDragging) { - // during the drag operation, the appkit thread is blocked, - // so nativeGetCursorPosition invocation may cause a deadlock. - // In order to avoid this, we returns last know cursor position. - return new Point(dragPos); - } - } - final Point2D nativePosition = nativeGetCursorPosition(); return new Point((int)nativePosition.getX(), (int)nativePosition.getY()); } @@ -101,31 +92,4 @@ // do something special throw new RuntimeException("Unimplemented"); } - - // package private methods to handle cursor change during drag-and-drop - private boolean isDragging = false; - private Point dragPos = null; - - synchronized void startDrag(int x, int y) { - if (isDragging) { - throw new RuntimeException("Invalid Drag state in CCursorManager!"); - } - isDragging = true; - dragPos = new Point(x, y); - } - - synchronized void updateDragPosition(int x, int y) { - if (!isDragging) { - throw new RuntimeException("Invalid Drag state in CCursorManager!"); - } - dragPos.move(x, y); - } - - synchronized void stopDrag() { - if (!isDragging) { - throw new RuntimeException("Invalid Drag state in CCursorManager!"); - } - isDragging = false; - dragPos = null; - } } diff -r 7ded74ffea36 -r a954e407680c src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java --- a/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java Wed Apr 17 10:30:02 2013 -0700 @@ -174,7 +174,7 @@ bytes = Normalizer.normalize(new String(bytes, "UTF8"), Form.NFC).getBytes("UTF8"); } - return super.translateBytesOrStream(stream, bytes, flavor, format, transferable); + return super.translateBytes(bytes, flavor, format, transferable); } @@ -257,16 +257,13 @@ private native byte[] imageDataToPlatformImageBytes(int[] rData, int nW, int nH); /** - * Translates either a byte array or an input stream which contain + * Translates a byte array which contains * platform-specific image data in the given format into an Image. */ - protected Image platformImageBytesOrStreamToImage(InputStream stream, byte[] bytes, long format) throws IOException { - byte[] imageData = bytes; - - if (imageData == null) - imageData = inputStreamToByteArray(stream); - - return getImageForByteStream(imageData); + protected Image platformImageBytesToImage(byte[] bytes, long format) + throws IOException + { + return getImageForByteStream(bytes); } private native Image getImageForByteStream(byte[] bytes); diff -r 7ded74ffea36 -r a954e407680c src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java --- a/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java Wed Apr 17 10:30:02 2013 -0700 @@ -38,8 +38,12 @@ import javax.accessibility.*; import java.util.Map; +import java.util.concurrent.Callable; + import sun.awt.dnd.*; import sun.lwawt.LWComponentPeer; +import sun.lwawt.LWWindowPeer; +import sun.lwawt.PlatformWindow; public final class CDragSourceContextPeer extends SunDragSourceContextPeer { @@ -104,13 +108,8 @@ } //It sure will be LWComponentPeer instance as rootComponent is a Window - LWComponentPeer peer = (LWComponentPeer)rootComponent.getPeer(); - //Get a pointer to a native window - CPlatformWindow platformWindow = (CPlatformWindow) peer.getPlatformWindow(); - long nativeWindowPtr = platformWindow.getNSWindowPtr(); - - // Get drag cursor: - Cursor cursor = this.getCursor(); + PlatformWindow platformWindow = ((LWComponentPeer)rootComponent.getPeer()).getPlatformWindow(); + long nativeViewPtr = CPlatformWindow.getNativeViewPtr(platformWindow); // If there isn't any drag image make one of default appearance: if (fDragImage == null) @@ -139,19 +138,15 @@ try { // Create native dragging source: - final long nativeDragSource = createNativeDragSource(component, peer, nativeWindowPtr, transferable, triggerEvent, + final long nativeDragSource = createNativeDragSource(component, nativeViewPtr, transferable, triggerEvent, (int) (dragOrigin.getX()), (int) (dragOrigin.getY()), extModifiers, - clickCount, timestamp, cursor, fDragCImage, dragImageOffset.x, dragImageOffset.y, + clickCount, timestamp, fDragCImage, dragImageOffset.x, dragImageOffset.y, getDragSourceContext().getSourceActions(), formats, formatMap); if (nativeDragSource == 0) throw new InvalidDnDOperationException(""); setNativeContext(nativeDragSource); - - CCursorManager.getInstance().startDrag( - (int) (dragOrigin.getX()), - (int) (dragOrigin.getY())); } catch (Exception e) { @@ -160,6 +155,8 @@ SunDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(transferable); + CCursorManager.getInstance().setCursor(getCursor()); + // Create a new thread to run the dragging operation since it's synchronous, only coming back // after dragging is finished. This leaves the AWT event thread free to handle AWT events which // are posted during dragging by native event handlers. @@ -173,8 +170,6 @@ } catch (Exception e) { e.printStackTrace(); } finally { - CCursorManager.getInstance().stopDrag(); - releaseNativeDragSource(nativeDragSource); fDragImage = null; if (fDragCImage != null) { @@ -189,8 +184,6 @@ } catch (Exception e) { - CCursorManager.getInstance().stopDrag(); - final long nativeDragSource = getNativeContext(); setNativeContext(0); releaseNativeDragSource(nativeDragSource); @@ -416,13 +409,24 @@ final int modifiers, final int x, final int y) { - CCursorManager.getInstance().updateDragPosition(x, y); + try { + Component componentAt = LWCToolkit.invokeAndWait( + new Callable() { + @Override + public Component call() { + LWWindowPeer mouseEventComponent = LWWindowPeer.getWindowUnderCursor(); + if (mouseEventComponent == null) { + return null; + } + Component root = SwingUtilities.getRoot(mouseEventComponent.getTarget()); + if (root == null) { + return null; + } + Point rootLocation = root.getLocationOnScreen(); + return getDropTargetAt(root, x - rootLocation.x, y - rootLocation.y); + } + }, getComponent()); - Component rootComponent = SwingUtilities.getRoot(getComponent()); - if(rootComponent != null) { - Point componentPoint = new Point(x, y); - SwingUtilities.convertPointFromScreen(componentPoint, rootComponent); - Component componentAt = SwingUtilities.getDeepestComponentAt(rootComponent, componentPoint.x, componentPoint.y); if(componentAt != hoveringComponent) { if(hoveringComponent != null) { dragExit(x, y); @@ -432,20 +436,36 @@ } hoveringComponent = componentAt; } + + postDragSourceDragEvent(targetActions, modifiers, x, y, + DISPATCH_MOUSE_MOVED); + } catch (Exception e) { + throw new InvalidDnDOperationException("Failed to handle DragMouseMoved event"); } - postDragSourceDragEvent(targetActions, modifiers, x, y, - DISPATCH_MOUSE_MOVED); } - /** - * upcall from native code - */ - private void dragEnter(final int targetActions, - final int modifiers, - final int x, final int y) { - CCursorManager.getInstance().updateDragPosition(x, y); + //Returns the first lightweight or heavyweight Component which has a dropTarget ready to accept the drag + //Should be called from the EventDispatchThread + private static Component getDropTargetAt(Component root, int x, int y) { + if (!root.contains(x, y) || !root.isEnabled() || !root.isVisible()) { + return null; + } + + if (root.getDropTarget() != null && root.getDropTarget().isActive()) { + return root; + } - postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_ENTER); + if (root instanceof Container) { + for (Component comp : ((Container) root).getComponents()) { + Point loc = comp.getLocation(); + Component dropTarget = getDropTargetAt(comp, x - loc.x, y - loc.y); + if (dropTarget != null) { + return dropTarget; + } + } + } + + return null; } /** @@ -455,19 +475,15 @@ hoveringComponent = null; } - public void setCursor(Cursor c) throws InvalidDnDOperationException { - // TODO : BG - //AWTLockAccess.awtLock(); - super.setCursor(c); - //AWTLockAccess.awtUnlock(); + @Override + protected void setNativeCursor(long nativeCtxt, Cursor c, int cType) { + CCursorManager.getInstance().setCursor(c); } - protected native void setNativeCursor(long nativeCtxt, Cursor c, int cType); - // Native support: - private native long createNativeDragSource(Component component, ComponentPeer peer, long nativePeer, Transferable transferable, + private native long createNativeDragSource(Component component, long nativePeer, Transferable transferable, InputEvent triggerEvent, int dragPosX, int dragPosY, int extModifiers, int clickCount, long timestamp, - Cursor cursor, CImage nsDragImage, int dragImageOffsetX, int dragImageOffsetY, + CImage nsDragImage, int dragImageOffsetX, int dragImageOffsetY, int sourceActions, long[] formats, Map formatMap); private native void doDragging(long nativeDragSource); diff -r 7ded74ffea36 -r a954e407680c src/macosx/classes/sun/lwawt/macosx/CDropTarget.java --- a/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java Wed Apr 17 10:30:02 2013 -0700 @@ -30,6 +30,7 @@ import java.awt.dnd.DropTarget; import sun.lwawt.LWComponentPeer; +import sun.lwawt.PlatformWindow; public final class CDropTarget { @@ -50,21 +51,11 @@ fComponent = component; fPeer = peer; - // Make sure the drop target is a ComponentModel: - if (!(peer instanceof LWComponentPeer)) - throw new IllegalArgumentException("CDropTarget's peer must be a LWComponentPeer."); - - // Get model pointer (CButton.m and such) and its native peer: - LWComponentPeer model = (LWComponentPeer) peer; - if (model.getPlatformWindow() instanceof CPlatformWindow) { - CPlatformWindow platformWindow = (CPlatformWindow) model.getPlatformWindow(); - long nativePeer = platformWindow.getNSWindowPtr(); - - // Create native dragging destination: - fNativeDropTarget = this.createNativeDropTarget(dropTarget, component, peer, nativePeer); - if (fNativeDropTarget == 0) { - throw new IllegalStateException("CDropTarget.createNativeDropTarget() failed."); - } + long nativePeer = CPlatformWindow.getNativeViewPtr(((LWComponentPeer) peer).getPlatformWindow()); + // Create native dragging destination: + fNativeDropTarget = this.createNativeDropTarget(dropTarget, component, peer, nativePeer); + if (fNativeDropTarget == 0) { + throw new IllegalStateException("CDropTarget.createNativeDropTarget() failed."); } } diff -r 7ded74ffea36 -r a954e407680c src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java --- a/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java Wed Apr 17 10:30:02 2013 -0700 @@ -112,6 +112,14 @@ public void handleFocusEvent(boolean focused) { this.focused = focused; + if (focused) { + // see bug 8010925 + // we can't put this to handleWindowFocusEvent because + // it won't be invoced if focuse is moved to a html element + // on the same page. + CClipboard clipboard = (CClipboard) Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.checkPasteboard(); + } if (parentWindowActive) { responder.handleWindowFocusEvent(focused, null); } diff -r 7ded74ffea36 -r a954e407680c src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java --- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Wed Apr 17 10:30:02 2013 -0700 @@ -875,6 +875,21 @@ } } + /** + * Helper method to get a pointer to the native view from the PlatformWindow. + */ + static long getNativeViewPtr(PlatformWindow platformWindow) { + long nativePeer = 0L; + if (platformWindow instanceof CPlatformWindow) { + nativePeer = ((CPlatformWindow) platformWindow).getContentView().getAWTView(); + } else if (platformWindow instanceof CViewPlatformEmbeddedFrame){ + nativePeer = ((CViewPlatformEmbeddedFrame) platformWindow).getNSViewPtr(); + } else { + throw new IllegalArgumentException("Unsupported platformWindow implementation"); + } + return nativePeer; + } + /************************************************************* * Callbacks from the AWTWindow and AWTView objc classes. *************************************************************/ diff -r 7ded74ffea36 -r a954e407680c src/macosx/native/sun/awt/CClipboard.m --- a/src/macosx/native/sun/awt/CClipboard.m Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/native/sun/awt/CClipboard.m Wed Apr 17 10:30:02 2013 -0700 @@ -189,18 +189,18 @@ - (void) checkPasteboard:(id)application { AWT_ASSERT_APPKIT_THREAD; - + //NSLog(@"CClipboard checkPasteboard oldCount %d newCount %d newTypes %@", fChangeCount, [[NSPasteboard generalPasteboard] changeCount], [[NSPasteboard generalPasteboard] types]); - + // This is called via NSApplicationDidBecomeActiveNotification. - + // If the change count on the general pasteboard is different than when we set it // someone else put data on the clipboard. That means the current owner lost ownership. NSInteger newChangeCount = [[NSPasteboard generalPasteboard] changeCount]; - + if (fChangeCount != newChangeCount) { fChangeCount = newChangeCount; - + [self pasteboardChangedOwner:[NSPasteboard generalPasteboard]]; } } @@ -371,4 +371,21 @@ return returnValue; } +/* + * Class: sun_lwawt_macosx_CClipboard + * Method: checkPasteboard + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_checkPasteboard +(JNIEnv *env, jobject inObject ) +{ + JNF_COCOA_ENTER(env); + [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ + [[CClipboard sharedClipboard] checkPasteboard:nil]; + }]; + + JNF_COCOA_EXIT(env); +} + + diff -r 7ded74ffea36 -r a954e407680c src/macosx/native/sun/awt/CDragSource.h --- a/src/macosx/native/sun/awt/CDragSource.h Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/native/sun/awt/CDragSource.h Wed Apr 17 10:30:02 2013 -0700 @@ -33,7 +33,6 @@ @private NSView* fView; jobject fComponent; - jobject fComponentPeer; jobject fDragSourceContextPeer; jobject fTransferable; @@ -43,8 +42,6 @@ jint fClickCount; jint fModifiers; - jobject fCursor; - NSImage* fDragImage; NSPoint fDragImageOffset; @@ -59,12 +56,22 @@ + (CDragSource *) currentDragSource; // Common methods: -- (id)init:(jobject)jdragsourcecontextpeer component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control - transferable:(jobject)jtransferable triggerEvent:(jobject)jtrigger - dragPosX:(jint)dragPosX dragPosY:(jint)dragPosY modifiers:(jint)extModifiers clickCount:(jint)clickCount timeStamp:(jlong)timeStamp - cursor:(jobject)jcursor - dragImage:(jobject)jnsdragimage dragImageOffsetX:(jint)jdragimageoffsetx dragImageOffsetY:(jint)jdragimageoffsety - sourceActions:(jint)jsourceactions formats:(jlongArray)jformats formatMap:(jobject)jformatmap; +- (id) init:(jobject)jDragSourceContextPeer + component:(jobject)jComponent + control:(id)control + transferable:(jobject)jTransferable + triggerEvent:(jobject)jTrigger + dragPosX:(jint)dragPosX + dragPosY:(jint)dragPosY + modifiers:(jint)extModifiers + clickCount:(jint)clickCount + timeStamp:(jlong)timeStamp + dragImage:(jobject)jDragImage + dragImageOffsetX:(jint)jDragImageOffsetX + dragImageOffsetY:(jint)jDragImageOffsetY + sourceActions:(jint)jSourceActions + formats:(jlongArray)jFormats + formatMap:(jobject)jFormatMap; - (void)removeFromView:(JNIEnv *)env; diff -r 7ded74ffea36 -r a954e407680c src/macosx/native/sun/awt/CDragSource.m --- a/src/macosx/native/sun/awt/CDragSource.m Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/native/sun/awt/CDragSource.m Wed Apr 17 10:30:02 2013 -0700 @@ -84,12 +84,22 @@ return sCurrentDragSource; } -- (id)init:(jobject)jdragsourcecontextpeer component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control - transferable:(jobject)jtransferable triggerEvent:(jobject)jtrigger - dragPosX:(jint)dragPosX dragPosY:(jint)dragPosY modifiers:(jint)extModifiers clickCount:(jint)clickCount - timeStamp:(jlong)timeStamp cursor:(jobject)jcursor - dragImage:(jobject)jnsdragimage dragImageOffsetX:(jint)jdragimageoffsetx dragImageOffsetY:(jint)jdragimageoffsety - sourceActions:(jint)jsourceactions formats:(jlongArray)jformats formatMap:(jobject)jformatmap +- (id) init:(jobject)jDragSourceContextPeer + component:(jobject)jComponent + control:(id)control + transferable:(jobject)jTransferable + triggerEvent:(jobject)jTrigger + dragPosX:(jint)dragPosX + dragPosY:(jint)dragPosY + modifiers:(jint)extModifiers + clickCount:(jint)clickCount + timeStamp:(jlong)timeStamp + dragImage:(jobject)jDragImage + dragImageOffsetX:(jint)jDragImageOffsetX + dragImageOffsetY:(jint)jDragImageOffsetY + sourceActions:(jint)jSourceActions + formats:(jlongArray)jFormats + formatMap:(jobject)jFormatMap { self = [super init]; DLog2(@"[CDragSource init]: %@\n", self); @@ -100,27 +110,25 @@ // Construct the object if we have a valid model for it: if (control != nil) { JNIEnv *env = [ThreadUtilities getJNIEnv]; - fComponent = JNFNewGlobalRef(env, jcomponent); - fComponentPeer = JNFNewGlobalRef(env, jpeer); - fDragSourceContextPeer = JNFNewGlobalRef(env, jdragsourcecontextpeer); + fComponent = JNFNewGlobalRef(env, jComponent); + fDragSourceContextPeer = JNFNewGlobalRef(env, jDragSourceContextPeer); - fTransferable = JNFNewGlobalRef(env, jtransferable); - fTriggerEvent = JNFNewGlobalRef(env, jtrigger); - fCursor = JNFNewGlobalRef(env, jcursor); + fTransferable = JNFNewGlobalRef(env, jTransferable); + fTriggerEvent = JNFNewGlobalRef(env, jTrigger); - if (jnsdragimage) { + if (jDragImage) { JNF_MEMBER_CACHE(nsImagePtr, CImageClass, "ptr", "J"); - jlong imgPtr = JNFGetLongField(env, jnsdragimage, nsImagePtr); + jlong imgPtr = JNFGetLongField(env, jDragImage, nsImagePtr); fDragImage = (NSImage*) jlong_to_ptr(imgPtr); // Double-casting prevents compiler 'd$|// [fDragImage retain]; } - fDragImageOffset = NSMakePoint(jdragimageoffsetx, jdragimageoffsety); + fDragImageOffset = NSMakePoint(jDragImageOffsetX, jDragImageOffsetY); - fSourceActions = jsourceactions; - fFormats = JNFNewGlobalRef(env, jformats); - fFormatMap = JNFNewGlobalRef(env, jformatmap); + fSourceActions = jSourceActions; + fFormats = JNFNewGlobalRef(env, jFormats); + fFormatMap = JNFNewGlobalRef(env, jFormatMap); fTriggerEventTimeStamp = timeStamp; fDragPos = NSMakePoint(dragPosX, dragPosY); @@ -129,9 +137,8 @@ // Set this object as a dragging source: - AWTView *awtView = [((NSWindow *) control) contentView]; - fView = [awtView retain]; - [awtView setDragSource:self]; + fView = [(AWTView *) control retain]; + [fView setDragSource:self]; // Let AWTEvent know Java drag is getting underway: [NSEvent javaDraggingBegin]; @@ -158,11 +165,6 @@ fComponent = NULL; } - if (fComponentPeer != NULL) { - JNFDeleteGlobalRef(env, fComponentPeer); - fComponentPeer = NULL; - } - if (fDragSourceContextPeer != NULL) { JNFDeleteGlobalRef(env, fDragSourceContextPeer); fDragSourceContextPeer = NULL; @@ -178,11 +180,6 @@ fTriggerEvent = NULL; } - if (fCursor != NULL) { - JNFDeleteGlobalRef(env, fCursor); - fCursor = NULL; - } - if (fFormats != NULL) { JNFDeleteGlobalRef(env, fFormats); fFormats = NULL; @@ -586,11 +583,6 @@ { AWT_ASSERT_NOT_APPKIT_THREAD; - // Set the drag cursor (or not 3839999) - //JNIEnv *env = [ThreadUtilities getJNIEnv]; - //jobject gCursor = JNFNewGlobalRef(env, fCursor); - //[EventFactory setJavaCursor:gCursor withEnv:env]; - [self performSelectorOnMainThread:@selector(doDrag) withObject:nil waitUntilDone:YES]; // AWT_THREADING Safe (called from unique asynchronous thread) } diff -r 7ded74ffea36 -r a954e407680c src/macosx/native/sun/awt/CDragSourceContextPeer.m --- a/src/macosx/native/sun/awt/CDragSourceContextPeer.m Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/native/sun/awt/CDragSourceContextPeer.m Wed Apr 17 10:30:02 2013 -0700 @@ -34,12 +34,13 @@ /* * Class: sun_lwawt_macosx_CDragSourceContextPeer * Method: createNativeDragSource - * Signature: (Ljava/awt/Component;Ljava/awt/peer/ComponentPeer;JLjava/awt/datatransfer/Transferable;Ljava/awt/event/InputEvent;IIIIJLjava/awt/Cursor;IJIII[JLjava/util/Map;)J + * Signature: (Ljava/awt/Component;JLjava/awt/datatransfer/Transferable; + Ljava/awt/event/InputEvent;IIIIJIJIII[JLjava/util/Map;)J */ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_createNativeDragSource - (JNIEnv *env, jobject jthis, jobject jcomponent, jobject jpeer, jlong jnativepeer, jobject jtransferable, + (JNIEnv *env, jobject jthis, jobject jcomponent, jlong jnativepeer, jobject jtransferable, jobject jtrigger, jint jdragposx, jint jdragposy, jint jextmodifiers, jint jclickcount, jlong jtimestamp, - jobject jcursor, jobject jnsdragimage, jint jdragimageoffsetx, jint jdragimageoffsety, + jobject jnsdragimage, jint jdragimageoffsetx, jint jdragimageoffsety, jint jsourceactions, jlongArray jformats, jobject jformatmap) { id controlObj = (id) jlong_to_ptr(jnativepeer); @@ -47,12 +48,22 @@ JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - dragSource = [[CDragSource alloc] init:jthis component:jcomponent peer:jpeer control:controlObj - transferable:jtransferable triggerEvent:jtrigger dragPosX:jdragposx - dragPosY:jdragposy modifiers:jextmodifiers clickCount:jclickcount timeStamp:jtimestamp - cursor:jcursor dragImage:jnsdragimage dragImageOffsetX:jdragimageoffsetx - dragImageOffsetY:jdragimageoffsety sourceActions:jsourceactions - formats:jformats formatMap:jformatmap]; + dragSource = [[CDragSource alloc] init:jthis + component:jcomponent + control:controlObj + transferable:jtransferable + triggerEvent:jtrigger + dragPosX:jdragposx + dragPosY:jdragposy + modifiers:jextmodifiers + clickCount:jclickcount + timeStamp:jtimestamp + dragImage:jnsdragimage + dragImageOffsetX:jdragimageoffsetx + dragImageOffsetY:jdragimageoffsety + sourceActions:jsourceactions + formats:jformats + formatMap:jformatmap]; }]; JNF_COCOA_EXIT(env); @@ -94,19 +105,3 @@ [dragSource removeFromView:env]; JNF_COCOA_EXIT(env); } - -/* - * Class: sun_lwawt_macosx_CDragSourceContextPeer - * Method: setNativeCursor - * Signature: (JLjava/awt/Cursor;I)V - */ -JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_setNativeCursor - (JNIEnv *env, jobject jthis, jlong nativeDragSourceVal, jobject jcursor, jint jcursortype) -{ - //AWT_ASSERT_NOT_APPKIT_THREAD; - -//JNF_COCOA_ENTER(env); -// jobject gCursor = JNFNewGlobalRef(env, jcursor); -// [EventFactory setJavaCursor:gCursor withEnv:env]; -//JNF_COCOA_EXIT(env); -} diff -r 7ded74ffea36 -r a954e407680c src/macosx/native/sun/awt/CDropTarget.m --- a/src/macosx/native/sun/awt/CDropTarget.m Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/native/sun/awt/CDropTarget.m Wed Apr 17 10:30:02 2013 -0700 @@ -81,9 +81,8 @@ fComponent = JNFNewGlobalRef(env, jcomponent); fDropTarget = JNFNewGlobalRef(env, jdropTarget); - AWTView *awtView = [((NSWindow *) control) contentView]; - fView = [awtView retain]; - [awtView setDropTarget:self]; + fView = [((AWTView *) control) retain]; + [fView setDropTarget:self]; } else { @@ -177,6 +176,10 @@ { DLog2(@"[CDropTarget dealloc]: %@\n", self); + if(sCurrentDropTarget == self) { + sCurrentDropTarget = nil; + } + [fView release]; fView = nil; @@ -490,7 +493,10 @@ JNF_MEMBER_CACHE(handleEnterMessageMethod, jc_CDropTargetContextPeer, "handleEnterMessage", "(Ljava/awt/Component;IIII[JJ)I"); if (sDraggingError == FALSE) { // Double-casting self gets rid of 'different size' compiler warning: - actions = JNFCallIntMethod(env, fDropTargetContextPeer, handleEnterMessageMethod, fComponent, (jint) javaLocation.x, (jint) javaLocation.y, dropAction, actions, formats, ptr_to_jlong(self)); // AWT_THREADING Safe (CToolkitThreadBlockedHandler) + // AWT_THREADING Safe (CToolkitThreadBlockedHandler) + actions = JNFCallIntMethod(env, fDropTargetContextPeer, handleEnterMessageMethod, + fComponent, (jint) javaLocation.x, (jint) javaLocation.y, + dropAction, actions, formats, ptr_to_jlong(self)); } if (sDraggingError == FALSE) { @@ -510,11 +516,6 @@ // Remember the dragOp for no-op'd update messages: sUpdateOperation = dragOp; } - - // If we are in the same process as the sender, make the sender post the appropriate message - if (sender) { - [[CDragSource currentDragSource] postDragEnter]; - } } // 9-11-02 Note: the native event thread would not handle an exception gracefully: @@ -608,11 +609,9 @@ JNF_MEMBER_CACHE(handleExitMessageMethod, jc_CDropTargetContextPeer, "handleExitMessage", "(Ljava/awt/Component;J)V"); if (sDraggingError == FALSE) { DLog3(@" - dragExit: loc native %f, %f\n", sDraggingLocation.x, sDraggingLocation.y); - JNFCallVoidMethod(env, fDropTargetContextPeer, handleExitMessageMethod, fComponent, ptr_to_jlong(self)); // AWT_THREADING Safe (CToolkitThreadBlockedHandler) - // If we are in the same process as the sender, make the sender post the appropriate message - if (sender) { - [[CDragSource currentDragSource] postDragExit]; - } + // AWT_THREADING Safe (CToolkitThreadBlockedHandler) + JNFCallVoidMethod(env, fDropTargetContextPeer, + handleExitMessageMethod, fComponent, ptr_to_jlong(self)); } // 5-27-03 Note: [Radar 3270455] diff -r 7ded74ffea36 -r a954e407680c src/macosx/native/sun/awt/CTextPipe.m --- a/src/macosx/native/sun/awt/CTextPipe.m Wed Apr 17 16:11:19 2013 +0100 +++ b/src/macosx/native/sun/awt/CTextPipe.m Wed Apr 17 10:30:02 2013 -0700 @@ -501,10 +501,22 @@ int *uniChars = (int *)malloc(sizeof(int) * length); CGSize *advances = (CGSize *)malloc(sizeof(CGSize) * length); - if (glyphs == NULL || advances == NULL) + if (glyphs == NULL || uniChars == NULL || advances == NULL) { (*env)->DeleteLocalRef(env, glyphsArray); [NSException raise:NSMallocException format:@"%s-%s:%d", THIS_FILE, __FUNCTION__, __LINE__]; + if (glyphs) + { + free(glyphs); + } + if (uniChars) + { + free(uniChars); + } + if (advances) + { + free(advances); + } return; } diff -r 7ded74ffea36 -r a954e407680c src/share/classes/java/awt/datatransfer/DataFlavor.java --- a/src/share/classes/java/awt/datatransfer/DataFlavor.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/share/classes/java/awt/datatransfer/DataFlavor.java Wed Apr 17 10:30:02 2013 -0700 @@ -25,7 +25,6 @@ package java.awt.datatransfer; -import java.awt.Toolkit; import java.io.*; import java.nio.*; import java.util.*; @@ -162,6 +161,18 @@ } } + /* + * private initializer + */ + static private DataFlavor initHtmlDataFlavor(String htmlFlavorType) { + try { + return new DataFlavor ("text/html; class=java.lang.String;document=" + + htmlFlavorType + ";charset=Unicode"); + } catch (Exception e) { + return null; + } + } + /** * The DataFlavor representing a Java Unicode String class, * where: @@ -246,6 +257,46 @@ public static final String javaRemoteObjectMimeType = "application/x-java-remote-object"; /** + * Represents a piece of an HTML markup. The markup consists of the part + * selected on the source side. Therefore some tags in the markup may be + * unpaired. If the flavor is used to represent the data in + * a {@link Transferable} instance, no additional changes will be made. + * This DataFlavor instance represents the same HTML markup as DataFlavor + * instances which content MIME type does not contain document parameter + * and representation class is the String class. + *
+     *     representationClass = String
+     *     mimeType           = "text/html"
+     * 
+ */ + public static DataFlavor selectionHtmlFlavor = initHtmlDataFlavor("selection"); + + /** + * Represents a piece of an HTML markup. If possible, the markup received + * from a native system is supplemented with pair tags to be + * a well-formed HTML markup. If the flavor is used to represent the data in + * a {@link Transferable} instance, no additional changes will be made. + *
+     *     representationClass = String
+     *     mimeType           = "text/html"
+     * 
+ */ + public static DataFlavor fragmentHtmlFlavor = initHtmlDataFlavor("fragment"); + + /** + * Represents a piece of an HTML markup. If possible, the markup + * received from a native system is supplemented with additional + * tags to make up a well-formed HTML document. If the flavor is used to + * represent the data in a {@link Transferable} instance, + * no additional changes will be made. + *
+     *     representationClass = String
+     *     mimeType           = "text/html"
+     * 
+ */ + public static DataFlavor allHtmlFlavor = initHtmlDataFlavor("all"); + + /** * Constructs a new DataFlavor. This constructor is * provided only for the purpose of supporting the * Externalizable interface. It is not @@ -949,24 +1000,35 @@ return false; } - if ("text".equals(getPrimaryType()) && - DataTransferer.doesSubtypeSupportCharset(this) && - representationClass != null && - !(isRepresentationClassReader() || - String.class.equals(representationClass) || - isRepresentationClassCharBuffer() || - DataTransferer.charArrayClass.equals(representationClass))) - { - String thisCharset = - DataTransferer.canonicalName(getParameter("charset")); - String thatCharset = - DataTransferer.canonicalName(that.getParameter("charset")); - if (thisCharset == null) { - if (thatCharset != null) { - return false; + if ("text".equals(getPrimaryType())) { + if (DataTransferer.doesSubtypeSupportCharset(this) && + representationClass != null && + !(isRepresentationClassReader() || + String.class.equals(representationClass) || + isRepresentationClassCharBuffer() || + DataTransferer.charArrayClass.equals(representationClass))) + { + String thisCharset = + DataTransferer.canonicalName(getParameter("charset")); + String thatCharset = + DataTransferer.canonicalName(that.getParameter("charset")); + if (thisCharset == null) { + if (thatCharset != null) { + return false; + } + } else { + if (!thisCharset.equals(thatCharset)) { + return false; + } } - } else { - if (!thisCharset.equals(thatCharset)) { + } + + if ("html".equals(getSubType()) && + this.getParameter("document") != null ) + { + if (!this.getParameter("document"). + equals(that.getParameter("document"))) + { return false; } } diff -r 7ded74ffea36 -r a954e407680c src/share/classes/java/awt/datatransfer/SystemFlavorMap.java --- a/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Wed Apr 17 10:30:02 2013 -0700 @@ -41,7 +41,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -101,6 +101,11 @@ private static final String TEXT_PLAIN_BASE_TYPE = "text/plain"; /** + * A String representing text/html MIME type. + */ + private static final String HTML_TEXT_BASE_TYPE = "text/html"; + + /** * This constant is passed to flavorToNativeLookup() to indicate that a * a native should be synthesized, stored, and returned by encoding the * DataFlavor's MIME type in case if the DataFlavor is not found in @@ -113,7 +118,7 @@ * text DataFlavors). * Do not use the field directly, use getNativeToFlavor() instead. */ - private Map nativeToFlavor = new HashMap(); + private final Map> nativeToFlavor = new HashMap<>(); /** * Accessor to nativeToFlavor map. Since we use lazy initialization we must @@ -122,7 +127,7 @@ * * @return nativeToFlavor */ - private Map getNativeToFlavor() { + private Map> getNativeToFlavor() { if (!isMapInitialized) { initSystemFlavorMap(); } @@ -134,7 +139,7 @@ * native Strings. * Do not use the field directly, use getFlavorToNative() instead. */ - private Map flavorToNative = new HashMap(); + private final Map flavorToNative = new HashMap(); /** * Accessor to flavorToNative map. Since we use lazy initialization we must @@ -421,14 +426,17 @@ } } - // For text/* flavors, store mappings in separate maps to - // enable dynamic mapping generation at a run-time. + final LinkedHashSet dfs = new LinkedHashSet<>(); + + dfs.add(flavor); + if ("text".equals(flavor.getPrimaryType())) { - store(value, key, getFlavorToNative()); - store(key, value, getNativeToFlavor()); - } else { - store(flavor, key, getFlavorToNative()); - store(key, flavor, getNativeToFlavor()); + dfs.addAll(convertMimeTypeToDataFlavors(value)); + } + + for (DataFlavor df : dfs) { + store(df, key, getFlavorToNative()); + store(key, df, getNativeToFlavor()); } } } @@ -530,7 +538,7 @@ * only if the specified native is encoded as a Java MIME type. */ private List nativeToFlavorLookup(String nat) { - List flavors = (List)getNativeToFlavor().get(nat); + List flavors = getNativeToFlavor().get(nat); if (nat != null && !disabledMappingGenerationKeys.contains(nat)) { DataTransferer transferer = DataTransferer.getInstance(); @@ -625,7 +633,7 @@ getNativesForFlavorCache.remove(flav); getNativesForFlavorCache.remove(null); - List flavors = (List)getNativeToFlavor().get(encoded); + List flavors = getNativeToFlavor().get(encoded); if (flavors == null) { flavors = new ArrayList(1); getNativeToFlavor().put(encoded, flavors); @@ -681,7 +689,7 @@ } if (flav == null) { - retval = new ArrayList(getNativeToFlavor().keySet()); + retval = new ArrayList(getNativeToFlavor().keySet()); } else if (disabledMappingGenerationKeys.contains(flav)) { // In this case we shouldn't synthesize a native for this flavor, // since its mappings were explicitly specified. @@ -809,140 +817,162 @@ } } - LinkedList retval = new LinkedList(); + final LinkedHashSet returnValue = + new LinkedHashSet<>(); if (nat == null) { - List natives = getNativesForFlavor(null); - HashSet dups = new HashSet(natives.size()); + final List natives = getNativesForFlavor(null); - for (Iterator natives_iter = natives.iterator(); - natives_iter.hasNext(); ) + for (String n : natives) { - List flavors = - getFlavorsForNative((String)natives_iter.next()); - for (Iterator flavors_iter = flavors.iterator(); - flavors_iter.hasNext(); ) + final List flavors = getFlavorsForNative(n); + + for (DataFlavor df : flavors) { - Object flavor = flavors_iter.next(); - if (dups.add(flavor)) { - retval.add(flavor); - } + returnValue.add(df); } } } else { - List flavors = nativeToFlavorLookup(nat); + + final List flavors = nativeToFlavorLookup(nat); if (disabledMappingGenerationKeys.contains(nat)) { return flavors; } - HashSet dups = new HashSet(flavors.size()); - - List flavorsAndbaseTypes = nativeToFlavorLookup(nat); - - for (Iterator flavorsAndbaseTypes_iter = - flavorsAndbaseTypes.iterator(); - flavorsAndbaseTypes_iter.hasNext(); ) - { - Object value = flavorsAndbaseTypes_iter.next(); - if (value instanceof String) { - String baseType = (String)value; - String subType = null; - try { - MimeType mimeType = new MimeType(baseType); - subType = mimeType.getSubType(); - } catch (MimeTypeParseException mtpe) { - // Cannot happen, since we checked all mappings - // on load from flavormap.properties. - assert(false); - } - if (DataTransferer.doesSubtypeSupportCharset(subType, - null)) { - if (TEXT_PLAIN_BASE_TYPE.equals(baseType) && - dups.add(DataFlavor.stringFlavor)) - { - retval.add(DataFlavor.stringFlavor); - } - - for (int i = 0; i < UNICODE_TEXT_CLASSES.length; i++) { - DataFlavor toAdd = null; - try { - toAdd = new DataFlavor - (baseType + ";charset=Unicode;class=" + - UNICODE_TEXT_CLASSES[i]); - } catch (ClassNotFoundException cannotHappen) { - } - if (dups.add(toAdd)) { - retval.add(toAdd); - } - } - - for (Iterator charset_iter = - DataTransferer.standardEncodings(); - charset_iter.hasNext(); ) - { - String charset = (String)charset_iter.next(); + final List flavorsAndBaseTypes = + nativeToFlavorLookup(nat); - for (int i = 0; i < ENCODED_TEXT_CLASSES.length; - i++) - { - DataFlavor toAdd = null; - try { - toAdd = new DataFlavor - (baseType + ";charset=" + charset + - ";class=" + ENCODED_TEXT_CLASSES[i]); - } catch (ClassNotFoundException cannotHappen) { - } - - // Check for equality to plainTextFlavor so - // that we can ensure that the exact charset of - // plainTextFlavor, not the canonical charset - // or another equivalent charset with a - // different name, is used. - if (toAdd.equals(DataFlavor.plainTextFlavor)) { - toAdd = DataFlavor.plainTextFlavor; - } - - if (dups.add(toAdd)) { - retval.add(toAdd); - } - } - } - - if (TEXT_PLAIN_BASE_TYPE.equals(baseType) && - dups.add(DataFlavor.plainTextFlavor)) - { - retval.add(DataFlavor.plainTextFlavor); - } - } else { - // Non-charset text natives should be treated as - // opaque, 8-bit data in any of its various - // representations. - for (int i = 0; i < ENCODED_TEXT_CLASSES.length; i++) { - DataFlavor toAdd = null; - try { - toAdd = new DataFlavor(baseType + - ";class=" + ENCODED_TEXT_CLASSES[i]); - } catch (ClassNotFoundException cannotHappen) { - } - - if (dups.add(toAdd)) { - retval.add(toAdd); - } - } - } - } else { - DataFlavor flavor = (DataFlavor)value; - if (dups.add(flavor)) { - retval.add(flavor); + for (DataFlavor df : flavorsAndBaseTypes) { + returnValue.add(df); + if ("text".equals(df.getPrimaryType())) { + try { + returnValue.addAll( + convertMimeTypeToDataFlavors( + new MimeType(df.getMimeType() + ).getBaseType())); + } catch (MimeTypeParseException e) { + e.printStackTrace(); } } } + + } + + final ArrayList arrayList = new ArrayList(returnValue); + getFlavorsForNativeCache.put(nat, new SoftReference(arrayList)); + return (List)arrayList.clone(); + } + + private static LinkedHashSet convertMimeTypeToDataFlavors( + final String baseType) { + + final LinkedHashSet returnValue = + new LinkedHashSet(); + + String subType = null; + + try { + final MimeType mimeType = new MimeType(baseType); + subType = mimeType.getSubType(); + } catch (MimeTypeParseException mtpe) { + // Cannot happen, since we checked all mappings + // on load from flavormap.properties. + assert(false); } - ArrayList arrayList = new ArrayList(retval); - getFlavorsForNativeCache.put(nat, new SoftReference(arrayList)); - return (List)arrayList.clone(); + if (DataTransferer.doesSubtypeSupportCharset(subType, null)) { + if (TEXT_PLAIN_BASE_TYPE.equals(baseType)) + { + returnValue.add(DataFlavor.stringFlavor); + } + + for (String unicodeClassName : UNICODE_TEXT_CLASSES) { + final String mimeType = baseType + ";charset=Unicode;class=" + + unicodeClassName; + + final LinkedHashSet mimeTypes = + handleHtmlMimeTypes(baseType, mimeType); + for (String mt : mimeTypes) { + DataFlavor toAdd = null; + try { + toAdd = new DataFlavor(mt); + } catch (ClassNotFoundException cannotHappen) { + } + returnValue.add(toAdd); + } + } + + for (String charset : DataTransferer.standardEncodings()) { + + for (String encodedTextClass : ENCODED_TEXT_CLASSES) { + final String mimeType = + baseType + ";charset=" + charset + + ";class=" + encodedTextClass; + + final LinkedHashSet mimeTypes = + handleHtmlMimeTypes(baseType, mimeType); + + for (String mt : mimeTypes) { + + DataFlavor df = null; + + try { + df = new DataFlavor(mt); + // Check for equality to plainTextFlavor so + // that we can ensure that the exact charset of + // plainTextFlavor, not the canonical charset + // or another equivalent charset with a + // different name, is used. + if (df.equals(DataFlavor.plainTextFlavor)) { + df = DataFlavor.plainTextFlavor; + } + } catch (ClassNotFoundException cannotHappen) { + } + + returnValue.add(df); + } + } + } + + if (TEXT_PLAIN_BASE_TYPE.equals(baseType)) + { + returnValue.add(DataFlavor.plainTextFlavor); + } + } else { + // Non-charset text natives should be treated as + // opaque, 8-bit data in any of its various + // representations. + for (String encodedTextClassName : ENCODED_TEXT_CLASSES) { + DataFlavor toAdd = null; + try { + toAdd = new DataFlavor(baseType + + ";class=" + encodedTextClassName); + } catch (ClassNotFoundException cannotHappen) { + } + returnValue.add(toAdd); + } + } + return returnValue; + } + + private static final String [] htmlDocumntTypes = + new String [] {"all", "selection", "fragment"}; + + private static LinkedHashSet handleHtmlMimeTypes( + String baseType, String mimeType) { + + LinkedHashSet returnValues = new LinkedHashSet<>(); + + if (HTML_TEXT_BASE_TYPE.equals(baseType)) { + for (String documentType : htmlDocumntTypes) { + returnValues.add(mimeType + ";document=" + documentType); + } + } else { + returnValues.add(mimeType); + } + + return returnValues; } /** diff -r 7ded74ffea36 -r a954e407680c src/share/classes/java/awt/dnd/InvalidDnDOperationException.java --- a/src/share/classes/java/awt/dnd/InvalidDnDOperationException.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/share/classes/java/awt/dnd/InvalidDnDOperationException.java Wed Apr 17 10:30:02 2013 -0700 @@ -36,7 +36,7 @@ public class InvalidDnDOperationException extends IllegalStateException { - private static final long serialVersionUID = 5156676500247816278L; + private static final long serialVersionUID = -6062568741193956678L; static private String dft_msg = "The operation requested cannot be performed by the DnD system since it is not in the appropriate state"; diff -r 7ded74ffea36 -r a954e407680c src/share/classes/sun/awt/datatransfer/DataTransferer.java --- a/src/share/classes/sun/awt/datatransfer/DataTransferer.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/share/classes/sun/awt/datatransfer/DataTransferer.java Wed Apr 17 10:30:02 2013 -0700 @@ -171,12 +171,12 @@ * Lazy initialization of Standard Encodings. */ private static class StandardEncodingsHolder { - private static final SortedSet standardEncodings = load(); - - private static SortedSet load() { + private static final SortedSet standardEncodings = load(); + + private static SortedSet load() { final Comparator comparator = new CharsetComparator(IndexedComparator.SELECT_WORST); - final SortedSet tempSet = new TreeSet(comparator); + final SortedSet tempSet = new TreeSet(comparator); tempSet.add("US-ASCII"); tempSet.add("ISO-8859-1"); tempSet.add("UTF-8"); @@ -523,8 +523,8 @@ * So as to avoid loading all available character converters, optional, * non-standard, character sets are not included. */ - public static Iterator standardEncodings() { - return StandardEncodingsHolder.standardEncodings.iterator(); + public static Set standardEncodings() { + return StandardEncodingsHolder.standardEncodings; } /** @@ -1068,17 +1068,10 @@ * * Native to Java string conversion */ - private String translateBytesOrStreamToString(InputStream str, byte[] bytes, - long format, - Transferable localeTransferable) + private String translateBytesToString(byte[] bytes, long format, + Transferable localeTransferable) throws IOException { - // A String holds all of its data in memory at one time, so - // we can't avoid reading the entire InputStream at this point. - if (bytes == null) { - bytes = inputStreamToByteArray(str); - } - str.close(); Long lFormat = Long.valueOf(format); String charset = getBestCharsetForTextFormat(lFormat, localeTransferable); @@ -1221,13 +1214,13 @@ ("cannot transfer non-text data as Reader"); } - Reader r = (Reader)obj; StringBuffer buf = new StringBuffer(); - int c; - while ((c = r.read()) != -1) { - buf.append((char)c); + try (Reader r = (Reader)obj) { + int c; + while ((c = r.read()) != -1) { + buf.append((char)c); + } } - r.close(); return translateTransferableString( buf.toString(), @@ -1309,7 +1302,7 @@ return bytes; } - ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] theByteArray = null; // Target data is a file list. Source data must be a // java.util.List which contains java.io.File or String instances. @@ -1324,8 +1317,9 @@ final ArrayList fileList = castToFiles(list, userProtectionDomain); - bos = convertFileListToBytes(fileList); - + try (ByteArrayOutputStream bos = convertFileListToBytes(fileList)) { + theByteArray = bos.toByteArray(); + } // Target data is a URI list. Source data must be a // java.util.List which contains java.io.File or String instances. @@ -1360,57 +1354,72 @@ } byte[] eoln = "\r\n".getBytes(targetCharset); - for (int i = 0; i < uriList.size(); i++) { - byte[] bytes = uriList.get(i).getBytes(targetCharset); - bos.write(bytes, 0, bytes.length); - bos.write(eoln, 0, eoln.length); + + try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + for (int i = 0; i < uriList.size(); i++) { + byte[] bytes = uriList.get(i).getBytes(targetCharset); + bos.write(bytes, 0, bytes.length); + bos.write(eoln, 0, eoln.length); + } + theByteArray = bos.toByteArray(); } // Source data is an InputStream. For arbitrary flavors, just grab the // bytes and dump them into a byte array. For text flavors, decode back // to a String and recur to reencode according to the requested format. } else if (flavor.isRepresentationClassInputStream()) { - InputStream is = (InputStream)obj; - boolean eof = false; - int avail = is.available(); - byte[] tmp = new byte[avail > 8192 ? avail : 8192]; - do { - int ret; - if (!(eof = (ret = is.read(tmp, 0, tmp.length)) == -1)) { - bos.write(tmp, 0, ret); + try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + try (InputStream is = (InputStream)obj) { + boolean eof = false; + int avail = is.available(); + byte[] tmp = new byte[avail > 8192 ? avail : 8192]; + do { + int aValue; + if (!(eof = (aValue = is.read(tmp, 0, tmp.length)) == -1)) { + bos.write(tmp, 0, aValue); + } + } while (!eof); } - } while (!eof); - is.close(); - - if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) { - byte[] bytes = bos.toByteArray(); - bos.close(); - String sourceEncoding = DataTransferer.getTextCharset(flavor); - return translateTransferableString( - new String(bytes, sourceEncoding), - format); + + if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) { + byte[] bytes = bos.toByteArray(); + String sourceEncoding = DataTransferer.getTextCharset(flavor); + return translateTransferableString( + new String(bytes, sourceEncoding), + format); + } + theByteArray = bos.toByteArray(); } + + // Source data is an RMI object } else if (flavor.isRepresentationClassRemote()) { + Object mo = RMI.newMarshalledObject(obj); - ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(mo); - oos.close(); - - // Source data is Serializable + theByteArray = convertObjectToBytes(mo); + + // Source data is Serializable } else if (flavor.isRepresentationClassSerializable()) { - ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(obj); - oos.close(); + + theByteArray = convertObjectToBytes(obj); } else { throw new IOException("data translation failed"); } - byte[] ret = bos.toByteArray(); - bos.close(); - return ret; + + + return theByteArray; + } + + private static byte[] convertObjectToBytes(Object object) throws IOException { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos)) + { + oos.writeObject(object); + return bos.toByteArray(); + } } protected abstract ByteArrayOutputStream convertFileListToBytes(ArrayList fileList) throws IOException; @@ -1565,38 +1574,8 @@ long format, Transferable localeTransferable) throws IOException { - return translateBytesOrStream(null, bytes, flavor, format, - localeTransferable); - } - - public Object translateStream(InputStream str, DataFlavor flavor, - long format, Transferable localeTransferable) - throws IOException - { - return translateBytesOrStream(str, null, flavor, format, - localeTransferable); - } - - - /** - * Primary translation function for translating either a byte array or - * an InputStream into an Object, given a source format and a target - * DataFlavor. - * - * One of str/bytes is non-null; the other is null. - * The conversion from byte[] to InputStream is cheap, so do that - * immediately if necessary. The opposite conversion is expensive, - * so avoid it if possible. - */ - protected Object translateBytesOrStream(InputStream str, byte[] bytes, - DataFlavor flavor, long format, - Transferable localeTransferable) - throws IOException - { - - if (str == null) { - str = new ByteArrayInputStream(bytes); - } + + Object theObject = null; // Source data is a file list. Use the dragQueryFile native function to // do most of the decoding. Then wrap File objects around the String @@ -1605,12 +1584,8 @@ if (!DataFlavor.javaFileListFlavor.equals(flavor)) { throw new IOException("data translation failed"); } - if (bytes == null) { - bytes = inputStreamToByteArray(str); - } String[] filenames = dragQueryFile(bytes); if (filenames == null) { - str.close(); return null; } @@ -1619,178 +1594,203 @@ for (int i = 0; i < filenames.length; i++) { files[i] = new File(filenames[i]); } - str.close(); // Turn the list of Files into a List and return - return Arrays.asList(files); - - // Source data is a URI list. Convert to DataFlavor.javaFileListFlavor - // where possible. - } else if (isURIListFormat(format) && DataFlavor.javaFileListFlavor.equals(flavor)) { - try { - URI uris[] = dragQueryURIs(str, bytes, format, localeTransferable); - if (uris == null) { - return null; - } - ArrayList files = new ArrayList(); - for (URI uri : uris) { - try { - files.add(new File(uri)); - } catch (IllegalArgumentException illegalArg) { - // When converting from URIs to less generic files, - // common practice (Wine, SWT) seems to be to - // silently drop the URIs that aren't local files. - } - } - return files; - } finally { - str.close(); - } - - // Target data is a String. Strip terminating NUL bytes. Decode bytes - // into characters. Search-and-replace EOLN. + theObject = Arrays.asList(files); + + // Target data is a String. Strip terminating NUL bytes. Decode bytes + // into characters. Search-and-replace EOLN. } else if (String.class.equals(flavor.getRepresentationClass()) && - isFlavorCharsetTextType(flavor) && isTextFormat(format)) { - - return translateBytesOrStreamToString( - str, bytes, - format, localeTransferable); - - // Special hack to maintain backwards-compatibility with the brokenness - // of StringSelection. Return a StringReader instead of an InputStream. - // Recur to obtain String and encapsulate. - } else if (DataFlavor.plainTextFlavor.equals(flavor)) { - return new StringReader(translateBytesOrStreamToString( - str, bytes, - format, localeTransferable)); - - // Target data is an InputStream. For arbitrary flavors, just return - // the raw bytes. For text flavors, decode to strip terminators and - // search-and-replace EOLN, then reencode according to the requested - // flavor. - } else if (flavor.isRepresentationClassInputStream()) { - return translateBytesOrStreamToInputStream(str, flavor, format, - localeTransferable); - - // Target data is a Reader. Obtain data in InputStream format, encoded - // as "Unicode" (utf-16be). Then use an InputStreamReader to decode - // back to chars on demand. + isFlavorCharsetTextType(flavor) && isTextFormat(format)) { + + theObject = translateBytesToString(bytes, format, localeTransferable); + + // Target data is a Reader. Obtain data in InputStream format, encoded + // as "Unicode" (utf-16be). Then use an InputStreamReader to decode + // back to chars on demand. } else if (flavor.isRepresentationClassReader()) { - if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) { - throw new IOException - ("cannot transfer non-text data as Reader"); + try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) { + theObject = translateStream(bais, + flavor, format, localeTransferable); } - - InputStream is = (InputStream) - translateBytesOrStreamToInputStream - (str, DataFlavor.plainTextFlavor, format, - localeTransferable); - String unicode = - DataTransferer.getTextCharset(DataFlavor.plainTextFlavor); - Reader reader = new InputStreamReader(is, unicode); - - return constructFlavoredObject(reader, flavor, Reader.class); - - // Target data is a CharBuffer. Recur to obtain String and wrap. + // Target data is a CharBuffer. Recur to obtain String and wrap. } else if (flavor.isRepresentationClassCharBuffer()) { if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) { throw new IOException - ("cannot transfer non-text data as CharBuffer"); + ("cannot transfer non-text data as CharBuffer"); } - CharBuffer buffer = CharBuffer.wrap(translateBytesOrStreamToString( - str, bytes, - format, localeTransferable)); - - return constructFlavoredObject(buffer, flavor, CharBuffer.class); - - // Target data is a char array. Recur to obtain String and convert to - // char array. + CharBuffer buffer = CharBuffer.wrap( + translateBytesToString(bytes,format, localeTransferable)); + + theObject = constructFlavoredObject(buffer, flavor, CharBuffer.class); + + // Target data is a char array. Recur to obtain String and convert to + // char array. } else if (charArrayClass.equals(flavor.getRepresentationClass())) { if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) { throw new IOException - ("cannot transfer non-text data as char array"); + ("cannot transfer non-text data as char array"); } - return translateBytesOrStreamToString( - str, bytes, - format, localeTransferable).toCharArray(); - - // Target data is a ByteBuffer. For arbitrary flavors, just return - // the raw bytes. For text flavors, convert to a String to strip - // terminators and search-and-replace EOLN, then reencode according to - // the requested flavor. + theObject = translateBytesToString( + bytes, format, localeTransferable).toCharArray(); + + // Target data is a ByteBuffer. For arbitrary flavors, just return + // the raw bytes. For text flavors, convert to a String to strip + // terminators and search-and-replace EOLN, then reencode according to + // the requested flavor. } else if (flavor.isRepresentationClassByteBuffer()) { if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) { - bytes = translateBytesOrStreamToString( - str, bytes, - format, localeTransferable - ).getBytes( - DataTransferer.getTextCharset(flavor) - ); - } else { - if (bytes == null) { - bytes = inputStreamToByteArray(str); - } + bytes = translateBytesToString( + bytes, format, localeTransferable).getBytes( + DataTransferer.getTextCharset(flavor) + ); } ByteBuffer buffer = ByteBuffer.wrap(bytes); - return constructFlavoredObject(buffer, flavor, ByteBuffer.class); - - // Target data is a byte array. For arbitrary flavors, just return - // the raw bytes. For text flavors, convert to a String to strip - // terminators and search-and-replace EOLN, then reencode according to - // the requested flavor. + theObject = constructFlavoredObject(buffer, flavor, ByteBuffer.class); + + // Target data is a byte array. For arbitrary flavors, just return + // the raw bytes. For text flavors, convert to a String to strip + // terminators and search-and-replace EOLN, then reencode according to + // the requested flavor. } else if (byteArrayClass.equals(flavor.getRepresentationClass())) { if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) { - return translateBytesOrStreamToString( - str, bytes, - format, localeTransferable - ).getBytes( - DataTransferer.getTextCharset(flavor) - ); + theObject = translateBytesToString( + bytes, format, localeTransferable + ).getBytes(DataTransferer.getTextCharset(flavor)); } else { - return (bytes != null) ? bytes : inputStreamToByteArray(str); + theObject = bytes; } - // Target data is an RMI object - } else if (flavor.isRepresentationClassRemote()) { - try { - byte[] ba = inputStreamToByteArray(str); - ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(ba)); - Object ret = RMI.getMarshalledObject(ois.readObject()); - ois.close(); - str.close(); - return ret; - } catch (Exception e) { - throw new IOException(e.getMessage()); + // Target data is an InputStream. For arbitrary flavors, just return + // the raw bytes. For text flavors, decode to strip terminators and + // search-and-replace EOLN, then reencode according to the requested + // flavor. + } else if (flavor.isRepresentationClassInputStream()) { + + try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) { + theObject = translateStream(bais, flavor, format, localeTransferable); } - // Target data is Serializable + // Target data is Serializable } else if (flavor.isRepresentationClassSerializable()) { - try { - byte[] ba = inputStreamToByteArray(str); - ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(ba)); - Object ret = ois.readObject(); - ois.close(); - str.close(); - return ret; - } catch (Exception e) { - throw new IOException(e.getMessage()); + + try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) { + theObject = translateStream(bais, flavor, format, localeTransferable); } - // Target data is Image + // Target data is Image } else if (DataFlavor.imageFlavor.equals(flavor)) { if (!isImageFormat(format)) { throw new IOException("data translation failed"); } - Image image = platformImageBytesOrStreamToImage(str, bytes, format); - str.close(); - return image; + theObject = platformImageBytesToImage(bytes, format); + } + + if (theObject == null) { + throw new IOException("data translation failed"); } - throw new IOException("data translation failed"); + return theObject; + + } + + /** + * Primary translation function for translating + * an InputStream into an Object, given a source format and a target + * DataFlavor. + */ + public Object translateStream(InputStream str, DataFlavor flavor, + long format, Transferable localeTransferable) + throws IOException + { + + Object theObject = null; + // Source data is a URI list. Convert to DataFlavor.javaFileListFlavor + // where possible. + if (isURIListFormat(format) + && DataFlavor.javaFileListFlavor.equals(flavor)) + { + + URI uris[] = dragQueryURIs(str, format, localeTransferable); + if (uris == null) { + return null; + } + ArrayList files = new ArrayList(); + for (URI uri : uris) { + try { + files.add(new File(uri)); + } catch (IllegalArgumentException illegalArg) { + // When converting from URIs to less generic files, + // common practice (Wine, SWT) seems to be to + // silently drop the URIs that aren't local files. + } + } + theObject = files; + + // Special hack to maintain backwards-compatibility with the brokenness + // of StringSelection. Return a StringReader instead of an InputStream. + // Recur to obtain String and encapsulate. + } else if (DataFlavor.plainTextFlavor.equals(flavor)) { + theObject = new StringReader(translateBytesToString( + inputStreamToByteArray(str), + format, localeTransferable)); + + // Target data is an InputStream. For arbitrary flavors, just return + // the raw bytes. For text flavors, decode to strip terminators and + // search-and-replace EOLN, then reencode according to the requested + // flavor. + } else if (flavor.isRepresentationClassInputStream()) { + theObject = translateStreamToInputStream(str, flavor, format, + localeTransferable); + + // Target data is a Reader. Obtain data in InputStream format, encoded + // as "Unicode" (utf-16be). Then use an InputStreamReader to decode + // back to chars on demand. + } else if (flavor.isRepresentationClassReader()) { + if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) { + throw new IOException + ("cannot transfer non-text data as Reader"); + } + + InputStream is = (InputStream)translateStreamToInputStream( + str, DataFlavor.plainTextFlavor, + format, localeTransferable); + + String unicode = DataTransferer.getTextCharset(DataFlavor.plainTextFlavor); + + Reader reader = new InputStreamReader(is, unicode); + + theObject = constructFlavoredObject(reader, flavor, Reader.class); + + // Target data is an RMI object + } else if (flavor.isRepresentationClassRemote()) { + + try (ObjectInputStream ois = + new ObjectInputStream(str)) + { + theObject = RMI.getMarshalledObject(ois.readObject()); + }catch (Exception e) { + throw new IOException(e.getMessage()); + } + + // Target data is Serializable + } else if (flavor.isRepresentationClassSerializable()) { + try (ObjectInputStream ois = + new ObjectInputStream(str)) + { + theObject = ois.readObject(); + } catch (Exception e) { + throw new IOException(e.getMessage()); + } + } + + + return theObject; + } /** @@ -1798,7 +1798,7 @@ * ReencodingInputStream will decode and reencode the InputStream on demand * so that we can strip terminators and search-and-replace EOLN. */ - private Object translateBytesOrStreamToInputStream + private Object translateStreamToInputStream (InputStream str, DataFlavor flavor, long format, Transferable localeTransferable) throws IOException { @@ -2054,7 +2054,6 @@ * Decodes URIs from either a byte array or a stream. */ protected URI[] dragQueryURIs(InputStream stream, - byte[] bytes, long format, Transferable localeTransferable) throws IOException @@ -2067,10 +2066,10 @@ * Translates either a byte array or an input stream which contain * platform-specific image data in the given format into an Image. */ - protected abstract Image platformImageBytesOrStreamToImage(InputStream str, - byte[] bytes, - long format) - throws IOException; + + + protected abstract Image platformImageBytesToImage( + byte[] bytes,long format) throws IOException; /** * Translates either a byte array or an input stream which contain @@ -2078,13 +2077,9 @@ * * @param mimeType image MIME type, such as: image/png, image/jpeg, image/gif */ - protected Image standardImageBytesOrStreamToImage(InputStream inputStream, - byte[] bytes, - String mimeType) - throws IOException { - if (inputStream == null) { - inputStream = new ByteArrayInputStream(bytes); - } + protected Image standardImageBytesToImage( + byte[] bytes, String mimeType) throws IOException + { Iterator readerIterator = ImageIO.getImageReadersByMIMEType(mimeType); @@ -2097,9 +2092,9 @@ while (readerIterator.hasNext()) { ImageReader imageReader = (ImageReader)readerIterator.next(); - try { + try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) { ImageInputStream imageInputStream = - ImageIO.createImageInputStream(inputStream); + ImageIO.createImageInputStream(bais); try { ImageReadParam param = imageReader.getDefaultReadParam(); @@ -2456,15 +2451,16 @@ protected static byte[] inputStreamToByteArray(InputStream str) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int len = 0; - byte[] buf = new byte[8192]; - - while ((len = str.read(buf)) != -1) { - baos.write(buf, 0, len); + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + int len = 0; + byte[] buf = new byte[8192]; + + while ((len = str.read(buf)) != -1) { + baos.write(buf, 0, len); + } + + return baos.toByteArray(); } - - return baos.toByteArray(); } /** diff -r 7ded74ffea36 -r a954e407680c src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java --- a/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java Wed Apr 17 10:30:02 2013 -0700 @@ -275,7 +275,7 @@ * upcall from native code */ - private void dragEnter(final int targetActions, + protected void dragEnter(final int targetActions, final int modifiers, final int x, final int y) { postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_ENTER); @@ -353,10 +353,6 @@ public static void setDragDropInProgress(boolean b) throws InvalidDnDOperationException { - if (dragDropInProgress == b) { - throw new InvalidDnDOperationException(getExceptionMessage(b)); - } - synchronized (SunDragSourceContextPeer.class) { if (dragDropInProgress == b) { throw new InvalidDnDOperationException(getExceptionMessage(b)); diff -r 7ded74ffea36 -r a954e407680c src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java --- a/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java Wed Apr 17 10:30:02 2013 -0700 @@ -57,7 +57,6 @@ import sun.awt.SunToolkit; import sun.awt.datatransfer.DataTransferer; import sun.awt.datatransfer.ToolkitThreadBlockedHandler; -import sun.security.util.SecurityConstants; /** *

@@ -260,6 +259,7 @@ } final long format = lFormat.longValue(); + Object ret = getNativeData(format); if (ret instanceof byte[]) { @@ -270,11 +270,14 @@ throw new InvalidDnDOperationException(e.getMessage()); } } else if (ret instanceof InputStream) { + InputStream inputStream = (InputStream)ret; try { return DataTransferer.getInstance(). - translateStream((InputStream)ret, df, format, this); + translateStream(inputStream, df, format, this); } catch (IOException e) { throw new InvalidDnDOperationException(e.getMessage()); + } finally { + inputStream.close(); } } else { throw new IOException("no native data was transfered"); diff -r 7ded74ffea36 -r a954e407680c src/share/classes/sun/swing/JLightweightFrame.java --- a/src/share/classes/sun/swing/JLightweightFrame.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/share/classes/sun/swing/JLightweightFrame.java Wed Apr 17 10:30:02 2013 -0700 @@ -72,8 +72,10 @@ public JLightweightFrame() { super(); add(rootPane, BorderLayout.CENTER); - setBackground(new Color(0, 0, 0, 0)); setFocusTraversalPolicy(new LayoutFocusTraversalPolicy()); + if (getGraphicsConfiguration().isTranslucencyCapable()) { + setBackground(new Color(0, 0, 0, 0)); + } } /** diff -r 7ded74ffea36 -r a954e407680c src/solaris/classes/sun/awt/X11/XDataTransferer.java --- a/src/solaris/classes/sun/awt/X11/XDataTransferer.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/solaris/classes/sun/awt/X11/XDataTransferer.java Wed Apr 17 10:30:02 2013 -0700 @@ -212,10 +212,9 @@ * Translates either a byte array or an input stream which contain * platform-specific image data in the given format into an Image. */ - protected Image platformImageBytesOrStreamToImage(InputStream inputStream, - byte[] bytes, - long format) - throws IOException { + protected Image platformImageBytesToImage( + byte[] bytes, long format) throws IOException + { String mimeType = null; if (format == PNG_ATOM.getAtom()) { mimeType = "image/png"; @@ -235,7 +234,7 @@ } } if (mimeType != null) { - return standardImageBytesOrStreamToImage(inputStream, bytes, mimeType); + return standardImageBytesToImage(bytes, mimeType); } else { String nativeFormat = getNativeForFormat(format); throw new IOException("Translation from " + nativeFormat + @@ -330,8 +329,8 @@ * a valid MIME and return a list of flavors to which the data in this MIME * type can be translated by the Data Transfer subsystem. */ - public List getPlatformMappingsForNative(String nat) { - List flavors = new ArrayList(); + public List getPlatformMappingsForNative(String nat) { + List flavors = new ArrayList(); if (nat == null) { return flavors; @@ -346,16 +345,14 @@ return flavors; } - Object value = df; + DataFlavor value = df; final String primaryType = df.getPrimaryType(); final String baseType = primaryType + "/" + df.getSubType(); // For text formats we map natives to MIME strings instead of data // flavors to enable dynamic text native-to-flavor mapping generation. // See SystemFlavorMap.getFlavorsForNative() for details. - if ("text".equals(primaryType)) { - value = primaryType + "/" + df.getSubType(); - } else if ("image".equals(primaryType)) { + if ("image".equals(primaryType)) { Iterator readers = ImageIO.getImageReadersByMIMEType(baseType); if (readers.hasNext()) { flavors.add(DataFlavor.imageFlavor); @@ -438,16 +435,13 @@ } } } else if (DataTransferer.isFlavorCharsetTextType(df)) { - final Iterator iter = DataTransferer.standardEncodings(); - // stringFlavor is semantically equivalent to the standard // "text/plain" MIME type. if (DataFlavor.stringFlavor.equals(df)) { baseType = "text/plain"; } - while (iter.hasNext()) { - String encoding = (String)iter.next(); + for (String encoding : DataTransferer.standardEncodings()) { if (!encoding.equals(charset)) { natives.add(baseType + ";charset=" + encoding); } diff -r 7ded74ffea36 -r a954e407680c src/solaris/classes/sun/awt/X11/XFramePeer.java --- a/src/solaris/classes/sun/awt/X11/XFramePeer.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/solaris/classes/sun/awt/X11/XFramePeer.java Wed Apr 17 10:30:02 2013 -0700 @@ -642,5 +642,11 @@ return getBounds(); } - public void emulateActivation(boolean doActivate) {} + public void emulateActivation(boolean doActivate) { + if (doActivate) { + handleWindowFocusIn(0); + } else { + handleWindowFocusOut(null, 0); + } + } } diff -r 7ded74ffea36 -r a954e407680c src/solaris/classes/sun/awt/X11/XLightweightFramePeer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/solaris/classes/sun/awt/X11/XLightweightFramePeer.java Wed Apr 17 10:30:02 2013 -0700 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.awt.X11; + +import java.awt.Graphics; + +import sun.awt.LightweightFrame; + +public class XLightweightFramePeer extends XFramePeer { + + XLightweightFramePeer(LightweightFrame target) { + super(target); + } + + private LightweightFrame getLwTarget() { + return (LightweightFrame)target; + } + + @Override + public Graphics getGraphics() { + return getLwTarget().getGraphics(); + } + + @Override + public void xSetVisible(boolean visible) { + this.visible = visible; + } + + @Override + protected void requestXFocus(long time, boolean timeProvided) { + // not sending native focus events to the proxy + } + + @Override + public void setGrab(boolean grab) { + if (grab) { + getLwTarget().grabFocus(); + } else { + getLwTarget().ungrabFocus(); + } + } +} diff -r 7ded74ffea36 -r a954e407680c src/solaris/classes/sun/awt/X11/XToolkit.java --- a/src/solaris/classes/sun/awt/X11/XToolkit.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/solaris/classes/sun/awt/X11/XToolkit.java Wed Apr 17 10:30:02 2013 -0700 @@ -420,7 +420,9 @@ } public FramePeer createLightweightFrame(LightweightFrame target) { - return null; + FramePeer peer = new XLightweightFramePeer(target); + targetCreatedPeer(target, peer); + return peer; } public FramePeer createFrame(Frame target) { diff -r 7ded74ffea36 -r a954e407680c src/windows/classes/sun/awt/windows/WDataTransferer.java --- a/src/windows/classes/sun/awt/windows/WDataTransferer.java Wed Apr 17 16:11:19 2013 +0100 +++ b/src/windows/classes/sun/awt/windows/WDataTransferer.java Wed Apr 17 10:30:02 2013 -0700 @@ -87,35 +87,35 @@ */ public class WDataTransferer extends DataTransferer { private static final String[] predefinedClipboardNames = { - "", - "TEXT", - "BITMAP", - "METAFILEPICT", - "SYLK", - "DIF", - "TIFF", - "OEM TEXT", - "DIB", - "PALETTE", - "PENDATA", - "RIFF", - "WAVE", - "UNICODE TEXT", - "ENHMETAFILE", - "HDROP", - "LOCALE", - "DIBV5" + "", + "TEXT", + "BITMAP", + "METAFILEPICT", + "SYLK", + "DIF", + "TIFF", + "OEM TEXT", + "DIB", + "PALETTE", + "PENDATA", + "RIFF", + "WAVE", + "UNICODE TEXT", + "ENHMETAFILE", + "HDROP", + "LOCALE", + "DIBV5" }; private static final Map predefinedClipboardNameMap; static { Map tempMap = - new HashMap <> (predefinedClipboardNames.length, 1.0f); + new HashMap <> (predefinedClipboardNames.length, 1.0f); for (int i = 1; i < predefinedClipboardNames.length; i++) { tempMap.put(predefinedClipboardNames[i], Long.valueOf(i)); } predefinedClipboardNameMap = - Collections.synchronizedMap(tempMap); + Collections.synchronizedMap(tempMap); } /** @@ -138,18 +138,18 @@ //CF_FILECONTENTS supported as mandatory associated clipboard private static final Long L_CF_LOCALE = - predefinedClipboardNameMap.get(predefinedClipboardNames[CF_LOCALE]); + predefinedClipboardNameMap.get(predefinedClipboardNames[CF_LOCALE]); private static final DirectColorModel directColorModel = - new DirectColorModel(24, - 0x00FF0000, /* red mask */ - 0x0000FF00, /* green mask */ - 0x000000FF); /* blue mask */ + new DirectColorModel(24, + 0x00FF0000, /* red mask */ + 0x0000FF00, /* green mask */ + 0x000000FF); /* blue mask */ private static final int[] bandmasks = new int[] { - directColorModel.getRedMask(), - directColorModel.getGreenMask(), - directColorModel.getBlueMask() }; + directColorModel.getRedMask(), + directColorModel.getGreenMask(), + directColorModel.getBlueMask() }; /** * Singleton constructor @@ -171,10 +171,10 @@ } public SortedMap getFormatsForFlavors( - DataFlavor[] flavors, FlavorTable map) + DataFlavor[] flavors, FlavorTable map) { SortedMap retval = - super.getFormatsForFlavors(flavors, map); + super.getFormatsForFlavors(flavors, map); // The Win32 native code does not support exporting LOCALE data, nor // should it. @@ -191,32 +191,60 @@ DataFlavor flavor, long format) throws IOException { - byte[] bytes = super.translateTransferable(contents, flavor, format); - + byte[] bytes = null; if (format == CF_HTML) { - bytes = HTMLCodec.convertToHTMLFormat(bytes); + if (contents.isDataFlavorSupported(DataFlavor.selectionHtmlFlavor)) { + // if a user provides data represented by + // DataFlavor.selectionHtmlFlavor format, we use this + // type to store the data in the native clipboard + bytes = super.translateTransferable(contents, + DataFlavor.selectionHtmlFlavor, + format); + } else if (contents.isDataFlavorSupported(DataFlavor.allHtmlFlavor)) { + // if we cannot get data represented by the + // DataFlavor.selectionHtmlFlavor format + // but the DataFlavor.allHtmlFlavor format is avialable + // we belive that the user knows how to represent + // the data and how to mark up selection in a + // system specific manner. Therefor, we use this data + bytes = super.translateTransferable(contents, + DataFlavor.allHtmlFlavor, + format); + } else { + // handel other html flavor types, including custom and + // fragment ones + bytes = HTMLCodec.convertToHTMLFormat(bytes); + } + } else { + // we handle non-html types basing on their + // flavors + bytes = super.translateTransferable(contents, flavor, format); } return bytes; } - protected Object translateBytesOrStream(InputStream str, byte[] bytes, - DataFlavor flavor, long format, - Transferable localeTransferable) + // The stream is closed as a closable object + public Object translateStream(InputStream str, + DataFlavor flavor, long format, + Transferable localeTransferable) throws IOException { if (format == CF_HTML && flavor.isFlavorTextType()) { - if (str == null) { - str = new ByteArrayInputStream(bytes); - bytes = null; - } + str = new HTMLCodec(str, + EHTMLReadMode.getEHTMLReadMode(flavor)); + + } + return super.translateStream(str, flavor, format, + localeTransferable); - str = new HTMLCodec(str, EHTMLReadMode.HTML_READ_SELECTION); - } + } + + public Object translateBytes(byte[] bytes, DataFlavor flavor, long format, + Transferable localeTransferable) throws IOException + { + if (format == CF_FILEGROUPDESCRIPTORA || format == CF_FILEGROUPDESCRIPTORW) { - if (null != str ) { - str.close(); - } if (bytes == null || !DataFlavor.javaFileListFlavor.equals(flavor)) { throw new IOException("data translation failed"); } @@ -238,28 +266,24 @@ } if (format == CFSTR_INETURL && - URL.class.equals(flavor.getRepresentationClass())) + URL.class.equals(flavor.getRepresentationClass())) { - if (bytes == null) { - bytes = inputStreamToByteArray(str); - str = null; - } String charset = getDefaultTextCharset(); if (localeTransferable != null && localeTransferable. - isDataFlavorSupported(javaTextEncodingFlavor)) + isDataFlavorSupported(javaTextEncodingFlavor)) { try { charset = new String((byte[])localeTransferable. - getTransferData(javaTextEncodingFlavor), - "UTF-8"); + getTransferData(javaTextEncodingFlavor), "UTF-8"); } catch (UnsupportedFlavorException cannotHappen) { } } return new URL(new String(bytes, charset)); } - return super.translateBytesOrStream(str, bytes, flavor, format, - localeTransferable); + return super.translateBytes(bytes , flavor, format, + localeTransferable); + } public boolean isLocaleDependentTextFormat(long format) { @@ -280,18 +304,18 @@ protected String getNativeForFormat(long format) { return (format < predefinedClipboardNames.length) - ? predefinedClipboardNames[(int)format] - : getClipboardFormatName(format); + ? predefinedClipboardNames[(int)format] + : getClipboardFormatName(format); } private final ToolkitThreadBlockedHandler handler = - new WToolkitThreadBlockedHandler(); + new WToolkitThreadBlockedHandler(); public ToolkitThreadBlockedHandler getToolkitThreadBlockedHandler() { return handler; } - /** + /** * Calls the Win32 RegisterClipboardFormat function to register * a non-standard format. */ @@ -305,12 +329,12 @@ public boolean isImageFormat(long format) { return format == CF_DIB || format == CF_ENHMETAFILE || - format == CF_METAFILEPICT || format == CF_PNG || - format == CF_JFIF; + format == CF_METAFILEPICT || format == CF_PNG || + format == CF_JFIF; } protected byte[] imageToPlatformBytes(Image image, long format) - throws IOException { + throws IOException { String mimeType = null; if (format == CF_PNG) { mimeType = "image/png"; @@ -352,11 +376,11 @@ int[] nBits = {8, 8, 8}; int[] bOffs = {2, 1, 0}; ColorModel colorModel = - new ComponentColorModel(cs, nBits, false, false, - Transparency.OPAQUE, DataBuffer.TYPE_BYTE); + new ComponentColorModel(cs, nBits, false, false, + Transparency.OPAQUE, DataBuffer.TYPE_BYTE); WritableRaster raster = - Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, - width * 3 + pad, 3, bOffs, null); + Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, + width * 3 + pad, 3, bOffs, null); BufferedImage bimage = new BufferedImage(colorModel, raster, false, null); @@ -364,7 +388,7 @@ // top-down DIBs. // So we flip the image vertically and create a bottom-up DIB. AffineTransform imageFlipTransform = - new AffineTransform(1, 0, 0, -1, 0, height); + new AffineTransform(1, 0, 0, -1, 0, height); Graphics2D g2d = bimage.createGraphics(); @@ -383,7 +407,7 @@ private static final byte [] UNICODE_NULL_TERMINATOR = new byte [] {0,0}; protected ByteArrayOutputStream convertFileListToBytes(ArrayList fileList) - throws IOException + throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); @@ -407,10 +431,10 @@ return bos; } - /** - * Returns a byte array which contains data special for the given format - * and for the given image data. - */ + /** + * Returns a byte array which contains data special for the given format + * and for the given image data. + */ private native byte[] imageDataToPlatformImageBytes(byte[] imageData, int width, int height, long format); @@ -419,10 +443,8 @@ * Translates either a byte array or an input stream which contain * platform-specific image data in the given format into an Image. */ - protected Image platformImageBytesOrStreamToImage(InputStream str, - byte[] bytes, - long format) - throws IOException { + protected Image platformImageBytesToImage(byte[] bytes, long format) + throws IOException { String mimeType = null; if (format == CF_PNG) { mimeType = "image/png"; @@ -430,11 +452,7 @@ mimeType = "image/jpeg"; } if (mimeType != null) { - return standardImageBytesOrStreamToImage(str, bytes, mimeType); - } - - if (bytes == null) { - bytes = inputStreamToByteArray(str); + return standardImageBytesToImage(bytes, mimeType); } int[] imageData = platformImageBytesToImageData(bytes, format); @@ -448,8 +466,8 @@ DataBufferInt buffer = new DataBufferInt(imageData, len); WritableRaster raster = Raster.createPackedRaster(buffer, width, - height, width, - bandmasks, null); + height, width, + bandmasks, null); return new BufferedImage(directColorModel, raster, false, null); } @@ -462,13 +480,13 @@ */ private native int[] platformImageBytesToImageData(byte[] bytes, long format) - throws IOException; + throws IOException; protected native String[] dragQueryFile(byte[] bytes); } final class WToolkitThreadBlockedHandler extends Mutex - implements ToolkitThreadBlockedHandler { + implements ToolkitThreadBlockedHandler { public void enter() { if (!isOwned()) { @@ -492,7 +510,22 @@ enum EHTMLReadMode { HTML_READ_ALL, HTML_READ_FRAGMENT, - HTML_READ_SELECTION + HTML_READ_SELECTION; + + public static EHTMLReadMode getEHTMLReadMode (DataFlavor df) { + + EHTMLReadMode mode = HTML_READ_SELECTION; + + String parameter = df.getParameter("document"); + + if ("all".equals(parameter)) { + mode = HTML_READ_ALL; + } else if ("fragment".equals(parameter)) { + mode = HTML_READ_FRAGMENT; + } + + return mode; + } } /** @@ -581,26 +614,24 @@ htmlSuffix = "" + htmlSuffix; }; }; - htmlPrefix = htmlPrefix + START_FRAGMENT_CMT; - htmlSuffix = END_FRAGMENT_CMT + htmlSuffix; } String stBaseUrl = DEF_SOURCE_URL; int nStartHTML = - VERSION.length() + VERSION_NUM.length() + EOLN.length() - + START_HTML.length() + PADDED_WIDTH + EOLN.length() - + END_HTML.length() + PADDED_WIDTH + EOLN.length() - + START_FRAGMENT.length() + PADDED_WIDTH + EOLN.length() - + END_FRAGMENT.length() + PADDED_WIDTH + EOLN.length() - + SOURCE_URL.length() + stBaseUrl.length() + EOLN.length() - ; + VERSION.length() + VERSION_NUM.length() + EOLN.length() + + START_HTML.length() + PADDED_WIDTH + EOLN.length() + + END_HTML.length() + PADDED_WIDTH + EOLN.length() + + START_FRAGMENT.length() + PADDED_WIDTH + EOLN.length() + + END_FRAGMENT.length() + PADDED_WIDTH + EOLN.length() + + SOURCE_URL.length() + stBaseUrl.length() + EOLN.length() + ; int nStartFragment = nStartHTML + htmlPrefix.length(); int nEndFragment = nStartFragment + bytes.length - 1; int nEndHTML = nEndFragment + htmlSuffix.length(); StringBuilder header = new StringBuilder( - nStartFragment - + START_FRAGMENT_CMT.length() + nStartFragment + + START_FRAGMENT_CMT.length() ); //header header.append(VERSION); @@ -639,14 +670,14 @@ } byte[] retval = new byte[headerBytes.length + bytes.length + - trailerBytes.length]; + trailerBytes.length]; System.arraycopy(headerBytes, 0, retval, 0, headerBytes.length); System.arraycopy(bytes, 0, retval, headerBytes.length, - bytes.length - 1); + bytes.length - 1); System.arraycopy(trailerBytes, 0, retval, - headerBytes.length + bytes.length - 1, - trailerBytes.length); + headerBytes.length + bytes.length - 1, + trailerBytes.length); retval[retval.length-1] = 0; return retval; @@ -659,7 +690,7 @@ private boolean descriptionParsed = false; private boolean closed = false; - // InputStreamReader uses an 8K buffer. The size is not customizable. + // InputStreamReader uses an 8K buffer. The size is not customizable. public static final int BYTE_BUFFER_LEN = 8192; // CharToByteUTF8.getMaxBytesPerChar returns 3, so we should not buffer @@ -667,30 +698,30 @@ public static final int CHAR_BUFFER_LEN = BYTE_BUFFER_LEN / 3; private static final String FAILURE_MSG = - "Unable to parse HTML description: "; + "Unable to parse HTML description: "; private static final String INVALID_MSG = - " invalid"; + " invalid"; //HTML header mapping: private long iHTMLStart,// StartHTML -- shift in array to the first byte after the header - iHTMLEnd, // EndHTML -- shift in array of last byte for HTML syntax analysis - iFragStart,// StartFragment -- shift in array jast after - iFragEnd, // EndFragment -- shift in array before start - iSelStart, // StartSelection -- shift in array of the first char in copied selection - iSelEnd; // EndSelection -- shift in array of the last char in copied selection + iHTMLEnd, // EndHTML -- shift in array of last byte for HTML syntax analysis + iFragStart,// StartFragment -- shift in array jast after + iFragEnd, // EndFragment -- shift in array before start + iSelStart, // StartSelection -- shift in array of the first char in copied selection + iSelEnd; // EndSelection -- shift in array of the last char in copied selection private String stBaseURL; // SourceURL -- base URL for related referenses private String stVersion; // Version -- current supported version //Stream reader markers: private long iStartOffset, - iEndOffset, - iReadCount; + iEndOffset, + iReadCount; private EHTMLReadMode readMode; public HTMLCodec( - InputStream _bytestream, - EHTMLReadMode _readMode) throws IOException + InputStream _bytestream, + EHTMLReadMode _readMode) throws IOException { bufferedStream = new BufferedInputStream(_bytestream, BYTE_BUFFER_LEN); readMode = _readMode; @@ -723,31 +754,31 @@ // initialization of array offset pointers // to the same "uninitialized" state. iHTMLEnd = - iHTMLStart = - iFragEnd = - iFragStart = - iSelEnd = - iSelStart = -1; + iHTMLStart = + iFragEnd = + iFragStart = + iSelEnd = + iSelStart = -1; bufferedStream.mark(BYTE_BUFFER_LEN); String astEntries[] = new String[] { - //common - VERSION, - START_HTML, - END_HTML, - START_FRAGMENT, - END_FRAGMENT, - //ver 1.0 - START_SELECTION, - END_SELECTION, - SOURCE_URL + //common + VERSION, + START_HTML, + END_HTML, + START_FRAGMENT, + END_FRAGMENT, + //ver 1.0 + START_SELECTION, + END_SELECTION, + SOURCE_URL }; BufferedReader bufferedReader = new BufferedReader( - new InputStreamReader( - bufferedStream, - ENCODING - ), - CHAR_BUFFER_LEN + new InputStreamReader( + bufferedStream, + ENCODING + ), + CHAR_BUFFER_LEN ); long iHeadSize = 0; long iCRSize = EOLN.length(); @@ -769,30 +800,30 @@ if( null!=stValue ) { try{ switch( iEntry ){ - case 0: - stVersion = stValue; - break; - case 1: - iHTMLStart = Integer.parseInt(stValue); - break; - case 2: - iHTMLEnd = Integer.parseInt(stValue); - break; - case 3: - iFragStart = Integer.parseInt(stValue); - break; - case 4: - iFragEnd = Integer.parseInt(stValue); - break; - case 5: - iSelStart = Integer.parseInt(stValue); - break; - case 6: - iSelEnd = Integer.parseInt(stValue); - break; - case 7: - stBaseURL = stValue; - break; + case 0: + stVersion = stValue; + break; + case 1: + iHTMLStart = Integer.parseInt(stValue); + break; + case 2: + iHTMLEnd = Integer.parseInt(stValue); + break; + case 3: + iFragStart = Integer.parseInt(stValue); + break; + case 4: + iFragEnd = Integer.parseInt(stValue); + break; + case 5: + iSelStart = Integer.parseInt(stValue); + break; + case 6: + iSelEnd = Integer.parseInt(stValue); + break; + case 7: + stBaseURL = stValue; + break; }; } catch ( NumberFormatException e ) { throw new IOException(FAILURE_MSG + astEntries[iEntry]+ " value " + e + INVALID_MSG); @@ -816,19 +847,19 @@ //one of possible modes switch( readMode ){ - case HTML_READ_ALL: - iStartOffset = iHTMLStart; - iEndOffset = iHTMLEnd; - break; - case HTML_READ_FRAGMENT: - iStartOffset = iFragStart; - iEndOffset = iFragEnd; - break; - case HTML_READ_SELECTION: - default: - iStartOffset = iSelStart; - iEndOffset = iSelEnd; - break; + case HTML_READ_ALL: + iStartOffset = iHTMLStart; + iEndOffset = iHTMLEnd; + break; + case HTML_READ_FRAGMENT: + iStartOffset = iFragStart; + iEndOffset = iFragEnd; + break; + case HTML_READ_SELECTION: + default: + iStartOffset = iSelStart; + iEndOffset = iSelEnd; + break; } bufferedStream.reset(); diff -r 7ded74ffea36 -r a954e407680c test/java/awt/datatransfer/HTMLDataFlavors/HTMLDataFlavorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/datatransfer/HTMLDataFlavors/HTMLDataFlavorTest.java Wed Apr 17 10:30:02 2013 -0700 @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. + * + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 7075105 + @summary WIN: Provide a way to format HTML on drop + @author Denis Fokin: area=datatransfer + @build HtmlTransferable PutAllHtmlFlavorsOnClipboard + @build PutOnlyAllHtmlFlavorOnClipboard PutSelectionAndFragmentHtmlFlavorsOnClipboard + @run main HTMLDataFlavorTest +*/ + +import java.awt.*; +import java.awt.datatransfer.*; +import java.io.*; +import java.util.HashMap; + +public class HTMLDataFlavorTest { + + private static HashMap dataFlavors = new HashMap(); + + + public static void main(String[] args) throws IOException, UnsupportedFlavorException { + + dataFlavors.put(DataFlavor.allHtmlFlavor, HtmlTransferable.ALL_HTML_AS_STRING); + dataFlavors.put(DataFlavor.fragmentHtmlFlavor, HtmlTransferable.FRAGMENT_HTML_AS_STRING); + dataFlavors.put(DataFlavor.selectionHtmlFlavor, HtmlTransferable.SELECTION_HTML_AS_STRING); + + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + resetClipboardContent(clipboard); + + // 1. Put all three html flavors on clipboard. + // Get the data within the same JVM + // Expect that the resulted html is the selection + // wrapped in all three types + + clipboard.setContents(new HtmlTransferable(HtmlTransferable.htmlDataFlavors),null); + + // Test local transfer + testClipboardContent(clipboard, HtmlTransferable.htmlDataFlavors); + + resetClipboardContent(clipboard); + + // 2. Put only DataFlavor.allHtmlFlavor on clipboard. + // Expect that the resulted html is the all + // wrapped in all three types + + putHtmlInAnotherProcess("PutOnlyAllHtmlFlavorOnClipboard"); + + for (DataFlavor df : HtmlTransferable.htmlDataFlavors) { + if (!clipboard.isDataFlavorAvailable(df)) { + throw new RuntimeException("The data should be available."); + } + } + + if (!clipboard.getData(DataFlavor.allHtmlFlavor).toString(). + equals(dataFlavors.get(DataFlavor.allHtmlFlavor).toString())) + { + throw new RuntimeException("DataFlavor.allHtmlFlavor data " + + "should be identical to the data put on the source side."); + } + + resetClipboardContent(clipboard); + + // 3. Put all three html flavors on clipboard. + // Expect that the resulted html is the selection + // wrapped in all three types + + putHtmlInAnotherProcess("PutAllHtmlFlavorsOnClipboard"); + + for (DataFlavor df : HtmlTransferable.htmlDataFlavors) { + if (!clipboard.isDataFlavorAvailable(df)) { + throw new RuntimeException("The data should be available."); + } + } + + if (!clipboard.getData(DataFlavor.selectionHtmlFlavor).toString(). + equals(dataFlavors.get(DataFlavor.selectionHtmlFlavor))) + { + throw new RuntimeException("DataFlavor.allHtmlFlavor data " + + "should be identical to the data put on the source side."); + } + + } + + private static void resetClipboardContent(Clipboard clipboard) { + clipboard.setContents( + new StringSelection("The data is used to empty the clipboard content" + ),null); + } + + + private static void putHtmlInAnotherProcess(String putterCommand) { + try { + + String command = System.getProperty("java.home") + "/bin/java -cp " + + System.getProperty("test.classes", ".") + " " + + putterCommand; + + System.out.println("Execute process : " + command); + + Process p = Runtime.getRuntime().exec(command); + + try { + p.waitFor(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + System.out.println("The data has been set remotely"); + + try (BufferedReader stdstr = new BufferedReader(new InputStreamReader(p.getInputStream()))) { + String s; + while ((s = stdstr.readLine()) != null) { + s = stdstr.readLine(); + System.out.println(s); + } + } + + try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()))) { + String s; + while ((s = br.readLine()) != null) { + s = br.readLine(); + System.err.println(s); + } + } + + + + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void testClipboardContent(Clipboard clipboard, + DataFlavor [] expectedDataFlavors) + throws UnsupportedFlavorException, IOException { + + for (DataFlavor df : clipboard.getAvailableDataFlavors()) { + System.out.println("available df: " + df.getMimeType()); + } + + for (DataFlavor df : expectedDataFlavors) { + + if (!clipboard.isDataFlavorAvailable(df)) { + throw new RuntimeException("The data should be available."); + } + + + System.out.println("Checking \"" + df.getParameter("document") + "\" for correspondence"); + + if (!dataFlavors.get(df).toString().equals(clipboard.getData(df).toString())) { + + System.err.println("Expected data: " + dataFlavors.get(df).toString()); + System.err.println("Actual data: " + clipboard.getData(df).toString()); + + + throw new RuntimeException("An html flavor with parameter \"" + + df.getParameter("document") + "\" does not correspond to the transferred data."); + + + } + } + } + + +} diff -r 7ded74ffea36 -r a954e407680c test/java/awt/datatransfer/HTMLDataFlavors/HtmlTransferable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/datatransfer/HTMLDataFlavors/HtmlTransferable.java Wed Apr 17 10:30:02 2013 -0700 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. + * + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; + +/** + * A transferable that mimic ie html data + */ +class HtmlTransferable implements Transferable { + + final static String SOURCE_HTML = "Simple html content" + + "

  1. Dasha
  2. Masha
  3. Lida
"; + + // Data identical to ie output for the next html without end of lines, + // that is gotten by java system clipboard + // + // + // Simple html content + // + // + //
    + //
  1. Dasha
  2. + //
  3. Masha
  4. + //
  5. Lida
  6. + //
+ // + // + + final static String ALL_HTML_AS_STRING = "\n" + + "\n" + + "Simple html content\n" + + "\n" + + "\n" + + "\n" + + "
  1. Masha\n" + + "
  2. Lida
\n" + + "\n" + + ""; + + final static String FRAGMENT_HTML_AS_STRING = "
  • Masha\n" + + "
  • Lida
  • "; + + final static String SELECTION_HTML_AS_STRING = "
  • Masha" + + "
  • Lida
  • "; + + private DataFlavor[] supportedDataFlavors; + + final static DataFlavor[] htmlDataFlavors = new DataFlavor [] { + DataFlavor.allHtmlFlavor, + DataFlavor.fragmentHtmlFlavor, + DataFlavor.selectionHtmlFlavor + }; + + @Override + public DataFlavor[] getTransferDataFlavors() { + return supportedDataFlavors; + } + + @Override + public boolean isDataFlavorSupported(DataFlavor flavor) { + for (DataFlavor supportedDataFlavor : supportedDataFlavors) { + if (supportedDataFlavor.equals(flavor)) { + return true; + } + } + return false; + } + + HtmlTransferable(DataFlavor[] supportedDataFlavors) { + this.supportedDataFlavors = supportedDataFlavors; + } + + @Override + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, IOException { + + if (isDataFlavorSupported(flavor)) { + if (flavor.equals(DataFlavor.allHtmlFlavor)) { + return ALL_HTML_AS_STRING; + } else if (flavor.equals(DataFlavor.fragmentHtmlFlavor)) { + return FRAGMENT_HTML_AS_STRING; + } else if (flavor.equals(DataFlavor.selectionHtmlFlavor)) { + return SELECTION_HTML_AS_STRING; + } + } + + throw new UnsupportedFlavorException(flavor); + } + +} diff -r 7ded74ffea36 -r a954e407680c test/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.html Wed Apr 17 10:30:02 2013 -0700 @@ -0,0 +1,20 @@ + + + +ManualHTMLDataFlavorTest + + + +

    ManualHTMLDataFlavorTest
    Bug ID: 7075105

    + +

    See the dialog box (usually in upper left corner) for instructions

    + + + + diff -r 7ded74ffea36 -r a954e407680c test/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.java Wed Apr 17 10:30:02 2013 -0700 @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. + * + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + test + @bug 7075105 + @summary WIN: Provide a way to format HTML on drop + @author Denis Fokin: area=datatransfer + @run applet/manual=yesno ManualHTMLDataFlavorTest +*/ + +import java.applet.Applet; +import java.awt.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.*; +import java.io.IOException; + +public class ManualHTMLDataFlavorTest extends Applet { + + class DropPane extends Panel implements DropTargetListener { + + DropPane() { + requestFocus(); + setBackground(Color.red); + setDropTarget(new DropTarget(this, DnDConstants.ACTION_COPY, this)); + } + + @Override + public Dimension getPreferredSize() { + return new Dimension(200,200); + } + + @Override + public void dragEnter(DropTargetDragEvent dtde) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + + @Override + public void dragOver(DropTargetDragEvent dtde) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + + @Override + public void dropActionChanged(DropTargetDragEvent dtde) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + + @Override + public void dragExit(DropTargetEvent dte) {} + + @Override + public void drop(DropTargetDropEvent dtde) { + if (!dtde.isDataFlavorSupported(DataFlavor.allHtmlFlavor)) { + Sysout.println("DataFlavor.allHtmlFlavor is not present in the system clipboard"); + dtde.rejectDrop(); + return; + } else if (!dtde.isDataFlavorSupported(DataFlavor.fragmentHtmlFlavor)) { + Sysout.println("DataFlavor.fragmentHtmlFlavor is not present in the system clipboard"); + dtde.rejectDrop(); + return; + } else if (!dtde.isDataFlavorSupported(DataFlavor.selectionHtmlFlavor)) { + Sysout.println("DataFlavor.selectionHtmlFlavor is not present in the system clipboard"); + dtde.rejectDrop(); + return; + } + + dtde.acceptDrop(DnDConstants.ACTION_COPY); + + Transferable t = dtde.getTransferable(); + try { + Sysout.println("ALL:"); + Sysout.println(t.getTransferData(DataFlavor.allHtmlFlavor).toString()); + Sysout.println("FRAGMENT:"); + Sysout.println(t.getTransferData(DataFlavor.fragmentHtmlFlavor).toString()); + Sysout.println("SELECTION:"); + Sysout.println(t.getTransferData(DataFlavor.selectionHtmlFlavor).toString()); + } catch (UnsupportedFlavorException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + } + + public void init() { + + String[] instructions = + { + "1) The test contains a drop-aware panel with a red background", + "2) Open some page in a browser, select some text", + " Drag and drop it on the red panel", + " IMPORTANT NOTE: the page should be stored locally.", + " otherwise for instance iexplore can prohibit drag and drop from", + " the browser to other applications because of", + " the protected mode restrictions.", + "3) Check the data in the output area of this dialog", + "5) The output should not contain information that any of", + " flavors is not present in the system clipboard", + "6) The output should contain data in three different formats", + " provided by the system clipboard", + " - Data after the \"ALL:\" marker should include the data", + " from the the \"SELECTION:\" marker", + " - Data after the \"FRAGMENT\" marker should include the data", + " from the \"SELECTION:\" marker and may be some closing", + " tags could be added to the mark-up", + " - Data after the \"SELECTION:\" marker should correspond", + " to the data selected in the browser", + "7) If the above requirements are met, the test is passed" + }; + + add(new DropPane()); + Sysout.createDialogWithInstructions( instructions ); + + new ManualHTMLDataFlavorTest(); + } + + public void start () + { + setSize (200,200); + setVisible(true); + validate(); + + }// start() + +} + + +/* Place other classes related to the test after this line */ + + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } + +}// TestDialog class diff -r 7ded74ffea36 -r a954e407680c test/java/awt/datatransfer/HTMLDataFlavors/PutAllHtmlFlavorsOnClipboard.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/datatransfer/HTMLDataFlavors/PutAllHtmlFlavorsOnClipboard.java Wed Apr 17 10:30:02 2013 -0700 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. + * + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.awt.*; + +public class PutAllHtmlFlavorsOnClipboard { + public static void main(String[] args) { + System.out.println("PutAllHtmlFlavorsOnClipboard has been started."); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents( + new HtmlTransferable(HtmlTransferable.htmlDataFlavors), null); + System.out.println("Data has been put on clipboard in a separate process"); + } +} diff -r 7ded74ffea36 -r a954e407680c test/java/awt/datatransfer/HTMLDataFlavors/PutOnlyAllHtmlFlavorOnClipboard.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/datatransfer/HTMLDataFlavors/PutOnlyAllHtmlFlavorOnClipboard.java Wed Apr 17 10:30:02 2013 -0700 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. + * + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.awt.*; +import java.awt.datatransfer.DataFlavor; + +public class PutOnlyAllHtmlFlavorOnClipboard { + public static void main(String[] args) { + System.out.println("PutOnlyAllHtmlFlavorOnClipboard has been started."); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents( + new HtmlTransferable(new DataFlavor[]{DataFlavor.allHtmlFlavor}), null); + System.out.println("Data has been put on clipboard in a separate process"); + } +} diff -r 7ded74ffea36 -r a954e407680c test/java/awt/datatransfer/HTMLDataFlavors/PutSelectionAndFragmentHtmlFlavorsOnClipboard.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/datatransfer/HTMLDataFlavors/PutSelectionAndFragmentHtmlFlavorsOnClipboard.java Wed Apr 17 10:30:02 2013 -0700 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. + * + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.awt.*; +import java.awt.datatransfer.DataFlavor; + +public class PutSelectionAndFragmentHtmlFlavorsOnClipboard { + public static void main(String[] args) { + Toolkit.getDefaultToolkit().getSystemClipboard().setContents( + new HtmlTransferable(new DataFlavor[]{DataFlavor.selectionHtmlFlavor, + DataFlavor.fragmentHtmlFlavor}), null); + } +} diff -r 7ded74ffea36 -r a954e407680c test/java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java Wed Apr 17 10:30:02 2013 -0700 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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. + * + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test @summary JVM crash if the frame is disposed in DropTargetListener + * @author Petr Pchelko + * @library ../../regtesthelpers + * @build Util + * @compile DisposeFrameOnDragTest.java + * @run main/othervm DisposeFrameOnDragTest + */ +import java.awt.AWTException; +import java.awt.Point; +import java.awt.Robot; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.TooManyListenersException; +import javax.swing.JFrame; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import test.java.awt.regtesthelpers.Util; + +public class DisposeFrameOnDragTest { + + private static JTextArea textArea; + + public static void main(String[] args) throws Throwable { + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + constructTestUI(); + } + }); + + Util.waitForIdle(null); + try { + Point loc = textArea.getLocationOnScreen(); + Util.drag(new Robot(), + new Point((int) loc.x + 3, (int) loc.y + 3), + new Point((int) loc.x + 40, (int) loc.y + 40), + InputEvent.BUTTON1_MASK); + } catch (AWTException ex) { + throw new RuntimeException("Could not initiate a drag operation"); + } + Util.waitForIdle(null); + } + + private static void constructTestUI() { + final JFrame frame = new JFrame("Test frame"); + textArea = new JTextArea("Drag Me!"); + try { + textArea.getDropTarget().addDropTargetListener(new DropTargetAdapter() { + @Override + public void drop(DropTargetDropEvent dtde) { + //IGNORE + } + + @Override + public void dragOver(DropTargetDragEvent dtde) { + frame.dispose(); + } + }); + } catch (TooManyListenersException ex) { + throw new RuntimeException(ex); + } + textArea.setSize(100, 100); + textArea.setDragEnabled(true); + textArea.select(0, textArea.getText().length()); + frame.add(textArea); + frame.setBounds(100, 100, 100, 100); + frame.setVisible(true); + } +} diff -r 7ded74ffea36 -r a954e407680c test/javax/swing/JPopupMenu/6827786/bug6827786.java --- a/test/javax/swing/JPopupMenu/6827786/bug6827786.java Wed Apr 17 16:11:19 2013 +0100 +++ b/test/javax/swing/JPopupMenu/6827786/bug6827786.java Wed Apr 17 10:30:02 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2013, Oracle and/or its affiliates. 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 @@ -65,7 +65,11 @@ checkfocus(); // select menu - Util.hitKeys(robot, KeyEvent.VK_ALT, KeyEvent.VK_F); + if (sun.awt.OSInfo.getOSType() == sun.awt.OSInfo.OSType.MACOSX) { + Util.hitKeys(robot, KeyEvent.VK_CONTROL, KeyEvent.VK_ALT, KeyEvent.VK_F); + } else { + Util.hitKeys(robot, KeyEvent.VK_ALT, KeyEvent.VK_F); + } // select submenu Util.hitKeys(robot, KeyEvent.VK_S); toolkit.realSync();