1 /* 2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 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 "CGLGraphicsConfig.h" 27 28 #import <JavaNativeFoundation/JavaNativeFoundation.h> 29 #import <JavaRuntimeSupport/JavaRuntimeSupport.h> 30 31 #import "ThreadUtilities.h" 32 #import "AWTView.h" 33 #import "AWTEvent.h" 34 #import "AWTWindow.h" 35 #import "LWCToolkit.h" 36 #import "JavaComponentAccessibility.h" 37 #import "JavaTextAccessibility.h" 38 #import "GeomUtilities.h" 39 #import "OSVersion.h" 40 #import "CGLLayer.h" 41 42 @interface AWTView() 43 @property (retain) CDropTarget *_dropTarget; 44 @property (retain) CDragSource *_dragSource; 45 @end 46 47 // Uncomment this line to see fprintfs of each InputMethod API being called on this View 48 //#define IM_DEBUG TRUE 49 //#define EXTRA_DEBUG 50 51 52 static BOOL shouldUsePressAndHold() { 53 static int shouldUsePressAndHold = -1; 54 if (shouldUsePressAndHold != -1) return shouldUsePressAndHold; 55 shouldUsePressAndHold = !isSnowLeopardOrLower(); 56 return shouldUsePressAndHold; 57 } 58 59 @implementation AWTView 60 61 @synthesize _dropTarget; 62 @synthesize _dragSource; 63 @synthesize cglLayer; 64 65 // Note: Must be called on main (AppKit) thread only 66 - (id) initWithRect: (NSRect) rect 67 platformView: (jobject) cPlatformView 68 windowLayer: (CALayer*) windowLayer 69 { 70 AWT_ASSERT_APPKIT_THREAD; 71 // Initialize ourselves 72 self = [super initWithFrame: rect]; 73 if (self == nil) return self; 74 75 m_cPlatformView = cPlatformView; 76 fInputMethodLOCKABLE = NULL; 77 fKeyEventsNeeded = NO; 78 fProcessingKeystroke = NO; 79 80 fEnablePressAndHold = shouldUsePressAndHold(); 81 fInPressAndHold = NO; 82 fPAHNeedsToSelect = NO; 83 84 if (windowLayer != nil) { 85 self.cglLayer = windowLayer; 86 [self setWantsLayer: YES]; 87 [self.layer addSublayer: (CALayer *)cglLayer]; 88 [self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize]; 89 [self setLayerContentsPlacement: NSViewLayerContentsPlacementTopLeft]; 90 [self setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable]; 91 } 92 93 #if USE_INTERMEDIATE_BUFFER 94 self.cglLayer = windowLayer; 95 [self setWantsLayer: YES]; 96 [self.layer addSublayer: (CALayer *)cglLayer]; 97 [self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize]; 98 [self setLayerContentsPlacement: NSViewLayerContentsPlacementTopLeft]; 99 [self setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable]; 100 #ifdef REMOTELAYER 101 CGLLayer *parentLayer = (CGLLayer*)self.cglLayer; 102 parentLayer.parentLayer = NULL; 103 parentLayer.remoteLayer = NULL; 104 if (JRSRemotePort != 0 && remoteSocketFD > 0) { 105 CGLLayer *remoteLayer = [CGLLayer layer]; 106 remoteLayer.target = GL_TEXTURE_2D; 107 NSLog(@"Creating Parent=%p, Remote=%p", parentLayer, remoteLayer); 108 parentLayer.remoteLayer = remoteLayer; 109 remoteLayer.parentLayer = parentLayer; 110 remoteLayer.remoteLayer = NULL; 111 remoteLayer.jrsRemoteLayer = [remoteLayer createRemoteLayerBoundTo:JRSRemotePort]; 112 CFRetain(remoteLayer); // REMIND 113 remoteLayer.frame = CGRectMake(0, 0, 720, 500); // REMIND 114 CFRetain(remoteLayer.jrsRemoteLayer); // REMIND 115 int layerID = [remoteLayer.jrsRemoteLayer layerID]; 116 NSLog(@"layer id to send = %d", layerID); 117 sendLayerID(layerID); 118 } 119 #endif /* REMOTELAYER */ 120 #endif 121 return self; 122 } 123 124 - (void) dealloc { 125 AWT_ASSERT_APPKIT_THREAD; 126 127 self.cglLayer = nil; 128 #if USE_INTERMEDIATE_BUFFER 129 self.cglLayer = nil; 130 #endif 131 132 JNIEnv *env = [ThreadUtilities getJNIEnv]; 133 (*env)->DeleteGlobalRef(env, m_cPlatformView); 134 m_cPlatformView = NULL; 135 136 if (fInputMethodLOCKABLE != NULL) 137 { 138 JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; 139 140 JNFDeleteGlobalRef(env, fInputMethodLOCKABLE); 141 fInputMethodLOCKABLE = NULL; 142 } 143 144 145 [super dealloc]; 146 } 147 148 - (void) viewDidMoveToWindow { 149 AWT_ASSERT_APPKIT_THREAD; 150 151 [AWTToolkit eventCountPlusPlus]; 152 153 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^() { 154 [[self window] makeFirstResponder: self]; 155 }]; 156 if ([self window] != NULL) { 157 [self resetTrackingRect]; 158 } 159 } 160 161 - (BOOL) acceptsFirstMouse: (NSEvent *)event { 162 return YES; 163 } 164 165 - (BOOL) acceptsFirstResponder { 166 return YES; 167 } 168 169 - (BOOL) becomeFirstResponder { 170 return YES; 171 } 172 173 - (BOOL) preservesContentDuringLiveResize { 174 return YES; 175 } 176 177 /* 178 * Automatically triggered functions. 179 */ 180 181 /* 182 * MouseEvents support 183 */ 184 185 - (void) mouseDown: (NSEvent *)event { 186 NSInputManager *inputManager = [NSInputManager currentInputManager]; 187 if ([inputManager wantsToHandleMouseEvents]) { 188 #if IM_DEBUG 189 NSLog(@"-> IM wants to handle event"); 190 #endif 191 if (![inputManager handleMouseEvent:event]) { 192 [self deliverJavaMouseEvent: event]; 193 } else { 194 #if IM_DEBUG 195 NSLog(@"-> Event was handled."); 196 #endif 197 } 198 } else { 199 NSLog(@"-> IM does not want to handle event"); 200 [self deliverJavaMouseEvent: event]; 201 } 202 } 203 204 - (void) mouseUp: (NSEvent *)event { 205 [self deliverJavaMouseEvent: event]; 206 } 207 208 - (void) rightMouseDown: (NSEvent *)event { 209 [self deliverJavaMouseEvent: event]; 210 } 211 212 - (void) rightMouseUp: (NSEvent *)event { 213 [self deliverJavaMouseEvent: event]; 214 } 215 216 - (void) otherMouseDown: (NSEvent *)event { 217 [self deliverJavaMouseEvent: event]; 218 } 219 220 - (void) otherMouseUp: (NSEvent *)event { 221 [self deliverJavaMouseEvent: event]; 222 } 223 224 - (void) mouseMoved: (NSEvent *)event { 225 // TODO: better way to redirect move events to the "under" view 226 227 NSPoint eventLocation = [event locationInWindow]; 228 NSPoint localPoint = [self convertPoint: eventLocation fromView: nil]; 229 230 if ([self mouse: localPoint inRect: [self bounds]]) { 231 [self deliverJavaMouseEvent: event]; 232 } else { 233 [[self nextResponder] mouseDown:event]; 234 } 235 } 236 237 - (void) mouseDragged: (NSEvent *)event { 238 [self deliverJavaMouseEvent: event]; 239 } 240 241 - (void) rightMouseDragged: (NSEvent *)event { 242 [self deliverJavaMouseEvent: event]; 243 } 244 245 - (void) otherMouseDragged: (NSEvent *)event { 246 [self deliverJavaMouseEvent: event]; 247 } 248 249 - (void) mouseEntered: (NSEvent *)event { 250 [[self window] setAcceptsMouseMovedEvents:YES]; 251 //[[self window] makeFirstResponder:self]; 252 [self deliverJavaMouseEvent: event]; 253 } 254 255 - (void) mouseExited: (NSEvent *)event { 256 [[self window] setAcceptsMouseMovedEvents:NO]; 257 [self deliverJavaMouseEvent: event]; 258 //Restore the cursor back. 259 //[CCursorManager _setCursor: [NSCursor arrowCursor]]; 260 } 261 262 - (void) scrollWheel: (NSEvent*) event { 263 [self deliverJavaMouseEvent: event]; 264 } 265 266 /* 267 * KeyEvents support 268 */ 269 270 - (void) keyDown: (NSEvent *)event { 271 272 fProcessingKeystroke = YES; 273 fKeyEventsNeeded = YES; 274 275 // Allow TSM to look at the event and potentially send back NSTextInputClient messages. 276 [self interpretKeyEvents:[NSArray arrayWithObject:event]]; 277 278 if (fEnablePressAndHold && [event willBeHandledByComplexInputMethod]) { 279 fProcessingKeystroke = NO; 280 if (!fInPressAndHold) { 281 fInPressAndHold = YES; 282 fPAHNeedsToSelect = YES; 283 } 284 return; 285 } 286 287 if (![self hasMarkedText] && fKeyEventsNeeded) { 288 [self deliverJavaKeyEventHelper: event]; 289 } 290 291 fProcessingKeystroke = NO; 292 } 293 294 - (void) keyUp: (NSEvent *)event { 295 [self deliverJavaKeyEventHelper: event]; 296 } 297 298 - (void) flagsChanged: (NSEvent *)event { 299 [self deliverJavaKeyEventHelper: event]; 300 } 301 302 - (BOOL) performKeyEquivalent: (NSEvent *) event { 303 [self deliverJavaKeyEventHelper: event]; 304 return NO; 305 } 306 307 /** 308 * Utility methods and accessors 309 */ 310 311 -(void) deliverJavaMouseEvent: (NSEvent *) event { 312 [AWTToolkit eventCountPlusPlus]; 313 314 JNIEnv *env = [ThreadUtilities getJNIEnv]; 315 316 NSPoint eventLocation = [event locationInWindow]; 317 NSPoint localPoint = [self convertPoint: eventLocation fromView: nil]; 318 NSPoint absP = [NSEvent mouseLocation]; 319 NSEventType type = [event type]; 320 321 // Convert global numbers between Cocoa's coordinate system and Java. 322 // TODO: need consitent way for doing that both with global as well as with local coordinates. 323 // The reason to do it here is one more native method for getting screen dimension otherwise. 324 325 NSRect screenRect = [[NSScreen mainScreen] frame]; 326 absP.y = screenRect.size.height - absP.y; 327 jint clickCount; 328 329 if (type == NSMouseEntered || 330 type == NSMouseExited || 331 type == NSScrollWheel || 332 type == NSMouseMoved) { 333 clickCount = 0; 334 } else { 335 clickCount = [event clickCount]; 336 } 337 338 static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/event/NSEvent"); 339 static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDD)V"); 340 jobject jEvent = JNFNewObject(env, jctor_NSEvent, 341 [event type], 342 [event modifierFlags], 343 clickCount, 344 [event buttonNumber], 345 (jint)localPoint.x, (jint)localPoint.y, 346 (jint)absP.x, (jint)absP.y, 347 [event deltaY], 348 [event deltaX]); 349 if (jEvent == nil) { 350 // Unable to create event by some reason. 351 return; 352 } 353 354 static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); 355 static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/event/NSEvent;)V"); 356 JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent); 357 } 358 359 360 - (void) clearTrackingRect { 361 if (rolloverTrackingRectTag > 0) { 362 [self removeTrackingRect:rolloverTrackingRectTag]; 363 rolloverTrackingRectTag = 0; 364 } 365 } 366 367 - (void) resetTrackingRect { 368 [self clearTrackingRect]; 369 rolloverTrackingRectTag = [self addTrackingRect:[self visibleRect] 370 owner:self 371 userData:NULL 372 assumeInside:NO]; 373 } 374 375 - (void) resetCursorRects { 376 [super resetCursorRects]; 377 [self resetTrackingRect]; 378 } 379 380 -(void) deliverJavaKeyEventHelper: (NSEvent *) event { 381 [AWTToolkit eventCountPlusPlus]; 382 JNIEnv *env = [ThreadUtilities getJNIEnv]; 383 384 jstring characters = NULL; 385 if ([event type] != NSFlagsChanged) { 386 characters = JNFNSToJavaString(env, [event characters]); 387 } 388 389 static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/event/NSEvent"); 390 static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IISLjava/lang/String;)V"); 391 jobject jevent = JNFNewObject(env, jctor_NSEvent, 392 [event type], 393 [event modifierFlags], 394 [event keyCode], 395 characters); 396 397 static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); 398 static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView, 399 "deliverKeyEvent", "(Lsun/lwawt/macosx/event/NSEvent;)V"); 400 JNFCallVoidMethod(env, m_cPlatformView, jm_deliverKeyEvent, jevent); 401 402 if (characters != NULL) { 403 (*env)->DeleteLocalRef(env, characters); 404 } 405 } 406 407 - (void) drawRect:(NSRect)dirtyRect { 408 AWT_ASSERT_APPKIT_THREAD; 409 410 [super drawRect:dirtyRect]; 411 JNIEnv *env = [ThreadUtilities getJNIEnv]; 412 if (env != NULL) { 413 /* 414 if ([self inLiveResize]) { 415 NSRect rs[4]; 416 NSInteger count; 417 [self getRectsExposedDuringLiveResize:rs count:&count]; 418 for (int i = 0; i < count; i++) { 419 JNU_CallMethodByName(env, NULL, [m_awtWindow cPlatformView], 420 "deliverWindowDidExposeEvent", "(FFFF)V", 421 (jfloat)rs[i].origin.x, (jfloat)rs[i].origin.y, 422 (jfloat)rs[i].size.width, (jfloat)rs[i].size.height); 423 if ((*env)->ExceptionOccurred(env)) { 424 (*env)->ExceptionDescribe(env); 425 (*env)->ExceptionClear(env); 426 } 427 } 428 } else { 429 */ 430 static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView"); 431 static JNF_MEMBER_CACHE(jm_deliverWindowDidExposeEvent, jc_CPlatformView, "deliverWindowDidExposeEvent", "()V"); 432 JNFCallVoidMethod(env, m_cPlatformView, jm_deliverWindowDidExposeEvent); 433 /* 434 } 435 */ 436 } 437 } 438 439 // NSAccessibility support 440 - (jobject)awtComponent:(JNIEnv*)env 441 { 442 static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView"); 443 static JNF_MEMBER_CACHE(jf_Peer, jc_CPlatformView, "peer", "Lsun/lwawt/LWWindowPeer;"); 444 if ((env == NULL) || (m_cPlatformView == NULL)) { 445 NSLog(@"Apple AWT : Error AWTView:awtComponent given bad parameters."); 446 if (env != NULL) 447 { 448 JNFDumpJavaStack(env); 449 } 450 return NULL; 451 } 452 jobject peer = JNFGetObjectField(env, m_cPlatformView, jf_Peer); 453 static JNF_CLASS_CACHE(jc_LWWindowPeer, "sun/lwawt/LWWindowPeer"); 454 static JNF_MEMBER_CACHE(jf_Target, jc_LWWindowPeer, "target", "Ljava/awt/Component;"); 455 if (peer == NULL) { 456 NSLog(@"Apple AWT : Error AWTView:awtComponent got null peer from CPlatformView"); 457 JNFDumpJavaStack(env); 458 return NULL; 459 } 460 return JNFGetObjectField(env, peer, jf_Target); 461 } 462 463 - (id)getAxData:(JNIEnv*)env 464 { 465 return [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:[self awtComponent:env] withIndex:-1 withView:self withJavaRole:nil] autorelease]; 466 } 467 468 - (NSArray *)accessibilityAttributeNames 469 { 470 return [[super accessibilityAttributeNames] arrayByAddingObject:NSAccessibilityChildrenAttribute]; 471 } 472 473 // NSAccessibility messages 474 // attribute methods 475 - (id)accessibilityAttributeValue:(NSString *)attribute 476 { 477 AWT_ASSERT_APPKIT_THREAD; 478 479 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) 480 { 481 JNIEnv *env = [ThreadUtilities getJNIEnv]; 482 483 (*env)->PushLocalFrame(env, 4); 484 485 id result = NSAccessibilityUnignoredChildrenForOnlyChild([self getAxData:env]); 486 487 (*env)->PopLocalFrame(env, NULL); 488 489 return result; 490 } 491 else 492 { 493 return [super accessibilityAttributeValue:attribute]; 494 } 495 } 496 - (BOOL)accessibilityIsIgnored 497 { 498 return YES; 499 } 500 501 - (id)accessibilityHitTest:(NSPoint)point 502 { 503 AWT_ASSERT_APPKIT_THREAD; 504 JNIEnv *env = [ThreadUtilities getJNIEnv]; 505 506 (*env)->PushLocalFrame(env, 4); 507 508 id result = [[self getAxData:env] accessibilityHitTest:point withEnv:env]; 509 510 (*env)->PopLocalFrame(env, NULL); 511 512 return result; 513 } 514 515 - (id)accessibilityFocusedUIElement 516 { 517 AWT_ASSERT_APPKIT_THREAD; 518 519 JNIEnv *env = [ThreadUtilities getJNIEnv]; 520 521 (*env)->PushLocalFrame(env, 4); 522 523 id result = [[self getAxData:env] accessibilityFocusedUIElement]; 524 525 (*env)->PopLocalFrame(env, NULL); 526 527 return result; 528 } 529 530 // --- Services menu support for lightweights --- 531 532 // finds the focused accessable element, and if it's a text element, obtains the text from it 533 - (NSString *)accessibleSelectedText 534 { 535 id focused = [self accessibilityFocusedUIElement]; 536 if (![focused isKindOfClass:[JavaTextAccessibility class]]) return nil; 537 return [(JavaTextAccessibility *)focused accessibilitySelectedTextAttribute]; 538 } 539 540 // same as above, but converts to RTFD 541 - (NSData *)accessibleSelectedTextAsRTFD 542 { 543 NSString *selectedText = [self accessibleSelectedText]; 544 NSAttributedString *styledText = [[NSAttributedString alloc] initWithString:selectedText]; 545 NSData *rtfdData = [styledText RTFDFromRange:NSMakeRange(0, [styledText length]) documentAttributes:nil]; 546 [styledText release]; 547 return rtfdData; 548 } 549 550 // finds the focused accessable element, and if it's a text element, sets the text in it 551 - (BOOL)replaceAccessibleTextSelection:(NSString *)text 552 { 553 id focused = [self accessibilityFocusedUIElement]; 554 if (![focused isKindOfClass:[JavaTextAccessibility class]]) return NO; 555 [(JavaTextAccessibility *)focused accessibilitySetSelectedTextAttribute:text]; 556 return YES; 557 } 558 559 // called for each service in the Services menu - only handle text for now 560 - (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType 561 { 562 if ([[self window] firstResponder] != self) return nil; // let AWT components handle themselves 563 564 if ([sendType isEqual:NSStringPboardType] || [returnType isEqual:NSStringPboardType]) { 565 NSString *selectedText = [self accessibleSelectedText]; 566 if (selectedText) return self; 567 } 568 569 return nil; 570 } 571 572 // fetch text from Java and hand off to the service 573 - (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard types:(NSArray *)types 574 { 575 if ([types containsObject:NSStringPboardType]) 576 { 577 [pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; 578 return [pboard setString:[self accessibleSelectedText] forType:NSStringPboardType]; 579 } 580 581 if ([types containsObject:NSRTFDPboardType]) 582 { 583 [pboard declareTypes:[NSArray arrayWithObject:NSRTFDPboardType] owner:nil]; 584 return [pboard setData:[self accessibleSelectedTextAsRTFD] forType:NSRTFDPboardType]; 585 } 586 587 return NO; 588 } 589 590 // write text back to Java from the service 591 - (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard 592 { 593 if ([[pboard types] containsObject:NSStringPboardType]) 594 { 595 NSString *text = [pboard stringForType:NSStringPboardType]; 596 return [self replaceAccessibleTextSelection:text]; 597 } 598 599 if ([[pboard types] containsObject:NSRTFDPboardType]) 600 { 601 NSData *rtfdData = [pboard dataForType:NSRTFDPboardType]; 602 NSAttributedString *styledText = [[NSAttributedString alloc] initWithRTFD:rtfdData documentAttributes:nil]; 603 NSString *text = [styledText string]; 604 [styledText release]; 605 606 return [self replaceAccessibleTextSelection:text]; 607 } 608 609 return NO; 610 } 611 612 613 -(void) setDragSource:(CDragSource *)source { 614 self._dragSource = source; 615 } 616 617 618 - (void) setDropTarget:(CDropTarget *)target { 619 self._dropTarget = target; 620 [ThreadUtilities performOnMainThread:@selector(controlModelControlValid) onObject:self._dropTarget withObject:nil waitUntilDone:YES awtMode:YES]; 621 } 622 623 /******************************** BEGIN NSDraggingSource Interface ********************************/ 624 625 - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)flag 626 { 627 // If draggingSource is nil route the message to the superclass (if responding to the selector): 628 CDragSource *dragSource = self._dragSource; 629 NSDragOperation dragOp = NSDragOperationNone; 630 631 if (dragSource != nil) 632 dragOp = [dragSource draggingSourceOperationMaskForLocal:flag]; 633 else if ([super respondsToSelector:@selector(draggingSourceOperationMaskForLocal:)]) 634 dragOp = [super draggingSourceOperationMaskForLocal:flag]; 635 636 return dragOp; 637 } 638 639 - (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination 640 { 641 // If draggingSource is nil route the message to the superclass (if responding to the selector): 642 CDragSource *dragSource = self._dragSource; 643 NSArray* array = nil; 644 645 if (dragSource != nil) 646 array = [dragSource namesOfPromisedFilesDroppedAtDestination:dropDestination]; 647 else if ([super respondsToSelector:@selector(namesOfPromisedFilesDroppedAtDestination:)]) 648 array = [super namesOfPromisedFilesDroppedAtDestination:dropDestination]; 649 650 return array; 651 } 652 653 - (void)draggedImage:(NSImage *)image beganAt:(NSPoint)screenPoint 654 { 655 // If draggingSource is nil route the message to the superclass (if responding to the selector): 656 CDragSource *dragSource = self._dragSource; 657 658 if (dragSource != nil) 659 [dragSource draggedImage:image beganAt:screenPoint]; 660 else if ([super respondsToSelector:@selector(draggedImage::)]) 661 [super draggedImage:image beganAt:screenPoint]; 662 } 663 664 - (void)draggedImage:(NSImage *)image endedAt:(NSPoint)screenPoint operation:(NSDragOperation)operation 665 { 666 // If draggingSource is nil route the message to the superclass (if responding to the selector): 667 CDragSource *dragSource = self._dragSource; 668 669 if (dragSource != nil) 670 [dragSource draggedImage:image endedAt:screenPoint operation:operation]; 671 else if ([super respondsToSelector:@selector(draggedImage:::)]) 672 [super draggedImage:image endedAt:screenPoint operation:operation]; 673 } 674 675 - (void)draggedImage:(NSImage *)image movedTo:(NSPoint)screenPoint 676 { 677 // If draggingSource is nil route the message to the superclass (if responding to the selector): 678 CDragSource *dragSource = self._dragSource; 679 680 if (dragSource != nil) 681 [dragSource draggedImage:image movedTo:screenPoint]; 682 else if ([super respondsToSelector:@selector(draggedImage::)]) 683 [super draggedImage:image movedTo:screenPoint]; 684 } 685 686 - (BOOL)ignoreModifierKeysWhileDragging 687 { 688 // If draggingSource is nil route the message to the superclass (if responding to the selector): 689 CDragSource *dragSource = self._dragSource; 690 BOOL result = FALSE; 691 692 if (dragSource != nil) 693 result = [dragSource ignoreModifierKeysWhileDragging]; 694 else if ([super respondsToSelector:@selector(ignoreModifierKeysWhileDragging)]) 695 result = [super ignoreModifierKeysWhileDragging]; 696 697 return result; 698 } 699 700 /******************************** END NSDraggingSource Interface ********************************/ 701 702 /******************************** BEGIN NSDraggingDestination Interface ********************************/ 703 704 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender 705 { 706 // If draggingDestination is nil route the message to the superclass: 707 CDropTarget *dropTarget = self._dropTarget; 708 NSDragOperation dragOp = NSDragOperationNone; 709 710 if (dropTarget != nil) 711 dragOp = [dropTarget draggingEntered:sender]; 712 else if ([super respondsToSelector:@selector(draggingEntered:)]) 713 dragOp = [super draggingEntered:sender]; 714 715 return dragOp; 716 } 717 718 - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender 719 { 720 // If draggingDestination is nil route the message to the superclass: 721 CDropTarget *dropTarget = self._dropTarget; 722 NSDragOperation dragOp = NSDragOperationNone; 723 724 if (dropTarget != nil) 725 dragOp = [dropTarget draggingUpdated:sender]; 726 else if ([super respondsToSelector:@selector(draggingUpdated:)]) 727 dragOp = [super draggingUpdated:sender]; 728 729 return dragOp; 730 } 731 732 - (void)draggingExited:(id <NSDraggingInfo>)sender 733 { 734 // If draggingDestination is nil route the message to the superclass: 735 CDropTarget *dropTarget = self._dropTarget; 736 737 if (dropTarget != nil) 738 [dropTarget draggingExited:sender]; 739 else if ([super respondsToSelector:@selector(draggingExited:)]) 740 [super draggingExited:sender]; 741 } 742 743 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender 744 { 745 // If draggingDestination is nil route the message to the superclass: 746 CDropTarget *dropTarget = self._dropTarget; 747 BOOL result = FALSE; 748 749 if (dropTarget != nil) 750 result = [dropTarget prepareForDragOperation:sender]; 751 else if ([super respondsToSelector:@selector(prepareForDragOperation:)]) 752 result = [super prepareForDragOperation:sender]; 753 754 return result; 755 } 756 757 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender 758 { 759 // If draggingDestination is nil route the message to the superclass: 760 CDropTarget *dropTarget = self._dropTarget; 761 BOOL result = FALSE; 762 763 if (dropTarget != nil) 764 result = [dropTarget performDragOperation:sender]; 765 else if ([super respondsToSelector:@selector(performDragOperation:)]) 766 result = [super performDragOperation:sender]; 767 768 return result; 769 } 770 771 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender 772 { 773 // If draggingDestination is nil route the message to the superclass: 774 CDropTarget *dropTarget = self._dropTarget; 775 776 if (dropTarget != nil) 777 [dropTarget concludeDragOperation:sender]; 778 else if ([super respondsToSelector:@selector(concludeDragOperation:)]) 779 [super concludeDragOperation:sender]; 780 } 781 782 - (void)draggingEnded:(id <NSDraggingInfo>)sender 783 { 784 // If draggingDestination is nil route the message to the superclass: 785 CDropTarget *dropTarget = self._dropTarget; 786 787 if (dropTarget != nil) 788 [dropTarget draggingEnded:sender]; 789 else if ([super respondsToSelector:@selector(draggingEnded:)]) 790 [super draggingEnded:sender]; 791 } 792 793 /******************************** END NSDraggingDestination Interface ********************************/ 794 795 /******************************** BEGIN NSTextInputClient Protocol ********************************/ 796 797 798 JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); 799 800 - (void) insertText:(id)aString replacementRange:(NSRange)replacementRange 801 { 802 #ifdef IM_DEBUG 803 fprintf(stderr, "AWTView InputMethod Selector Called : [insertText]: %s\n", [aString UTF8String]); 804 #endif // IM_DEBUG 805 806 if (fInputMethodLOCKABLE == NULL) { 807 return; 808 } 809 810 // Insert happens at the end of PAH 811 fInPressAndHold = NO; 812 813 // insertText gets called when the user commits text generated from an input method. It also gets 814 // called during ordinary input as well. We only need to send an input method event when we have marked 815 // text, or 'text in progress'. We also need to send the event if we get an insert text out of the blue! 816 // (i.e., when the user uses the Character palette or Inkwell), or when the string to insert is a complex 817 // Unicode value. 818 NSUInteger utf8Length = [aString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; 819 820 if ([self hasMarkedText] || !fProcessingKeystroke || (utf8Length > 2)) { 821 JNIEnv *env = [ThreadUtilities getJNIEnv]; 822 823 static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V"); 824 // We need to select the previous glyph so that it is overwritten. 825 if (fPAHNeedsToSelect) { 826 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph); 827 fPAHNeedsToSelect = NO; 828 } 829 830 static JNF_MEMBER_CACHE(jm_insertText, jc_CInputMethod, "insertText", "(Ljava/lang/String;)V"); 831 jstring insertedText = JNFNSToJavaString(env, aString); 832 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_insertText, insertedText); // AWT_THREADING Safe (AWTRunLoopMode) 833 (*env)->DeleteLocalRef(env, insertedText); 834 835 // The input method event will create psuedo-key events for each character in the committed string. 836 // We also don't want to send the character that triggered the insertText, usually a return. [3337563] 837 fKeyEventsNeeded = NO; 838 } 839 840 fPAHNeedsToSelect = NO; 841 842 } 843 844 - (void) doCommandBySelector:(SEL)aSelector 845 { 846 #ifdef IM_DEBUG 847 fprintf(stderr, "AWTView InputMethod Selector Called : [doCommandBySelector]\n"); 848 NSLog(@"%@", NSStringFromSelector(aSelector)); 849 #endif // IM_DEBUG 850 if (@selector(insertNewline:) == aSelector || @selector(insertTab:) == aSelector || @selector(deleteBackward:) == aSelector) 851 { 852 fKeyEventsNeeded = YES; 853 } 854 } 855 856 // setMarkedText: cannot take a nil first argument. aString can be NSString or NSAttributedString 857 - (void) setMarkedText:(id)aString selectedRange:(NSRange)selectionRange replacementRange:(NSRange)replacementRange 858 { 859 if (!fInputMethodLOCKABLE) 860 return; 861 862 BOOL isAttributedString = [aString isKindOfClass:[NSAttributedString class]]; 863 NSAttributedString *attrString = (isAttributedString ? (NSAttributedString *)aString : nil); 864 NSString *incomingString = (isAttributedString ? [aString string] : aString); 865 #ifdef IM_DEBUG 866 fprintf(stderr, "AWTView InputMethod Selector Called : [setMarkedText] \"%s\", loc=%lu, length=%lu\n", [incomingString UTF8String], (unsigned long)selectionRange.location, (unsigned long)selectionRange.length); 867 #endif // IM_DEBUG 868 static JNF_MEMBER_CACHE(jm_startIMUpdate, jc_CInputMethod, "startIMUpdate", "(Ljava/lang/String;)V"); 869 static JNF_MEMBER_CACHE(jm_addAttribute, jc_CInputMethod, "addAttribute", "(ZZII)V"); 870 static JNF_MEMBER_CACHE(jm_dispatchText, jc_CInputMethod, "dispatchText", "(IIZ)V"); 871 JNIEnv *env = [ThreadUtilities getJNIEnv]; 872 873 // NSInputContext already did the analysis of the TSM event and created attributes indicating 874 // the underlining and color that should be done to the string. We need to look at the underline 875 // style and color to determine what kind of Java hilighting needs to be done. 876 jstring inProcessText = JNFNSToJavaString(env, incomingString); 877 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_startIMUpdate, inProcessText); // AWT_THREADING Safe (AWTRunLoopMode) 878 (*env)->DeleteLocalRef(env, inProcessText); 879 880 if (isAttributedString) { 881 NSUInteger length; 882 NSRange effectiveRange; 883 NSDictionary *attributes; 884 length = [attrString length]; 885 effectiveRange = NSMakeRange(0, 0); 886 while (NSMaxRange(effectiveRange) < length) { 887 attributes = [attrString attributesAtIndex:NSMaxRange(effectiveRange) 888 effectiveRange:&effectiveRange]; 889 if (attributes) { 890 BOOL isThickUnderline, isGray; 891 NSNumber *underlineSizeObj = 892 (NSNumber *)[attributes objectForKey:NSUnderlineStyleAttributeName]; 893 NSInteger underlineSize = [underlineSizeObj integerValue]; 894 isThickUnderline = (underlineSize > 1); 895 896 NSColor *underlineColorObj = 897 (NSColor *)[attributes objectForKey:NSUnderlineColorAttributeName]; 898 isGray = !([underlineColorObj isEqual:[NSColor blackColor]]); 899 900 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_addAttribute, isThickUnderline, isGray, effectiveRange.location, effectiveRange.length); // AWT_THREADING Safe (AWTRunLoopMode) 901 } 902 } 903 } 904 905 static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V"); 906 // We need to select the previous glyph so that it is overwritten. 907 if (fPAHNeedsToSelect) { 908 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph); 909 fPAHNeedsToSelect = NO; 910 } 911 912 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_dispatchText, selectionRange.location, selectionRange.length, JNI_FALSE); // AWT_THREADING Safe (AWTRunLoopMode) 913 914 // If the marked text is being cleared (zero-length string) don't handle the key event. 915 if ([incomingString length] == 0) { 916 fKeyEventsNeeded = NO; 917 } 918 } 919 920 - (void) unmarkText 921 { 922 #ifdef IM_DEBUG 923 fprintf(stderr, "AWTView InputMethod Selector Called : [unmarkText]\n"); 924 #endif // IM_DEBUG 925 926 if (!fInputMethodLOCKABLE) { 927 return; 928 } 929 930 // unmarkText cancels any input in progress and commits it to the text field. 931 static JNF_MEMBER_CACHE(jm_unmarkText, jc_CInputMethod, "unmarkText", "()V"); 932 JNIEnv *env = [ThreadUtilities getJNIEnv]; 933 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_unmarkText); // AWT_THREADING Safe (AWTRunLoopMode) 934 935 } 936 937 - (BOOL) hasMarkedText 938 { 939 #ifdef IM_DEBUG 940 fprintf(stderr, "AWTView InputMethod Selector Called : [hasMarkedText]\n"); 941 #endif // IM_DEBUG 942 943 if (!fInputMethodLOCKABLE) { 944 return NO; 945 } 946 947 static JNF_MEMBER_CACHE(jf_fCurrentText, jc_CInputMethod, "fCurrentText", "Ljava/text/AttributedString;"); 948 static JNF_MEMBER_CACHE(jf_fCurrentTextLength, jc_CInputMethod, "fCurrentTextLength", "I"); 949 JNIEnv *env = [ThreadUtilities getJNIEnv]; 950 jobject currentText = JNFGetObjectField(env, fInputMethodLOCKABLE, jf_fCurrentText); 951 952 jint currentTextLength = JNFGetIntField(env, fInputMethodLOCKABLE, jf_fCurrentTextLength); 953 954 BOOL hasMarkedText = (currentText != NULL && currentTextLength > 0); 955 956 if (currentText != NULL) { 957 (*env)->DeleteLocalRef(env, currentText); 958 } 959 960 return hasMarkedText; 961 } 962 963 - (NSInteger) conversationIdentifier 964 { 965 #ifdef IM_DEBUG 966 fprintf(stderr, "AWTView InputMethod Selector Called : [conversationIdentifier]\n"); 967 #endif // IM_DEBUG 968 969 return (NSInteger) self; 970 } 971 972 /* Returns attributed string at the range. This allows input mangers to 973 query any range in backing-store (Andy's request) 974 */ 975 - (NSAttributedString *) attributedSubstringForProposedRange:(NSRange)theRange actualRange:(NSRangePointer)actualRange 976 { 977 #ifdef IM_DEBUG 978 fprintf(stderr, "AWTView InputMethod Selector Called : [attributedSubstringFromRange] location=%lu, length=%lu\n", (unsigned long)theRange.location, (unsigned long)theRange.length); 979 #endif // IM_DEBUG 980 981 static JNF_MEMBER_CACHE(jm_substringFromRange, jc_CInputMethod, "attributedSubstringFromRange", "(II)Ljava/lang/String;"); 982 JNIEnv *env = [ThreadUtilities getJNIEnv]; 983 jobject theString = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_substringFromRange, theRange.location, theRange.length); // AWT_THREADING Safe (AWTRunLoopMode) 984 985 id result = [[[NSAttributedString alloc] initWithString:JNFJavaToNSString(env, theString)] autorelease]; 986 #ifdef IM_DEBUG 987 NSLog(@"attributedSubstringFromRange returning \"%@\"", result); 988 #endif // IM_DEBUG 989 990 (*env)->DeleteLocalRef(env, theString); 991 return result; 992 } 993 994 /* This method returns the range for marked region. If hasMarkedText == false, 995 it'll return NSNotFound location & 0 length range. 996 */ 997 - (NSRange) markedRange 998 { 999 1000 #ifdef IM_DEBUG 1001 fprintf(stderr, "AWTView InputMethod Selector Called : [markedRange]\n"); 1002 #endif // IM_DEBUG 1003 1004 if (!fInputMethodLOCKABLE) { 1005 return NSMakeRange(NSNotFound, 0); 1006 } 1007 1008 static JNF_MEMBER_CACHE(jm_markedRange, jc_CInputMethod, "markedRange", "()[I"); 1009 JNIEnv *env = [ThreadUtilities getJNIEnv]; 1010 jarray array; 1011 jboolean isCopy; 1012 jint *_array; 1013 NSRange range; 1014 1015 array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_markedRange); // AWT_THREADING Safe (AWTRunLoopMode) 1016 1017 if (array) { 1018 _array = (*env)->GetIntArrayElements(env, array, &isCopy); 1019 range = NSMakeRange(_array[0], _array[1]); 1020 1021 #ifdef IM_DEBUG 1022 fprintf(stderr, "markedRange returning (%lu, %lu)\n", (unsigned long)range.location, (unsigned long)range.length); 1023 #endif // IM_DEBUG 1024 (*env)->ReleaseIntArrayElements(env, array, _array, 0); 1025 (*env)->DeleteLocalRef(env, array); 1026 } else { 1027 range = NSMakeRange(NSNotFound, 0); 1028 } 1029 1030 return range; 1031 } 1032 1033 /* This method returns the range for selected region. Just like markedRange method, 1034 its location field contains char index from the text beginning. 1035 */ 1036 - (NSRange) selectedRange 1037 { 1038 if (!fInputMethodLOCKABLE) { 1039 return NSMakeRange(NSNotFound, 0); 1040 } 1041 1042 static JNF_MEMBER_CACHE(jm_selectedRange, jc_CInputMethod, "selectedRange", "()[I"); 1043 JNIEnv *env = [ThreadUtilities getJNIEnv]; 1044 jarray array; 1045 jboolean isCopy; 1046 jint *_array; 1047 NSRange range; 1048 1049 #ifdef IM_DEBUG 1050 fprintf(stderr, "AWTView InputMethod Selector Called : [selectedRange]\n"); 1051 #endif // IM_DEBUG 1052 1053 array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_selectedRange); // AWT_THREADING Safe (AWTRunLoopMode) 1054 if (array) { 1055 _array = (*env)->GetIntArrayElements(env, array, &isCopy); 1056 range = NSMakeRange(_array[0], _array[1]); 1057 (*env)->ReleaseIntArrayElements(env, array, _array, 0); 1058 (*env)->DeleteLocalRef(env, array); 1059 } else { 1060 range = NSMakeRange(NSNotFound, 0); 1061 } 1062 1063 return range; 1064 1065 } 1066 1067 /* This method returns the first frame of rects for theRange in screen coordindate system. 1068 */ 1069 - (NSRect) firstRectForCharacterRange:(NSRange)theRange actualRange:(NSRangePointer)actualRange 1070 { 1071 if (!fInputMethodLOCKABLE) { 1072 return NSMakeRect(0, 0, 0, 0); 1073 } 1074 1075 static JNF_MEMBER_CACHE(jm_firstRectForCharacterRange, jc_CInputMethod, 1076 "firstRectForCharacterRange", "(I)[I"); 1077 JNIEnv *env = [ThreadUtilities getJNIEnv]; 1078 jarray array; 1079 jboolean isCopy; 1080 jint *_array; 1081 NSRect rect; 1082 1083 #ifdef IM_DEBUG 1084 fprintf(stderr, "AWTView InputMethod Selector Called : [firstRectForCharacterRange:] location=%lu, length=%lu\n", (unsigned long)theRange.location, (unsigned long)theRange.length); 1085 #endif // IM_DEBUG 1086 1087 array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_firstRectForCharacterRange, theRange.location); // AWT_THREADING Safe (AWTRunLoopMode) 1088 1089 _array = (*env)->GetIntArrayElements(env, array, &isCopy); 1090 rect = ConvertNSScreenRect(env, NSMakeRect(_array[0], _array[1], _array[2], _array[3])); 1091 (*env)->ReleaseIntArrayElements(env, array, _array, 0); 1092 (*env)->DeleteLocalRef(env, array); 1093 1094 #ifdef IM_DEBUG 1095 fprintf(stderr, "firstRectForCharacterRange returning x=%f, y=%f, width=%f, height=%f\n", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); 1096 #endif // IM_DEBUG 1097 return rect; 1098 } 1099 1100 /* This method returns the index for character that is nearest to thePoint. thPoint is in 1101 screen coordinate system. 1102 */ 1103 - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint 1104 { 1105 if (!fInputMethodLOCKABLE) { 1106 return NSNotFound; 1107 } 1108 1109 static JNF_MEMBER_CACHE(jm_characterIndexForPoint, jc_CInputMethod, 1110 "characterIndexForPoint", "(II)I"); 1111 JNIEnv *env = [ThreadUtilities getJNIEnv]; 1112 1113 NSPoint flippedLocation = ConvertNSScreenPoint(env, thePoint); 1114 1115 #ifdef IM_DEBUG 1116 fprintf(stderr, "AWTView InputMethod Selector Called : [characterIndexForPoint:(NSPoint)thePoint] x=%f, y=%f\n", flippedLocation.x, flippedLocation.y); 1117 #endif // IM_DEBUG 1118 1119 jint index = JNFCallIntMethod(env, fInputMethodLOCKABLE, jm_characterIndexForPoint, (jint)flippedLocation.x, (jint)flippedLocation.y); // AWT_THREADING Safe (AWTRunLoopMode) 1120 1121 #ifdef IM_DEBUG 1122 fprintf(stderr, "characterIndexForPoint returning %ld\n", index); 1123 #endif // IM_DEBUG 1124 1125 if (index == -1) { 1126 return NSNotFound; 1127 } else { 1128 return (NSUInteger)index; 1129 } 1130 } 1131 1132 - (NSArray*) validAttributesForMarkedText 1133 { 1134 #ifdef IM_DEBUG 1135 fprintf(stderr, "AWTView InputMethod Selector Called : [validAttributesForMarkedText]\n"); 1136 #endif // IM_DEBUG 1137 1138 return [NSArray array]; 1139 } 1140 1141 - (void)setInputMethod:(jobject)inputMethod 1142 { 1143 #ifdef IM_DEBUG 1144 fprintf(stderr, "AWTView InputMethod Selector Called : [setInputMethod]\n"); 1145 #endif // IM_DEBUG 1146 1147 JNIEnv *env = [ThreadUtilities getJNIEnv]; 1148 1149 // Get rid of the old one 1150 if (fInputMethodLOCKABLE) { 1151 JNFDeleteGlobalRef(env, fInputMethodLOCKABLE); 1152 } 1153 1154 // Save a global ref to the new input method. 1155 if (inputMethod != NULL) 1156 fInputMethodLOCKABLE = JNFNewGlobalRef(env, inputMethod); 1157 else 1158 fInputMethodLOCKABLE = NULL; 1159 } 1160 1161 - (void)abandonInput 1162 { 1163 #ifdef IM_DEBUG 1164 fprintf(stderr, "AWTView InputMethod Selector Called : [abandonInput]\n"); 1165 #endif // IM_DEBUG 1166 1167 [ThreadUtilities performOnMainThread:@selector(markedTextAbandoned:) onObject:[NSInputManager currentInputManager] withObject:self waitUntilDone:YES awtMode:YES]; 1168 [self unmarkText]; 1169 } 1170 1171 /******************************** END NSTextInputClient Protocol ********************************/ 1172 1173 1174 1175 1176 @end // AWTView 1177 1178 /* 1179 * Class: sun_lwawt_macosx_CPlatformView 1180 * Method: nativeCreateView 1181 * Signature: (IIII)J 1182 */ 1183 JNIEXPORT jlong JNICALL 1184 Java_sun_lwawt_macosx_CPlatformView_nativeCreateView 1185 (JNIEnv *env, jobject obj, jint originX, jint originY, jint width, jint height, jlong windowLayerPtr) 1186 { 1187 __block AWTView *newView = nil; 1188 1189 JNF_COCOA_ENTER(env); 1190 AWT_ASSERT_NOT_APPKIT_THREAD; 1191 1192 NSRect rect = NSMakeRect(originX, originY, width, height); 1193 jobject cPlatformView = (*env)->NewGlobalRef(env, obj); 1194 1195 [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ 1196 AWT_ASSERT_APPKIT_THREAD; 1197 1198 CALayer *windowLayer = jlong_to_ptr(windowLayerPtr); 1199 AWTView *view = [[AWTView alloc] initWithRect:rect 1200 platformView:cPlatformView 1201 windowLayer:windowLayer]; 1202 CFRetain(view); 1203 [view release]; // GC 1204 1205 newView = view; 1206 }]; 1207 1208 JNF_COCOA_EXIT(env); 1209 1210 return ptr_to_jlong(newView); 1211 }