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