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