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