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