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