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