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