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