annotate src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m @ 17695:7d3e0c5b5e25

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