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