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