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