annotate src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m @ 14038:bef17930c9ae

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