--- old/src/macosx/native/sun/awt/CClipboard.m 2014-03-18 12:10:24.000000000 +0400 +++ new/src/macosx/native/sun/awt/CClipboard.m 2014-03-18 12:10:24.000000000 +0400 @@ -23,70 +23,28 @@ * questions. */ -#import "CClipboard.h" #import "CDataTransferer.h" #import "ThreadUtilities.h" #import "jni_util.h" #import #import -static CClipboard *sClipboard = nil; - -// -// CClipboardUpdate is used for mulitple calls to setData that happen before -// the model and AppKit can get back in sync. -// - -@interface CClipboardUpdate : NSObject { - NSData *fData; - NSString *fFormat; -} - -- (id)initWithData:(NSData *)inData withFormat:(NSString *)inFormat; -- (NSData *)data; -- (NSString *)format; - -@end - -@implementation CClipboardUpdate - -- (id)initWithData:(NSData *)inData withFormat:(NSString *)inFormat -{ - self = [super init]; - - if (self != nil) { - fData = [inData retain]; - fFormat = [inFormat retain]; - } - - return self; -} - -- (void)dealloc -{ - [fData release]; - fData = nil; - - [fFormat release]; - fFormat = nil; - - [super dealloc]; -} - -- (NSData *)data { - return fData; -} - -- (NSString *)format { - return fFormat; -} +@interface CClipboard : NSObject { } +@property NSInteger changeCount; +@property jobject clipboardOwner; + ++ (CClipboard*)sharedClipboard; +- (void)declareTypes:(NSArray *)types withOwner:(jobject)owner jniEnv:(JNIEnv*)env; +- (void)checkPasteboard:(id)sender; @end @implementation CClipboard +@synthesize changeCount = _changeCount; +@synthesize clipboardOwner = _clipboardOwner; -// Clipboard creation is synchronized at the Java level. -+ (CClipboard *) sharedClipboard -{ +// Clipboard creation is synchronized at the Java level ++ (CClipboard*)sharedClipboard { + static CClipboard* sClipboard = nil; if (sClipboard == nil) { sClipboard = [[CClipboard alloc] init]; [[NSNotificationCenter defaultCenter] addObserver:sClipboard selector: @selector(checkPasteboard:) @@ -97,90 +55,33 @@ return sClipboard; } -- (id) init -{ - self = [super init]; - - if (self != nil) { - fChangeCount = [[NSPasteboard generalPasteboard] changeCount]; +- (id)init { + if (self = [super init]) { + self.changeCount = [[NSPasteboard generalPasteboard] changeCount]; } - return self; } -- (void) javaDeclareTypes:(NSArray *)inTypes withOwner:(jobject)inClipboard jniEnv:(JNIEnv *)inEnv { - +- (void)declareTypes:(NSArray*)types withOwner:(jobject)owner jniEnv:(JNIEnv*)env { @synchronized(self) { - if (inClipboard != NULL) { - if (fClipboardOwner != NULL) { - JNFDeleteGlobalRef(inEnv, fClipboardOwner); + if (owner != NULL) { + if (self.clipboardOwner != NULL) { + JNFDeleteGlobalRef(env, self.clipboardOwner); } - fClipboardOwner = JNFNewGlobalRef(inEnv, inClipboard); + self.clipboardOwner = JNFNewGlobalRef(env, owner); } } - [ThreadUtilities performOnMainThread:@selector(_nativeDeclareTypes:) on:self withObject:inTypes waitUntilDone:YES]; -} - -- (void) _nativeDeclareTypes:(NSArray *)inTypes { - AWT_ASSERT_APPKIT_THREAD; - - fChangeCount = [[NSPasteboard generalPasteboard] declareTypes:inTypes owner:self]; -} - - -- (NSArray *) javaGetTypes { - - NSMutableArray *args = [NSMutableArray arrayWithCapacity:1]; - [ThreadUtilities performOnMainThread:@selector(_nativeGetTypes:) on:self withObject:args waitUntilDone:YES]; - return [args lastObject]; -} - -- (void) _nativeGetTypes:(NSMutableArray *)args { - AWT_ASSERT_APPKIT_THREAD; - - [args addObject:[[NSPasteboard generalPasteboard] types]]; -} - -- (void) javaSetData:(NSData *)inData forType:(NSString *) inFormat { - - CClipboardUpdate *newUpdate = [[CClipboardUpdate alloc] initWithData:inData withFormat:inFormat]; - [ThreadUtilities performOnMainThread:@selector(_nativeSetData:) on:self withObject:newUpdate waitUntilDone:YES]; - [newUpdate release]; -} - -- (void) _nativeSetData:(CClipboardUpdate *)newUpdate { - AWT_ASSERT_APPKIT_THREAD; - - [[NSPasteboard generalPasteboard] setData:[newUpdate data] forType:[newUpdate format]]; -} - -- (NSData *) javaGetDataForType:(NSString *) inFormat { - - NSMutableArray *args = [NSMutableArray arrayWithObject:inFormat]; - [ThreadUtilities performOnMainThread:@selector(_nativeGetDataForType:) on:self withObject:args waitUntilDone:YES]; - return [args lastObject]; + [ThreadUtilities performOnMainThreadWaiting:YES block:^() { + self.changeCount = [[NSPasteboard generalPasteboard] declareTypes:types owner:self]; + }]; } -- (void) _nativeGetDataForType:(NSMutableArray *) args { - AWT_ASSERT_APPKIT_THREAD; +- (void)checkPasteboard:(id)sender { - NSData *returnValue = [[NSPasteboard generalPasteboard] dataForType:[args objectAtIndex:0]]; - - if (returnValue) [args replaceObjectAtIndex:0 withObject:returnValue]; - else [args removeLastObject]; -} - -- (void) checkPasteboard:(id)application { - AWT_ASSERT_APPKIT_THREAD; - - // 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; + + if (self.changeCount != newChangeCount) { + self.changeCount = newChangeCount; // Notify that the content might be changed static JNF_CLASS_CACHE(jc_CClipboard, "sun/lwawt/macosx/CClipboard"); @@ -191,11 +92,11 @@ // If we have a Java pasteboard owner, tell it that it doesn't own the pasteboard anymore. static JNF_MEMBER_CACHE(jm_lostOwnership, jc_CClipboard, "notifyLostOwnership", "()V"); @synchronized(self) { - if (fClipboardOwner) { + if (self.clipboardOwner) { JNIEnv *env = [ThreadUtilities getJNIEnv]; - JNFCallVoidMethod(env, fClipboardOwner, jm_lostOwnership); // AWT_THREADING Safe (event) - JNFDeleteGlobalRef(env, fClipboardOwner); - fClipboardOwner = NULL; + JNFCallVoidMethod(env, self.clipboardOwner, jm_lostOwnership); // AWT_THREADING Safe (event) + JNFDeleteGlobalRef(env, self.clipboardOwner); + self.clipboardOwner = NULL; } } } @@ -225,7 +126,7 @@ } (*env)->ReleasePrimitiveArrayCritical(env, inTypes, elements, JNI_ABORT); - [[CClipboard sharedClipboard] javaDeclareTypes:formatArray withOwner:inJavaClip jniEnv:env]; + [[CClipboard sharedClipboard] declareTypes:formatArray withOwner:inJavaClip jniEnv:env]; JNF_COCOA_EXIT(env); } @@ -248,7 +149,9 @@ NSData *bytesAsData = [NSData dataWithBytes:rawBytes length:nBytes]; (*env)->ReleasePrimitiveArrayCritical(env, inBytes, rawBytes, JNI_ABORT); NSString *format = formatForIndex(inFormat); - [[CClipboard sharedClipboard] javaSetData:bytesAsData forType:format]; + [ThreadUtilities performOnMainThreadWaiting:YES block:^() { + [[NSPasteboard generalPasteboard] setData:bytesAsData forType:format]; + }]; JNF_COCOA_EXIT(env); } @@ -263,7 +166,12 @@ jlongArray returnValue = NULL; JNF_COCOA_ENTER(env); - NSArray *dataTypes = [[CClipboard sharedClipboard] javaGetTypes]; + __block NSArray* dataTypes; + [ThreadUtilities performOnMainThreadWaiting:YES block:^() { + dataTypes = [[[NSPasteboard generalPasteboard] types] retain]; + }]; + [dataTypes autorelease]; + NSUInteger nFormats = [dataTypes count]; NSUInteger knownFormats = 0; NSUInteger i; @@ -320,11 +228,16 @@ JNF_COCOA_ENTER(env); NSString *formatAsString = formatForIndex(format); - NSData *clipData = [[CClipboard sharedClipboard] javaGetDataForType:formatAsString]; - + __block NSData* clipData; + [ThreadUtilities performOnMainThreadWaiting:YES block:^() { + clipData = [[[NSPasteboard generalPasteboard] dataForType:formatAsString] retain]; + }]; + if (clipData == NULL) { [JNFException raise:env as:"java/io/IOException" reason:"Font transform has NaN position"]; return NULL; + } else { + [clipData autorelease]; } NSUInteger dataSize = [clipData length]; @@ -350,13 +263,13 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_checkPasteboard (JNIEnv *env, jobject inObject ) { - JNF_COCOA_ENTER(env); +JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ [[CClipboard sharedClipboard] checkPasteboard:nil]; }]; - JNF_COCOA_EXIT(env); +JNF_COCOA_EXIT(env); } --- old/src/macosx/native/sun/awt/CClipboard.h 2014-03-18 12:10:25.000000000 +0400 +++ /dev/null 2014-03-18 12:10:25.000000000 +0400 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2011, 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. - */ - -#import -#import "jni.h" - -@interface CClipboard : NSObject { - jobject fClipboardOwner; - - // Track pasteboard changes. Initialized once at the start, and then updated - // on an application resume event. If it's different than the last time we claimed - // the clipboard that means we lost the clipboard to someone else. - NSInteger fChangeCount; -} - -+ (CClipboard *) sharedClipboard; - -- (void) javaDeclareTypes:(NSArray *)inTypes withOwner:(jobject)inClipboard jniEnv:(JNIEnv *)inEnv; -- (void) javaSetData:(NSData *)inData forType:(NSString *) inFormat; - -- (NSArray *) javaGetTypes; -- (NSData *) javaGetDataForType:(NSString *)inFormat; - -@end