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