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