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