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