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