src/macosx/native/sun/awt/CClipboard.m

Print this page




   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #import "CClipboard.h"
  27 #import "CDataTransferer.h"
  28 #import "ThreadUtilities.h"
  29 #import "jni_util.h" 
  30 #import <Cocoa/Cocoa.h>
  31 #import <JavaNativeFoundation/JavaNativeFoundation.h>
  32 
  33 static CClipboard *sClipboard = nil;
  34 
  35 //
  36 // CClipboardUpdate is used for mulitple calls to setData that happen before
  37 // the model and AppKit can get back in sync.
  38 //
  39 
  40 @interface CClipboardUpdate : NSObject {
  41     NSData *fData;
  42     NSString *fFormat;
  43 }
  44 
  45 - (id)initWithData:(NSData *)inData withFormat:(NSString *)inFormat;
  46 - (NSData *)data;
  47 - (NSString *)format;
  48 
  49 @end
  50 
  51 @implementation CClipboardUpdate
  52 
  53 - (id)initWithData:(NSData *)inData withFormat:(NSString *)inFormat
  54 {
  55     self = [super init];
  56 
  57     if (self != nil) {
  58         fData = [inData retain];
  59         fFormat = [inFormat retain];
  60     }
  61 
  62     return self;
  63 }
  64 
  65 - (void)dealloc
  66 {
  67     [fData release];
  68     fData = nil;
  69 
  70     [fFormat release];
  71     fFormat = nil;
  72 
  73     [super dealloc];
  74 }
  75 
  76 - (NSData *)data {
  77     return fData;
  78 }
  79 
  80 - (NSString *)format {
  81     return fFormat;
  82 }
  83 @end
  84 
  85 @implementation CClipboard


  86 
  87 // Clipboard creation is synchronized at the Java level.
  88 + (CClipboard *) sharedClipboard
  89 {
  90     if (sClipboard == nil) {
  91         sClipboard = [[CClipboard alloc] init];
  92         [[NSNotificationCenter defaultCenter] addObserver:sClipboard selector: @selector(checkPasteboard:)
  93                                                      name: NSApplicationDidBecomeActiveNotification
  94                                                    object: nil];
  95     }
  96 
  97     return sClipboard;
  98 }
  99 
 100 - (id) init
 101 {
 102     self = [super init];
 103 
 104     if (self != nil) {
 105         fChangeCount = [[NSPasteboard generalPasteboard] changeCount];
 106     }
 107 
 108     return self;
 109 }
 110 
 111 - (void) javaDeclareTypes:(NSArray *)inTypes withOwner:(jobject)inClipboard jniEnv:(JNIEnv *)inEnv {
 112 
 113     @synchronized(self) {
 114         if (inClipboard != NULL) {
 115             if (fClipboardOwner != NULL) {
 116                 JNFDeleteGlobalRef(inEnv, fClipboardOwner);
 117             }
 118             fClipboardOwner = JNFNewGlobalRef(inEnv, inClipboard);
 119         }
 120     }
 121     [ThreadUtilities performOnMainThread:@selector(_nativeDeclareTypes:) on:self withObject:inTypes waitUntilDone:YES];
 122 }
 123 
 124 - (void) _nativeDeclareTypes:(NSArray *)inTypes {
 125     AWT_ASSERT_APPKIT_THREAD;
 126 
 127     fChangeCount = [[NSPasteboard generalPasteboard] declareTypes:inTypes owner:self];
 128 }
 129 
 130 
 131 - (NSArray *) javaGetTypes {
 132 
 133     NSMutableArray *args = [NSMutableArray arrayWithCapacity:1];
 134     [ThreadUtilities performOnMainThread:@selector(_nativeGetTypes:) on:self withObject:args waitUntilDone:YES];
 135     return [args lastObject];
 136 }
 137 
 138 - (void) _nativeGetTypes:(NSMutableArray *)args {
 139     AWT_ASSERT_APPKIT_THREAD;
 140 
 141     [args addObject:[[NSPasteboard generalPasteboard] types]];
 142 }
 143 
 144 - (void) javaSetData:(NSData *)inData forType:(NSString *) inFormat {
 145 
 146     CClipboardUpdate *newUpdate = [[CClipboardUpdate alloc] initWithData:inData withFormat:inFormat];
 147     [ThreadUtilities performOnMainThread:@selector(_nativeSetData:) on:self withObject:newUpdate waitUntilDone:YES];
 148     [newUpdate release];
 149 }
 150 
 151 - (void) _nativeSetData:(CClipboardUpdate *)newUpdate {
 152     AWT_ASSERT_APPKIT_THREAD;
 153 
 154     [[NSPasteboard generalPasteboard] setData:[newUpdate data] forType:[newUpdate format]];
 155 }
 156 
 157 - (NSData *) javaGetDataForType:(NSString *) inFormat {
 158 
 159     NSMutableArray *args = [NSMutableArray arrayWithObject:inFormat];
 160     [ThreadUtilities performOnMainThread:@selector(_nativeGetDataForType:) on:self withObject:args waitUntilDone:YES];
 161     return [args lastObject];
 162 }
 163 
 164 - (void) _nativeGetDataForType:(NSMutableArray *) args {
 165     AWT_ASSERT_APPKIT_THREAD;
 166 
 167     NSData *returnValue = [[NSPasteboard generalPasteboard] dataForType:[args objectAtIndex:0]];
 168 
 169     if (returnValue) [args replaceObjectAtIndex:0 withObject:returnValue];
 170     else [args removeLastObject];
 171 }
 172 
 173 - (void) checkPasteboard:(id)application {
 174     AWT_ASSERT_APPKIT_THREAD;
 175     
 176     // This is called via NSApplicationDidBecomeActiveNotification.
 177     
 178     // If the change count on the general pasteboard is different than when we set it
 179     // someone else put data on the clipboard.  That means the current owner lost ownership.
 180     NSInteger newChangeCount = [[NSPasteboard generalPasteboard] changeCount];
 181     
 182     if (fChangeCount != newChangeCount) {
 183         fChangeCount = newChangeCount;    
 184 
 185         // Notify that the content might be changed
 186         static JNF_CLASS_CACHE(jc_CClipboard, "sun/lwawt/macosx/CClipboard");
 187         static JNF_STATIC_MEMBER_CACHE(jm_contentChanged, jc_CClipboard, "notifyChanged", "()V");
 188         JNIEnv *env = [ThreadUtilities getJNIEnv];
 189         JNFCallStaticVoidMethod(env, jm_contentChanged);
 190 
 191         // If we have a Java pasteboard owner, tell it that it doesn't own the pasteboard anymore.
 192         static JNF_MEMBER_CACHE(jm_lostOwnership, jc_CClipboard, "notifyLostOwnership", "()V");
 193         @synchronized(self) {
 194             if (fClipboardOwner) {
 195                 JNIEnv *env = [ThreadUtilities getJNIEnv];
 196                 JNFCallVoidMethod(env, fClipboardOwner, jm_lostOwnership); // AWT_THREADING Safe (event)
 197                 JNFDeleteGlobalRef(env, fClipboardOwner);
 198                 fClipboardOwner = NULL;
 199             }
 200         }
 201     }
 202 }
 203 
 204 @end
 205 
 206 /*
 207  * Class:     sun_lwawt_macosx_CClipboard
 208  * Method:    declareTypes
 209  * Signature: ([JLsun/awt/datatransfer/SunClipboard;)V
 210 */
 211 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_declareTypes
 212 (JNIEnv *env, jobject inObject, jlongArray inTypes, jobject inJavaClip)
 213 {
 214 JNF_COCOA_ENTER(env);
 215 
 216     jint i;
 217     jint nElements = (*env)->GetArrayLength(env, inTypes);
 218     NSMutableArray *formatArray = [NSMutableArray arrayWithCapacity:nElements];
 219     jlong *elements = (*env)->GetPrimitiveArrayCritical(env, inTypes, NULL);
 220 
 221     for (i = 0; i < nElements; i++) {
 222         NSString *pbFormat = formatForIndex(elements[i]);
 223         if (pbFormat)
 224             [formatArray addObject:pbFormat];
 225     }
 226 
 227     (*env)->ReleasePrimitiveArrayCritical(env, inTypes, elements, JNI_ABORT);
 228     [[CClipboard sharedClipboard] javaDeclareTypes:formatArray withOwner:inJavaClip jniEnv:env];
 229 JNF_COCOA_EXIT(env);
 230 }
 231 
 232 /*
 233  * Class:     sun_lwawt_macosx_CClipboard
 234  * Method:    setData
 235  * Signature: ([BJ)V
 236 */
 237 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_setData
 238 (JNIEnv *env, jobject inObject, jbyteArray inBytes, jlong inFormat)
 239 {
 240     if (inBytes == NULL) {
 241         return;
 242     }
 243 
 244 JNF_COCOA_ENTER(env);
 245     jint nBytes = (*env)->GetArrayLength(env, inBytes);
 246     jbyte *rawBytes = (*env)->GetPrimitiveArrayCritical(env, inBytes, NULL);
 247     CHECK_NULL(rawBytes);
 248     NSData *bytesAsData = [NSData dataWithBytes:rawBytes length:nBytes];
 249     (*env)->ReleasePrimitiveArrayCritical(env, inBytes, rawBytes, JNI_ABORT);
 250     NSString *format = formatForIndex(inFormat);
 251     [[CClipboard sharedClipboard] javaSetData:bytesAsData forType:format];


 252 JNF_COCOA_EXIT(env);
 253 }
 254 
 255 /*
 256  * Class:     sun_lwawt_macosx_CClipboard
 257  * Method:    getClipboardFormats
 258  * Signature: (J)[J
 259      */
 260 JNIEXPORT jlongArray JNICALL Java_sun_lwawt_macosx_CClipboard_getClipboardFormats
 261 (JNIEnv *env, jobject inObject)
 262 {
 263     jlongArray returnValue = NULL;
 264 JNF_COCOA_ENTER(env);
 265 
 266     NSArray *dataTypes = [[CClipboard sharedClipboard] javaGetTypes];





 267     NSUInteger nFormats = [dataTypes count];
 268     NSUInteger knownFormats = 0;
 269     NSUInteger i;
 270 
 271     // There can be any number of formats on the general pasteboard.  Find out which ones
 272     // we know about (i.e., live in the flavormap.properties).
 273     for (i = 0; i < nFormats; i++) {
 274         NSString *format = (NSString *)[dataTypes objectAtIndex:i];
 275         if (indexForFormat(format) != -1)
 276             knownFormats++;
 277     }
 278 
 279     returnValue = (*env)->NewLongArray(env, knownFormats);
 280     if (returnValue == NULL) {
 281         return NULL;
 282     }
 283 
 284     if (knownFormats == 0) {
 285         return returnValue;
 286     }


 303     (*env)->ReleaseLongArrayElements(env, returnValue, saveFormats, JNI_COMMIT);
 304 JNF_COCOA_EXIT(env);
 305     return returnValue;
 306 }
 307 
 308 /*
 309  * Class:     sun_lwawt_macosx_CClipboard
 310  * Method:    getClipboardData
 311  * Signature: (JJ)[B
 312      */
 313 JNIEXPORT jbyteArray JNICALL Java_sun_lwawt_macosx_CClipboard_getClipboardData
 314 (JNIEnv *env, jobject inObject, jlong format)
 315 {
 316     jbyteArray returnValue = NULL;
 317 
 318     // Note that this routine makes no attempt to interpret the data, since we're returning
 319     // a byte array back to Java.  CDataTransferer will do that if necessary.
 320 JNF_COCOA_ENTER(env);
 321 
 322     NSString *formatAsString = formatForIndex(format);
 323     NSData *clipData = [[CClipboard sharedClipboard] javaGetDataForType:formatAsString];



 324 
 325     if (clipData == NULL) {
 326         [JNFException raise:env as:"java/io/IOException" reason:"Font transform has NaN position"];
 327         return NULL;


 328     }
 329 
 330     NSUInteger dataSize = [clipData length];
 331     returnValue = (*env)->NewByteArray(env, dataSize);
 332     if (returnValue == NULL) {
 333         return NULL;
 334     }
 335 
 336     if (dataSize != 0) {
 337         const void *dataBuffer = [clipData bytes];
 338         (*env)->SetByteArrayRegion(env, returnValue, 0, dataSize, (jbyte *)dataBuffer);
 339     }
 340 
 341 JNF_COCOA_EXIT(env);
 342     return returnValue;
 343 }
 344 
 345 /*
 346  * Class:     sun_lwawt_macosx_CClipboard
 347  * Method:    checkPasteboard
 348  * Signature: ()V
 349  */
 350 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_checkPasteboard
 351 (JNIEnv *env, jobject inObject )
 352 {
 353     JNF_COCOA_ENTER(env);
 354 
 355     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
 356         [[CClipboard sharedClipboard] checkPasteboard:nil];
 357     }];
 358         
 359     JNF_COCOA_EXIT(env);
 360 }
 361 
 362 


   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 

  26 #import "CDataTransferer.h"
  27 #import "ThreadUtilities.h"
  28 #import "jni_util.h" 
  29 #import <Cocoa/Cocoa.h>
  30 #import <JavaNativeFoundation/JavaNativeFoundation.h>
  31 
  32 @interface CClipboard : NSObject { }
  33 @property NSInteger changeCount;
  34 @property jobject clipboardOwner;
  35 
  36 + (CClipboard*)sharedClipboard;
  37 - (void)declareTypes:(NSArray *)types withOwner:(jobject)owner jniEnv:(JNIEnv*)env;
  38 - (void)checkPasteboard:(id)sender;











































  39 @end
  40 
  41 @implementation CClipboard
  42 @synthesize changeCount = _changeCount;
  43 @synthesize clipboardOwner = _clipboardOwner;
  44 
  45 // Clipboard creation is synchronized at the Java level
  46 + (CClipboard*)sharedClipboard {
  47     static CClipboard* sClipboard = nil;
  48     if (sClipboard == nil) {
  49         sClipboard = [[CClipboard alloc] init];
  50         [[NSNotificationCenter defaultCenter] addObserver:sClipboard selector: @selector(checkPasteboard:)
  51                                                      name: NSApplicationDidBecomeActiveNotification
  52                                                    object: nil];
  53     }
  54 
  55     return sClipboard;
  56 }
  57 
  58 - (id)init {
  59     if (self = [super init]) {
  60         self.changeCount = [[NSPasteboard generalPasteboard] changeCount];



  61     }

  62     return self;
  63 }
  64 
  65 - (void)declareTypes:(NSArray*)types withOwner:(jobject)owner jniEnv:(JNIEnv*)env {

  66     @synchronized(self) {
  67         if (owner != NULL) {
  68             if (self.clipboardOwner != NULL) {
  69                 JNFDeleteGlobalRef(env, self.clipboardOwner);
  70             }
  71             self.clipboardOwner = JNFNewGlobalRef(env, owner);
  72         }
  73     }
  74     [ThreadUtilities performOnMainThreadWaiting:YES block:^() {
  75         self.changeCount = [[NSPasteboard generalPasteboard] declareTypes:types owner:self];
  76     }];















































  77 }
  78 
  79 - (void)checkPasteboard:(id)sender {

  80 




  81     NSInteger newChangeCount = [[NSPasteboard generalPasteboard] changeCount];
  82 
  83     if (self.changeCount != newChangeCount) {
  84         self.changeCount = newChangeCount;
  85 
  86         // Notify that the content might be changed
  87         static JNF_CLASS_CACHE(jc_CClipboard, "sun/lwawt/macosx/CClipboard");
  88         static JNF_STATIC_MEMBER_CACHE(jm_contentChanged, jc_CClipboard, "notifyChanged", "()V");
  89         JNIEnv *env = [ThreadUtilities getJNIEnv];
  90         JNFCallStaticVoidMethod(env, jm_contentChanged);
  91 
  92         // If we have a Java pasteboard owner, tell it that it doesn't own the pasteboard anymore.
  93         static JNF_MEMBER_CACHE(jm_lostOwnership, jc_CClipboard, "notifyLostOwnership", "()V");
  94         @synchronized(self) {
  95             if (self.clipboardOwner) {
  96                 JNIEnv *env = [ThreadUtilities getJNIEnv];
  97                 JNFCallVoidMethod(env, self.clipboardOwner, jm_lostOwnership); // AWT_THREADING Safe (event)
  98                 JNFDeleteGlobalRef(env, self.clipboardOwner);
  99                 self.clipboardOwner = NULL;
 100             }
 101         }
 102     }
 103 }
 104 
 105 @end
 106 
 107 /*
 108  * Class:     sun_lwawt_macosx_CClipboard
 109  * Method:    declareTypes
 110  * Signature: ([JLsun/awt/datatransfer/SunClipboard;)V
 111 */
 112 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_declareTypes
 113 (JNIEnv *env, jobject inObject, jlongArray inTypes, jobject inJavaClip)
 114 {
 115 JNF_COCOA_ENTER(env);
 116 
 117     jint i;
 118     jint nElements = (*env)->GetArrayLength(env, inTypes);
 119     NSMutableArray *formatArray = [NSMutableArray arrayWithCapacity:nElements];
 120     jlong *elements = (*env)->GetPrimitiveArrayCritical(env, inTypes, NULL);
 121 
 122     for (i = 0; i < nElements; i++) {
 123         NSString *pbFormat = formatForIndex(elements[i]);
 124         if (pbFormat)
 125             [formatArray addObject:pbFormat];
 126     }
 127 
 128     (*env)->ReleasePrimitiveArrayCritical(env, inTypes, elements, JNI_ABORT);
 129     [[CClipboard sharedClipboard] declareTypes:formatArray withOwner:inJavaClip jniEnv:env];
 130 JNF_COCOA_EXIT(env);
 131 }
 132 
 133 /*
 134  * Class:     sun_lwawt_macosx_CClipboard
 135  * Method:    setData
 136  * Signature: ([BJ)V
 137 */
 138 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_setData
 139 (JNIEnv *env, jobject inObject, jbyteArray inBytes, jlong inFormat)
 140 {
 141     if (inBytes == NULL) {
 142         return;
 143     }
 144 
 145 JNF_COCOA_ENTER(env);
 146     jint nBytes = (*env)->GetArrayLength(env, inBytes);
 147     jbyte *rawBytes = (*env)->GetPrimitiveArrayCritical(env, inBytes, NULL);
 148     CHECK_NULL(rawBytes);
 149     NSData *bytesAsData = [NSData dataWithBytes:rawBytes length:nBytes];
 150     (*env)->ReleasePrimitiveArrayCritical(env, inBytes, rawBytes, JNI_ABORT);
 151     NSString *format = formatForIndex(inFormat);
 152     [ThreadUtilities performOnMainThreadWaiting:YES block:^() {
 153         [[NSPasteboard generalPasteboard] setData:bytesAsData forType:format];
 154     }];
 155 JNF_COCOA_EXIT(env);
 156 }
 157 
 158 /*
 159  * Class:     sun_lwawt_macosx_CClipboard
 160  * Method:    getClipboardFormats
 161  * Signature: (J)[J
 162      */
 163 JNIEXPORT jlongArray JNICALL Java_sun_lwawt_macosx_CClipboard_getClipboardFormats
 164 (JNIEnv *env, jobject inObject)
 165 {
 166     jlongArray returnValue = NULL;
 167 JNF_COCOA_ENTER(env);
 168 
 169     __block NSArray* dataTypes;
 170     [ThreadUtilities performOnMainThreadWaiting:YES block:^() {
 171         dataTypes = [[[NSPasteboard generalPasteboard] types] retain];
 172     }];
 173     [dataTypes autorelease];
 174     
 175     NSUInteger nFormats = [dataTypes count];
 176     NSUInteger knownFormats = 0;
 177     NSUInteger i;
 178 
 179     // There can be any number of formats on the general pasteboard.  Find out which ones
 180     // we know about (i.e., live in the flavormap.properties).
 181     for (i = 0; i < nFormats; i++) {
 182         NSString *format = (NSString *)[dataTypes objectAtIndex:i];
 183         if (indexForFormat(format) != -1)
 184             knownFormats++;
 185     }
 186 
 187     returnValue = (*env)->NewLongArray(env, knownFormats);
 188     if (returnValue == NULL) {
 189         return NULL;
 190     }
 191 
 192     if (knownFormats == 0) {
 193         return returnValue;
 194     }


 211     (*env)->ReleaseLongArrayElements(env, returnValue, saveFormats, JNI_COMMIT);
 212 JNF_COCOA_EXIT(env);
 213     return returnValue;
 214 }
 215 
 216 /*
 217  * Class:     sun_lwawt_macosx_CClipboard
 218  * Method:    getClipboardData
 219  * Signature: (JJ)[B
 220      */
 221 JNIEXPORT jbyteArray JNICALL Java_sun_lwawt_macosx_CClipboard_getClipboardData
 222 (JNIEnv *env, jobject inObject, jlong format)
 223 {
 224     jbyteArray returnValue = NULL;
 225 
 226     // Note that this routine makes no attempt to interpret the data, since we're returning
 227     // a byte array back to Java.  CDataTransferer will do that if necessary.
 228 JNF_COCOA_ENTER(env);
 229 
 230     NSString *formatAsString = formatForIndex(format);
 231     __block NSData* clipData;
 232     [ThreadUtilities performOnMainThreadWaiting:YES block:^() {
 233         clipData = [[[NSPasteboard generalPasteboard] dataForType:formatAsString] retain];
 234     }];
 235     
 236     if (clipData == NULL) {
 237         [JNFException raise:env as:"java/io/IOException" reason:"Font transform has NaN position"];
 238         return NULL;
 239     } else {
 240         [clipData autorelease];
 241     }
 242 
 243     NSUInteger dataSize = [clipData length];
 244     returnValue = (*env)->NewByteArray(env, dataSize);
 245     if (returnValue == NULL) {
 246         return NULL;
 247     }
 248 
 249     if (dataSize != 0) {
 250         const void *dataBuffer = [clipData bytes];
 251         (*env)->SetByteArrayRegion(env, returnValue, 0, dataSize, (jbyte *)dataBuffer);
 252     }
 253 
 254 JNF_COCOA_EXIT(env);
 255     return returnValue;
 256 }
 257 
 258 /*
 259  * Class:     sun_lwawt_macosx_CClipboard
 260  * Method:    checkPasteboard
 261  * Signature: ()V
 262  */
 263 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_checkPasteboard
 264 (JNIEnv *env, jobject inObject )
 265 {
 266 JNF_COCOA_ENTER(env);
 267 
 268     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
 269         [[CClipboard sharedClipboard] checkPasteboard:nil];
 270     }];
 271         
 272 JNF_COCOA_EXIT(env);
 273 }
 274 
 275