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) resetCursorRects { 366 [super resetCursorRects]; 367 [self resetTrackingRect]; 368 } 369 370 -(void) deliverJavaKeyEventHelper: (NSEvent *) event { 371 [AWTToolkit eventCountPlusPlus]; 372 JNIEnv *env = [ThreadUtilities getJNIEnv]; 373 374 jstring characters = NULL; 375 if ([event type] != NSFlagsChanged) { 376 characters = JNFNSToJavaString(env, [event characters]); 377 } 378 379 static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/event/NSEvent"); 380 static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IISLjava/lang/String;)V"); 381 jobject jevent = JNFNewObject(env, jctor_NSEvent, 382 [event type], 383 [event modifierFlags], 384 [event keyCode], 385 characters); 386 387 static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); 388 static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView, 389 "deliverKeyEvent", "(Lsun/lwawt/macosx/event/NSEvent;)V"); 390 JNFCallVoidMethod(env, m_cPlatformView, jm_deliverKeyEvent, jevent); 391 392 if (characters != NULL) { 393 (*env)->DeleteLocalRef(env, characters); 394 } 395 } 396 397 - (void) drawRect:(NSRect)dirtyRect { 398 AWT_ASSERT_APPKIT_THREAD; 399 400 [super drawRect:dirtyRect]; 401 JNIEnv *env = [ThreadUtilities getJNIEnv]; 402 if (env != NULL) { 403 /* 404 if ([self inLiveResize]) { 405 NSRect rs[4]; 406 NSInteger count; 407 [self getRectsExposedDuringLiveResize:rs count:&count]; 408 for (int i = 0; i < count; i++) { 409 JNU_CallMethodByName(env, NULL, [m_awtWindow cPlatformView], 410 "deliverWindowDidExposeEvent", "(FFFF)V", 411 (jfloat)rs[i].origin.x, (jfloat)rs[i].origin.y, 412 (jfloat)rs[i].size.width, (jfloat)rs[i].size.height); 413 if ((*env)->ExceptionOccurred(env)) { 414 (*env)->ExceptionDescribe(env); 415 (*env)->ExceptionClear(env); 416 } 417 } 418 } else { 419 */ 420 static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView"); 421 static JNF_MEMBER_CACHE(jm_deliverWindowDidExposeEvent, jc_CPlatformView, "deliverWindowDidExposeEvent", "()V"); 422 JNFCallVoidMethod(env, m_cPlatformView, jm_deliverWindowDidExposeEvent); 423 /* 424 } 425 */ 426 } 427 } 428 429 // NSAccessibility support 430 - (jobject)awtComponent:(JNIEnv*)env 431 { 432 static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView"); 433 static JNF_MEMBER_CACHE(jf_Peer, jc_CPlatformView, "peer", "Lsun/lwawt/LWWindowPeer;"); 434 if ((env == NULL) || (m_cPlatformView == NULL)) { 435 NSLog(@"Apple AWT : Error AWTView:awtComponent given bad parameters."); 436 if (env != NULL) 437 { 438 JNFDumpJavaStack(env); 439 } 440 return NULL; 441 } 442 jobject peer = JNFGetObjectField(env, m_cPlatformView, jf_Peer); 443 static JNF_CLASS_CACHE(jc_LWWindowPeer, "sun/lwawt/LWWindowPeer"); 444 static JNF_MEMBER_CACHE(jf_Target, jc_LWWindowPeer, "target", "Ljava/awt/Component;"); 445 if (peer == NULL) { 446 NSLog(@"Apple AWT : Error AWTView:awtComponent got null peer from CPlatformView"); 447 JNFDumpJavaStack(env); 448 return NULL; 449 } 450 return JNFGetObjectField(env, peer, jf_Target); 451 } 452 453 - (id)getAxData:(JNIEnv*)env 454 { 455 return [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:[self awtComponent:env] withIndex:-1 withView:self withJavaRole:nil] autorelease]; 456 } 457 458 - (NSArray *)accessibilityAttributeNames 459 { 460 return [[super accessibilityAttributeNames] arrayByAddingObject:NSAccessibilityChildrenAttribute]; 461 } 462 463 // NSAccessibility messages 464 // attribute methods 465 - (id)accessibilityAttributeValue:(NSString *)attribute 466 { 467 AWT_ASSERT_APPKIT_THREAD; 468 469 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) 470 { 471 JNIEnv *env = [ThreadUtilities getJNIEnv]; 472 473 (*env)->PushLocalFrame(env, 4); 474 475 id result = NSAccessibilityUnignoredChildrenForOnlyChild([self getAxData:env]); 476 477 (*env)->PopLocalFrame(env, NULL); 478 479 return result; 480 } 481 else 482 { 483 return [super accessibilityAttributeValue:attribute]; 484 } 485 } 486 - (BOOL)accessibilityIsIgnored 487 { 488 return YES; 489 } 490 491 - (id)accessibilityHitTest:(NSPoint)point 492 { 493 AWT_ASSERT_APPKIT_THREAD; 494 JNIEnv *env = [ThreadUtilities getJNIEnv]; 495 496 (*env)->PushLocalFrame(env, 4); 497 498 id result = [[self getAxData:env] accessibilityHitTest:point withEnv:env]; 499 500 (*env)->PopLocalFrame(env, NULL); 501 502 return result; 503 } 504 505 - (id)accessibilityFocusedUIElement 506 { 507 AWT_ASSERT_APPKIT_THREAD; 508 509 JNIEnv *env = [ThreadUtilities getJNIEnv]; 510 511 (*env)->PushLocalFrame(env, 4); 512 513 id result = [[self getAxData:env] accessibilityFocusedUIElement]; 514 515 (*env)->PopLocalFrame(env, NULL); 516 517 return result; 518 } 519 520 // --- Services menu support for lightweights --- 521 522 // finds the focused accessable element, and if it's a text element, obtains the text from it 523 - (NSString *)accessibleSelectedText 524 { 525 id focused = [self accessibilityFocusedUIElement]; 526 if (![focused isKindOfClass:[JavaTextAccessibility class]]) return nil; 527 return [(JavaTextAccessibility *)focused accessibilitySelectedTextAttribute]; 528 } 529 530 // same as above, but converts to RTFD 531 - (NSData *)accessibleSelectedTextAsRTFD 532 { 533 NSString *selectedText = [self accessibleSelectedText]; 534 NSAttributedString *styledText = [[NSAttributedString alloc] initWithString:selectedText]; 535 NSData *rtfdData = [styledText RTFDFromRange:NSMakeRange(0, [styledText length]) documentAttributes:nil]; 536 [styledText release]; 537 return rtfdData; 538 } 539 540 // finds the focused accessable element, and if it's a text element, sets the text in it 541 - (BOOL)replaceAccessibleTextSelection:(NSString *)text 542 { 543 id focused = [self accessibilityFocusedUIElement]; 544 if (![focused isKindOfClass:[JavaTextAccessibility class]]) return NO; 545 [(JavaTextAccessibility *)focused accessibilitySetSelectedTextAttribute:text]; 546 return YES; 547 } 548 549 // called for each service in the Services menu - only handle text for now 550 - (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType 551 { 552 if ([[self window] firstResponder] != self) return nil; // let AWT components handle themselves 553 554 if ([sendType isEqual:NSStringPboardType] || [returnType isEqual:NSStringPboardType]) { 555 NSString *selectedText = [self accessibleSelectedText]; 556 if (selectedText) return self; 557 } 558 559 return nil; 560 } 561 562 // fetch text from Java and hand off to the service 563 - (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard types:(NSArray *)types 564 { 565 if ([types containsObject:NSStringPboardType]) 566 { 567 [pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; 568 return [pboard setString:[self accessibleSelectedText] forType:NSStringPboardType]; 569 } 570 571 if ([types containsObject:NSRTFDPboardType]) 572 { 573 [pboard declareTypes:[NSArray arrayWithObject:NSRTFDPboardType] owner:nil]; 574 return [pboard setData:[self accessibleSelectedTextAsRTFD] forType:NSRTFDPboardType]; 575 } 576 577 return NO; 578 } 579 580 // write text back to Java from the service 581 - (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard 582 { 583 if ([[pboard types] containsObject:NSStringPboardType]) 584 { 585 NSString *text = [pboard stringForType:NSStringPboardType]; 586 return [self replaceAccessibleTextSelection:text]; 587 } 588 589 if ([[pboard types] containsObject:NSRTFDPboardType]) 590 { 591 NSData *rtfdData = [pboard dataForType:NSRTFDPboardType]; 592 NSAttributedString *styledText = [[NSAttributedString alloc] initWithRTFD:rtfdData documentAttributes:nil]; 593 NSString *text = [styledText string]; 594 [styledText release]; 595 596 return [self replaceAccessibleTextSelection:text]; 597 } 598 599 return NO; 600 } 601 602 603 -(void) setDragSource:(CDragSource *)source { 604 self._dragSource = source; 605 } 606 607 608 - (void) setDropTarget:(CDropTarget *)target { 609 self._dropTarget = target; 610 [ThreadUtilities performOnMainThread:@selector(controlModelControlValid) onObject:self._dropTarget withObject:nil waitUntilDone:YES awtMode:YES]; 611 } 612 613 /******************************** BEGIN NSDraggingSource Interface ********************************/ 614 615 - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)flag 616 { 617 // If draggingSource is nil route the message to the superclass (if responding to the selector): 618 CDragSource *dragSource = self._dragSource; 619 NSDragOperation dragOp = NSDragOperationNone; 620 621 if (dragSource != nil) 622 dragOp = [dragSource draggingSourceOperationMaskForLocal:flag]; 623 else if ([super respondsToSelector:@selector(draggingSourceOperationMaskForLocal:)]) 624 dragOp = [super draggingSourceOperationMaskForLocal:flag]; 625 626 return dragOp; 627 } 628 629 - (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination 630 { 631 // If draggingSource is nil route the message to the superclass (if responding to the selector): 632 CDragSource *dragSource = self._dragSource; 633 NSArray* array = nil; 634 635 if (dragSource != nil) 636 array = [dragSource namesOfPromisedFilesDroppedAtDestination:dropDestination]; 637 else if ([super respondsToSelector:@selector(namesOfPromisedFilesDroppedAtDestination:)]) 638 array = [super namesOfPromisedFilesDroppedAtDestination:dropDestination]; 639 640 return array; 641 } 642 643 - (void)draggedImage:(NSImage *)image beganAt:(NSPoint)screenPoint 644 { 645 // If draggingSource is nil route the message to the superclass (if responding to the selector): 646 CDragSource *dragSource = self._dragSource; 647 648 if (dragSource != nil) 649 [dragSource draggedImage:image beganAt:screenPoint]; 650 else if ([super respondsToSelector:@selector(draggedImage::)]) 651 [super draggedImage:image beganAt:screenPoint]; 652 } 653 654 - (void)draggedImage:(NSImage *)image endedAt:(NSPoint)screenPoint operation:(NSDragOperation)operation 655 { 656 // If draggingSource is nil route the message to the superclass (if responding to the selector): 657 CDragSource *dragSource = self._dragSource; 658 659 if (dragSource != nil) 660 [dragSource draggedImage:image endedAt:screenPoint operation:operation]; 661 else if ([super respondsToSelector:@selector(draggedImage:::)]) 662 [super draggedImage:image endedAt:screenPoint operation:operation]; 663 } 664 665 - (void)draggedImage:(NSImage *)image movedTo:(NSPoint)screenPoint 666 { 667 // If draggingSource is nil route the message to the superclass (if responding to the selector): 668 CDragSource *dragSource = self._dragSource; 669 670 if (dragSource != nil) 671 [dragSource draggedImage:image movedTo:screenPoint]; 672 else if ([super respondsToSelector:@selector(draggedImage::)]) 673 [super draggedImage:image movedTo:screenPoint]; 674 } 675 676 - (BOOL)ignoreModifierKeysWhileDragging 677 { 678 // If draggingSource is nil route the message to the superclass (if responding to the selector): 679 CDragSource *dragSource = self._dragSource; 680 BOOL result = FALSE; 681 682 if (dragSource != nil) 683 result = [dragSource ignoreModifierKeysWhileDragging]; 684 else if ([super respondsToSelector:@selector(ignoreModifierKeysWhileDragging)]) 685 result = [super ignoreModifierKeysWhileDragging]; 686 687 return result; 688 } 689 690 /******************************** END NSDraggingSource Interface ********************************/ 691 692 /******************************** BEGIN NSDraggingDestination Interface ********************************/ 693 694 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender 695 { 696 // If draggingDestination is nil route the message to the superclass: 697 CDropTarget *dropTarget = self._dropTarget; 698 NSDragOperation dragOp = NSDragOperationNone; 699 700 if (dropTarget != nil) 701 dragOp = [dropTarget draggingEntered:sender]; 702 else if ([super respondsToSelector:@selector(draggingEntered:)]) 703 dragOp = [super draggingEntered:sender]; 704 705 return dragOp; 706 } 707 708 - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender 709 { 710 // If draggingDestination is nil route the message to the superclass: 711 CDropTarget *dropTarget = self._dropTarget; 712 NSDragOperation dragOp = NSDragOperationNone; 713 714 if (dropTarget != nil) 715 dragOp = [dropTarget draggingUpdated:sender]; 716 else if ([super respondsToSelector:@selector(draggingUpdated:)]) 717 dragOp = [super draggingUpdated:sender]; 718 719 return dragOp; 720 } 721 722 - (void)draggingExited:(id <NSDraggingInfo>)sender 723 { 724 // If draggingDestination is nil route the message to the superclass: 725 CDropTarget *dropTarget = self._dropTarget; 726 727 if (dropTarget != nil) 728 [dropTarget draggingExited:sender]; 729 else if ([super respondsToSelector:@selector(draggingExited:)]) 730 [super draggingExited:sender]; 731 } 732 733 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender 734 { 735 // If draggingDestination is nil route the message to the superclass: 736 CDropTarget *dropTarget = self._dropTarget; 737 BOOL result = FALSE; 738 739 if (dropTarget != nil) 740 result = [dropTarget prepareForDragOperation:sender]; 741 else if ([super respondsToSelector:@selector(prepareForDragOperation:)]) 742 result = [super prepareForDragOperation:sender]; 743 744 return result; 745 } 746 747 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender 748 { 749 // If draggingDestination is nil route the message to the superclass: 750 CDropTarget *dropTarget = self._dropTarget; 751 BOOL result = FALSE; 752 753 if (dropTarget != nil) 754 result = [dropTarget performDragOperation:sender]; 755 else if ([super respondsToSelector:@selector(performDragOperation:)]) 756 result = [super performDragOperation:sender]; 757 758 return result; 759 } 760 761 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender 762 { 763 // If draggingDestination is nil route the message to the superclass: 764 CDropTarget *dropTarget = self._dropTarget; 765 766 if (dropTarget != nil) 767 [dropTarget concludeDragOperation:sender]; 768 else if ([super respondsToSelector:@selector(concludeDragOperation:)]) 769 [super concludeDragOperation:sender]; 770 } 771 772 - (void)draggingEnded:(id <NSDraggingInfo>)sender 773 { 774 // If draggingDestination is nil route the message to the superclass: 775 CDropTarget *dropTarget = self._dropTarget; 776 777 if (dropTarget != nil) 778 [dropTarget draggingEnded:sender]; 779 else if ([super respondsToSelector:@selector(draggingEnded:)]) 780 [super draggingEnded:sender]; 781 } 782 783 /******************************** END NSDraggingDestination Interface ********************************/ 784 785 /******************************** BEGIN NSTextInputClient Protocol ********************************/ 786 787 788 JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); 789 790 - (void) insertText:(id)aString replacementRange:(NSRange)replacementRange 791 { 792 #ifdef IM_DEBUG 793 fprintf(stderr, "AWTView InputMethod Selector Called : [insertText]: %s\n", [aString UTF8String]); 794 #endif // IM_DEBUG 795 796 if (fInputMethodLOCKABLE == NULL) { 797 return; 798 } 799 800 // Insert happens at the end of PAH 801 fInPressAndHold = NO; 802 803 // insertText gets called when the user commits text generated from an input method. It also gets 804 // called during ordinary input as well. We only need to send an input method event when we have marked 805 // text, or 'text in progress'. We also need to send the event if we get an insert text out of the blue! 806 // (i.e., when the user uses the Character palette or Inkwell), or when the string to insert is a complex 807 // Unicode value. 808 NSUInteger utf8Length = [aString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; 809 810 if ([self hasMarkedText] || !fProcessingKeystroke || (utf8Length > 2)) { 811 JNIEnv *env = [ThreadUtilities getJNIEnv]; 812 813 static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V"); 814 // We need to select the previous glyph so that it is overwritten. 815 if (fPAHNeedsToSelect) { 816 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph); 817 fPAHNeedsToSelect = NO; 818 } 819 820 static JNF_MEMBER_CACHE(jm_insertText, jc_CInputMethod, "insertText", "(Ljava/lang/String;)V"); 821 jstring insertedText = JNFNSToJavaString(env, aString); 822 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_insertText, insertedText); // AWT_THREADING Safe (AWTRunLoopMode) 823 (*env)->DeleteLocalRef(env, insertedText); 824 825 // The input method event will create psuedo-key events for each character in the committed string. 826 // We also don't want to send the character that triggered the insertText, usually a return. [3337563] 827 fKeyEventsNeeded = NO; 828 } 829 830 fPAHNeedsToSelect = NO; 831 832 } 833 834 - (void) doCommandBySelector:(SEL)aSelector 835 { 836 #ifdef IM_DEBUG 837 fprintf(stderr, "AWTView InputMethod Selector Called : [doCommandBySelector]\n"); 838 NSLog(@"%@", NSStringFromSelector(aSelector)); 839 #endif // IM_DEBUG 840 if (@selector(insertNewline:) == aSelector || @selector(insertTab:) == aSelector || @selector(deleteBackward:) == aSelector) 841 { 842 fKeyEventsNeeded = YES; 843 } 844 } 845 846 // setMarkedText: cannot take a nil first argument. aString can be NSString or NSAttributedString 847 - (void) setMarkedText:(id)aString selectedRange:(NSRange)selectionRange replacementRange:(NSRange)replacementRange 848 { 849 if (!fInputMethodLOCKABLE) 850 return; 851 852 BOOL isAttributedString = [aString isKindOfClass:[NSAttributedString class]]; 853 NSAttributedString *attrString = (isAttributedString ? (NSAttributedString *)aString : nil); 854 NSString *incomingString = (isAttributedString ? [aString string] : aString); 855 #ifdef IM_DEBUG 856 fprintf(stderr, "AWTView InputMethod Selector Called : [setMarkedText] \"%s\", loc=%lu, length=%lu\n", [incomingString UTF8String], (unsigned long)selectionRange.location, (unsigned long)selectionRange.length); 857 #endif // IM_DEBUG 858 static JNF_MEMBER_CACHE(jm_startIMUpdate, jc_CInputMethod, "startIMUpdate", "(Ljava/lang/String;)V"); 859 static JNF_MEMBER_CACHE(jm_addAttribute, jc_CInputMethod, "addAttribute", "(ZZII)V"); 860 static JNF_MEMBER_CACHE(jm_dispatchText, jc_CInputMethod, "dispatchText", "(IIZ)V"); 861 JNIEnv *env = [ThreadUtilities getJNIEnv]; 862 863 // NSInputContext already did the analysis of the TSM event and created attributes indicating 864 // the underlining and color that should be done to the string. We need to look at the underline 865 // style and color to determine what kind of Java hilighting needs to be done. 866 jstring inProcessText = JNFNSToJavaString(env, incomingString); 867 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_startIMUpdate, inProcessText); // AWT_THREADING Safe (AWTRunLoopMode) 868 (*env)->DeleteLocalRef(env, inProcessText); 869 870 if (isAttributedString) { 871 NSUInteger length; 872 NSRange effectiveRange; 873 NSDictionary *attributes; 874 length = [attrString length]; 875 effectiveRange = NSMakeRange(0, 0); 876 while (NSMaxRange(effectiveRange) < length) { 877 attributes = [attrString attributesAtIndex:NSMaxRange(effectiveRange) 878 effectiveRange:&effectiveRange]; 879 if (attributes) { 880 BOOL isThickUnderline, isGray; 881 NSNumber *underlineSizeObj = 882 (NSNumber *)[attributes objectForKey:NSUnderlineStyleAttributeName]; 883 NSInteger underlineSize = [underlineSizeObj integerValue]; 884 isThickUnderline = (underlineSize > 1); 885 886 NSColor *underlineColorObj = 887 (NSColor *)[attributes objectForKey:NSUnderlineColorAttributeName]; 888 isGray = !([underlineColorObj isEqual:[NSColor blackColor]]); 889 890 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_addAttribute, isThickUnderline, isGray, effectiveRange.location, effectiveRange.length); // AWT_THREADING Safe (AWTRunLoopMode) 891 } 892 } 893 } 894 895 static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V"); 896 // We need to select the previous glyph so that it is overwritten. 897 if (fPAHNeedsToSelect) { 898 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph); 899 fPAHNeedsToSelect = NO; 900 } 901 902 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_dispatchText, selectionRange.location, selectionRange.length, JNI_FALSE); // AWT_THREADING Safe (AWTRunLoopMode) 903 904 // If the marked text is being cleared (zero-length string) don't handle the key event. 905 if ([incomingString length] == 0) { 906 fKeyEventsNeeded = NO; 907 } 908 } 909 910 - (void) unmarkText 911 { 912 #ifdef IM_DEBUG 913 fprintf(stderr, "AWTView InputMethod Selector Called : [unmarkText]\n"); 914 #endif // IM_DEBUG 915 916 if (!fInputMethodLOCKABLE) { 917 return; 918 } 919 920 // unmarkText cancels any input in progress and commits it to the text field. 921 static JNF_MEMBER_CACHE(jm_unmarkText, jc_CInputMethod, "unmarkText", "()V"); 922 JNIEnv *env = [ThreadUtilities getJNIEnv]; 923 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_unmarkText); // AWT_THREADING Safe (AWTRunLoopMode) 924 925 } 926 927 - (BOOL) hasMarkedText 928 { 929 #ifdef IM_DEBUG 930 fprintf(stderr, "AWTView InputMethod Selector Called : [hasMarkedText]\n"); 931 #endif // IM_DEBUG 932 933 if (!fInputMethodLOCKABLE) { 934 return NO; 935 } 936 937 static JNF_MEMBER_CACHE(jf_fCurrentText, jc_CInputMethod, "fCurrentText", "Ljava/text/AttributedString;"); 938 static JNF_MEMBER_CACHE(jf_fCurrentTextLength, jc_CInputMethod, "fCurrentTextLength", "I"); 939 JNIEnv *env = [ThreadUtilities getJNIEnv]; 940 jobject currentText = JNFGetObjectField(env, fInputMethodLOCKABLE, jf_fCurrentText); 941 942 jint currentTextLength = JNFGetIntField(env, fInputMethodLOCKABLE, jf_fCurrentTextLength); 943 944 BOOL hasMarkedText = (currentText != NULL && currentTextLength > 0); 945 946 if (currentText != NULL) { 947 (*env)->DeleteLocalRef(env, currentText); 948 } 949 950 return hasMarkedText; 951 } 952 953 - (NSInteger) conversationIdentifier 954 { 955 #ifdef IM_DEBUG 956 fprintf(stderr, "AWTView InputMethod Selector Called : [conversationIdentifier]\n"); 957 #endif // IM_DEBUG 958 959 return (NSInteger) self; 960 } 961 962 /* Returns attributed string at the range. This allows input mangers to 963 query any range in backing-store (Andy's request) 964 */ 965 - (NSAttributedString *) attributedSubstringForProposedRange:(NSRange)theRange actualRange:(NSRangePointer)actualRange 966 { 967 #ifdef IM_DEBUG 968 fprintf(stderr, "AWTView InputMethod Selector Called : [attributedSubstringFromRange] location=%lu, length=%lu\n", (unsigned long)theRange.location, (unsigned long)theRange.length); 969 #endif // IM_DEBUG 970 971 static JNF_MEMBER_CACHE(jm_substringFromRange, jc_CInputMethod, "attributedSubstringFromRange", "(II)Ljava/lang/String;"); 972 JNIEnv *env = [ThreadUtilities getJNIEnv]; 973 jobject theString = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_substringFromRange, theRange.location, theRange.length); // AWT_THREADING Safe (AWTRunLoopMode) 974 975 id result = [[[NSAttributedString alloc] initWithString:JNFJavaToNSString(env, theString)] autorelease]; 976 #ifdef IM_DEBUG 977 NSLog(@"attributedSubstringFromRange returning \"%@\"", result); 978 #endif // IM_DEBUG 979 980 (*env)->DeleteLocalRef(env, theString); 981 return result; 982 } 983 984 /* This method returns the range for marked region. If hasMarkedText == false, 985 it'll return NSNotFound location & 0 length range. 986 */ 987 - (NSRange) markedRange 988 { 989 990 #ifdef IM_DEBUG 991 fprintf(stderr, "AWTView InputMethod Selector Called : [markedRange]\n"); 992 #endif // IM_DEBUG 993 994 if (!fInputMethodLOCKABLE) { 995 return NSMakeRange(NSNotFound, 0); 996 } 997 998 static JNF_MEMBER_CACHE(jm_markedRange, jc_CInputMethod, "markedRange", "()[I"); 999 JNIEnv *env = [ThreadUtilities getJNIEnv]; 1000 jarray array; 1001 jboolean isCopy; 1002 jint *_array; 1003 NSRange range; 1004 1005 array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_markedRange); // AWT_THREADING Safe (AWTRunLoopMode) 1006 1007 if (array) { 1008 _array = (*env)->GetIntArrayElements(env, array, &isCopy); 1009 range = NSMakeRange(_array[0], _array[1]); 1010 1011 #ifdef IM_DEBUG 1012 fprintf(stderr, "markedRange returning (%lu, %lu)\n", (unsigned long)range.location, (unsigned long)range.length); 1013 #endif // IM_DEBUG 1014 (*env)->ReleaseIntArrayElements(env, array, _array, 0); 1015 (*env)->DeleteLocalRef(env, array); 1016 } else { 1017 range = NSMakeRange(NSNotFound, 0); 1018 } 1019 1020 return range; 1021 } 1022 1023 /* This method returns the range for selected region. Just like markedRange method, 1024 its location field contains char index from the text beginning. 1025 */ 1026 - (NSRange) selectedRange 1027 { 1028 if (!fInputMethodLOCKABLE) { 1029 return NSMakeRange(NSNotFound, 0); 1030 } 1031 1032 static JNF_MEMBER_CACHE(jm_selectedRange, jc_CInputMethod, "selectedRange", "()[I"); 1033 JNIEnv *env = [ThreadUtilities getJNIEnv]; 1034 jarray array; 1035 jboolean isCopy; 1036 jint *_array; 1037 NSRange range; 1038 1039 #ifdef IM_DEBUG 1040 fprintf(stderr, "AWTView InputMethod Selector Called : [selectedRange]\n"); 1041 #endif // IM_DEBUG 1042 1043 array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_selectedRange); // AWT_THREADING Safe (AWTRunLoopMode) 1044 if (array) { 1045 _array = (*env)->GetIntArrayElements(env, array, &isCopy); 1046 range = NSMakeRange(_array[0], _array[1]); 1047 (*env)->ReleaseIntArrayElements(env, array, _array, 0); 1048 (*env)->DeleteLocalRef(env, array); 1049 } else { 1050 range = NSMakeRange(NSNotFound, 0); 1051 } 1052 1053 return range; 1054 1055 } 1056 1057 /* This method returns the first frame of rects for theRange in screen coordindate system. 1058 */ 1059 - (NSRect) firstRectForCharacterRange:(NSRange)theRange actualRange:(NSRangePointer)actualRange 1060 { 1061 if (!fInputMethodLOCKABLE) { 1062 return NSMakeRect(0, 0, 0, 0); 1063 } 1064 1065 static JNF_MEMBER_CACHE(jm_firstRectForCharacterRange, jc_CInputMethod, 1066 "firstRectForCharacterRange", "(I)[I"); 1067 JNIEnv *env = [ThreadUtilities getJNIEnv]; 1068 jarray array; 1069 jboolean isCopy; 1070 jint *_array; 1071 NSRect rect; 1072 1073 #ifdef IM_DEBUG 1074 fprintf(stderr, "AWTView InputMethod Selector Called : [firstRectForCharacterRange:] location=%lu, length=%lu\n", (unsigned long)theRange.location, (unsigned long)theRange.length); 1075 #endif // IM_DEBUG 1076 1077 array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_firstRectForCharacterRange, theRange.location); // AWT_THREADING Safe (AWTRunLoopMode) 1078 1079 _array = (*env)->GetIntArrayElements(env, array, &isCopy); 1080 rect = ConvertNSScreenRect(env, NSMakeRect(_array[0], _array[1], _array[2], _array[3])); 1081 (*env)->ReleaseIntArrayElements(env, array, _array, 0); 1082 (*env)->DeleteLocalRef(env, array); 1083 1084 #ifdef IM_DEBUG 1085 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); 1086 #endif // IM_DEBUG 1087 return rect; 1088 } 1089 1090 /* This method returns the index for character that is nearest to thePoint. thPoint is in 1091 screen coordinate system. 1092 */ 1093 - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint 1094 { 1095 if (!fInputMethodLOCKABLE) { 1096 return NSNotFound; 1097 } 1098 1099 static JNF_MEMBER_CACHE(jm_characterIndexForPoint, jc_CInputMethod, 1100 "characterIndexForPoint", "(II)I"); 1101 JNIEnv *env = [ThreadUtilities getJNIEnv]; 1102 1103 NSPoint flippedLocation = ConvertNSScreenPoint(env, thePoint); 1104 1105 #ifdef IM_DEBUG 1106 fprintf(stderr, "AWTView InputMethod Selector Called : [characterIndexForPoint:(NSPoint)thePoint] x=%f, y=%f\n", flippedLocation.x, flippedLocation.y); 1107 #endif // IM_DEBUG 1108 1109 jint index = JNFCallIntMethod(env, fInputMethodLOCKABLE, jm_characterIndexForPoint, (jint)flippedLocation.x, (jint)flippedLocation.y); // AWT_THREADING Safe (AWTRunLoopMode) 1110 1111 #ifdef IM_DEBUG 1112 fprintf(stderr, "characterIndexForPoint returning %ld\n", index); 1113 #endif // IM_DEBUG 1114 1115 if (index == -1) { 1116 return NSNotFound; 1117 } else { 1118 return (NSUInteger)index; 1119 } 1120 } 1121 1122 - (NSArray*) validAttributesForMarkedText 1123 { 1124 #ifdef IM_DEBUG 1125 fprintf(stderr, "AWTView InputMethod Selector Called : [validAttributesForMarkedText]\n"); 1126 #endif // IM_DEBUG 1127 1128 return [NSArray array]; 1129 } 1130 1131 - (void)setInputMethod:(jobject)inputMethod 1132 { 1133 #ifdef IM_DEBUG 1134 fprintf(stderr, "AWTView InputMethod Selector Called : [setInputMethod]\n"); 1135 #endif // IM_DEBUG 1136 1137 JNIEnv *env = [ThreadUtilities getJNIEnv]; 1138 1139 // Get rid of the old one 1140 if (fInputMethodLOCKABLE) { 1141 JNFDeleteGlobalRef(env, fInputMethodLOCKABLE); 1142 } 1143 1144 // Save a global ref to the new input method. 1145 if (inputMethod != NULL) 1146 fInputMethodLOCKABLE = JNFNewGlobalRef(env, inputMethod); 1147 else 1148 fInputMethodLOCKABLE = NULL; 1149 } 1150 1151 - (void)abandonInput 1152 { 1153 #ifdef IM_DEBUG 1154 fprintf(stderr, "AWTView InputMethod Selector Called : [abandonInput]\n"); 1155 #endif // IM_DEBUG 1156 1157 [ThreadUtilities performOnMainThread:@selector(markedTextAbandoned:) onObject:[NSInputManager currentInputManager] withObject:self waitUntilDone:YES awtMode:YES]; 1158 [self unmarkText]; 1159 } 1160 1161 /******************************** END NSTextInputClient Protocol ********************************/ 1162 1163 1164 1165 1166 @end // AWTView 1167 1168 /* 1169 * Class: sun_lwawt_macosx_CPlatformView 1170 * Method: nativeCreateView 1171 * Signature: (IIII)J 1172 */ 1173 JNIEXPORT jlong JNICALL 1174 Java_sun_lwawt_macosx_CPlatformView_nativeCreateView 1175 (JNIEnv *env, jobject obj, jint originX, jint originY, jint width, jint height, jlong windowLayerPtr) 1176 { 1177 __block AWTView *newView = nil; 1178 1179 JNF_COCOA_ENTER(env); 1180 AWT_ASSERT_NOT_APPKIT_THREAD; 1181 1182 NSRect rect = NSMakeRect(originX, originY, width, height); 1183 jobject cPlatformView = (*env)->NewGlobalRef(env, obj); 1184 1185 [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ 1186 AWT_ASSERT_APPKIT_THREAD; 1187 1188 CALayer *windowLayer = jlong_to_ptr(windowLayerPtr); 1189 AWTView *view = [[AWTView alloc] initWithRect:rect 1190 platformView:cPlatformView 1191 windowLayer:windowLayer]; 1192 CFRetain(view); 1193 [view release]; // GC 1194 1195 newView = view; 1196 }]; 1197 1198 JNF_COCOA_EXIT(env); 1199 1200 return ptr_to_jlong(newView); 1201 }