Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/unix/classes/sun/awt/X11InputMethodBase.java
41152 views
1
/*
2
* Copyright (c) 1997, 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
package sun.awt;
27
28
import java.awt.AWTEvent;
29
import java.awt.AWTException;
30
import java.awt.Component;
31
import java.awt.Container;
32
import java.awt.EventQueue;
33
import java.awt.Window;
34
import java.awt.event.InputMethodEvent;
35
import java.awt.font.TextAttribute;
36
import java.awt.font.TextHitInfo;
37
import java.awt.im.InputMethodHighlight;
38
import java.awt.im.spi.InputMethodContext;
39
import java.awt.peer.ComponentPeer;
40
import java.io.BufferedReader;
41
import java.io.File;
42
import java.io.FileReader;
43
import java.io.IOException;
44
import java.lang.Character.Subset;
45
import java.lang.ref.WeakReference;
46
import java.text.AttributedCharacterIterator;
47
import java.text.AttributedString;
48
import java.util.Collections;
49
import java.util.HashMap;
50
import java.util.Locale;
51
import java.util.Map;
52
import java.util.StringTokenizer;
53
import java.util.regex.Pattern;
54
55
import sun.awt.im.InputMethodAdapter;
56
import sun.util.logging.PlatformLogger;
57
58
/**
59
* Input Method Adapter for XIM
60
*
61
* @author JavaSoft International
62
*/
63
public abstract class X11InputMethodBase extends InputMethodAdapter {
64
protected static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11InputMethod");
65
/*
66
* The following XIM* values must be the same as those defined in
67
* Xlib.h
68
*/
69
private static final int XIMReverse = (1<<0);
70
private static final int XIMUnderline = (1<<1);
71
private static final int XIMHighlight = (1<<2);
72
private static final int XIMPrimary = (1<<5);
73
private static final int XIMSecondary = (1<<6);
74
private static final int XIMTertiary = (1<<7);
75
76
/*
77
* visible position values
78
*/
79
protected static final int XIMVisibleToForward = (1<<8);
80
protected static final int XIMVisibleToBackward = (1<<9);
81
protected static final int XIMVisibleCenter = (1<<10);
82
protected static final int XIMVisibleMask =
83
(XIMVisibleToForward | XIMVisibleToBackward | XIMVisibleCenter);
84
85
private Locale locale;
86
private static boolean isXIMOpened = false;
87
protected Container clientComponentWindow = null;
88
protected Component awtFocussedComponent = null;
89
protected Component lastXICFocussedComponent = null;
90
protected boolean isLastXICActive = false;
91
protected boolean isLastTemporary = false;
92
protected boolean isActive = false;
93
private static Map<TextAttribute, ?>[] highlightStyles;
94
protected boolean disposed = false;
95
96
//reset the XIC if necessary
97
protected boolean needResetXIC = false;
98
private WeakReference<Component> needResetXICClient = new WeakReference<>(null);
99
100
// The use of compositionEnableSupported is to reduce unnecessary
101
// native calls if set/isCompositionEnabled
102
// throws UnsupportedOperationException.
103
// It is set to false if that exception is thrown first time
104
// either of the two methods are called.
105
protected boolean compositionEnableSupported = true;
106
// The savedCompositionState indicates the composition mode when
107
// endComposition or setCompositionEnabled is called. It doesn't always
108
// reflect the actual composition state because it doesn't get updated
109
// when the user changes the composition state through direct interaction
110
// with the input method. It is used to save the composition mode when
111
// focus is traversed across different client components sharing the
112
// same java input context. Also if set/isCompositionEnabled are not
113
// supported, it remains false.
114
protected boolean savedCompositionState = false;
115
116
// variables to keep track of preedit context.
117
// these variables need to be accessed within AWT_LOCK/UNLOCK
118
protected String committedText = null;
119
protected StringBuffer composedText = null;
120
protected IntBuffer rawFeedbacks;
121
122
// private data (X11InputMethodData structure defined in
123
// awt_InputMethod.c) for native methods
124
// this structure needs to be accessed within AWT_LOCK/UNLOCK
125
protected transient long pData = 0; // accessed by native
126
127
// Initialize highlight mapping table
128
static {
129
@SuppressWarnings({"unchecked", "rawtypes"})
130
Map<TextAttribute, ?>[] styles = new Map[4];
131
HashMap<TextAttribute, Object> map;
132
133
// UNSELECTED_RAW_TEXT_HIGHLIGHT
134
map = new HashMap<>(1);
135
map.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
136
styles[0] = Collections.unmodifiableMap(map);
137
138
// SELECTED_RAW_TEXT_HIGHLIGHT
139
map = new HashMap<>(1);
140
map.put(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON);
141
styles[1] = Collections.unmodifiableMap(map);
142
143
// UNSELECTED_CONVERTED_TEXT_HIGHLIGHT
144
map = new HashMap<>(1);
145
map.put(TextAttribute.INPUT_METHOD_UNDERLINE,
146
TextAttribute.UNDERLINE_LOW_ONE_PIXEL);
147
styles[2] = Collections.unmodifiableMap(map);
148
149
// SELECTED_CONVERTED_TEXT_HIGHLIGHT
150
map = new HashMap<>(1);
151
map.put(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON);
152
styles[3] = Collections.unmodifiableMap(map);
153
154
highlightStyles = styles;
155
}
156
157
static {
158
initIDs();
159
}
160
161
/**
162
* Constructs an X11InputMethod instance. It initializes the XIM
163
* environment if it's not done yet.
164
*
165
* @exception AWTException if XOpenIM() failed.
166
*/
167
public X11InputMethodBase() throws AWTException {
168
// supports only the locale in which the VM is started
169
locale = X11InputMethodDescriptor.getSupportedLocale();
170
if (initXIM() == false) {
171
throw new AWTException("Cannot open X Input Method");
172
}
173
}
174
175
@SuppressWarnings("deprecation")
176
protected void finalize() throws Throwable {
177
dispose();
178
super.finalize();
179
}
180
181
/**
182
* Invokes openIM() that invokes XOpenIM() if it's not opened yet.
183
* @return true if openXIM() is successful or it's already been opened.
184
*/
185
private synchronized boolean initXIM() {
186
if (isXIMOpened == false)
187
isXIMOpened = openXIM();
188
return isXIMOpened;
189
}
190
191
protected abstract boolean openXIM();
192
193
protected boolean isDisposed() {
194
return disposed;
195
}
196
197
protected abstract void setXICFocus(ComponentPeer peer,
198
boolean value, boolean active);
199
200
/**
201
* Does nothing - this adapter doesn't use the input method context.
202
*
203
* @see java.awt.im.spi.InputMethod#setInputMethodContext
204
*/
205
public void setInputMethodContext(InputMethodContext context) {
206
}
207
208
/**
209
* Set locale to input. If input method doesn't support specified locale,
210
* false will be returned and its behavior is not changed.
211
*
212
* @param lang locale to input
213
* @return the true is returned when specified locale is supported.
214
*/
215
public boolean setLocale(Locale lang) {
216
if (lang.equals(locale)) {
217
return true;
218
}
219
// special compatibility rule for Japanese and Korean
220
if (locale.equals(Locale.JAPAN) && lang.equals(Locale.JAPANESE) ||
221
locale.equals(Locale.KOREA) && lang.equals(Locale.KOREAN)) {
222
return true;
223
}
224
return false;
225
}
226
227
/**
228
* Returns current input locale.
229
*/
230
public Locale getLocale() {
231
return locale;
232
}
233
234
/**
235
* Does nothing - XIM doesn't let you specify which characters you expect.
236
*
237
* @see java.awt.im.spi.InputMethod#setCharacterSubsets
238
*/
239
public void setCharacterSubsets(Subset[] subsets) {
240
}
241
242
/**
243
* Dispatch event to input method. InputContext dispatch event with this
244
* method. Input method set consume flag if event is consumed in
245
* input method.
246
*
247
* @param e event
248
*/
249
public void dispatchEvent(AWTEvent e) {
250
}
251
252
protected final void resetXICifneeded(){
253
/* needResetXIC is used to indicate whether to call
254
resetXIC on the active client. resetXIC will always be
255
called on the passive client when endComposition is called.
256
*/
257
if (needResetXIC && haveActiveClient() &&
258
getClientComponent() != needResetXICClient.get()){
259
resetXIC();
260
261
// needs to reset the last xic focussed component.
262
lastXICFocussedComponent = null;
263
isLastXICActive = false;
264
265
needResetXICClient.clear();
266
needResetXIC = false;
267
}
268
}
269
270
/**
271
* Reset the composition state to the current composition state.
272
*/
273
protected abstract void resetCompositionState();
274
275
/**
276
* Query and then return the current composition state.
277
* @return the composition state if isCompositionEnabled call
278
* is successful. Otherwise, it returns false.
279
*/
280
protected boolean getCompositionState() {
281
boolean compositionState = false;
282
if (compositionEnableSupported) {
283
try {
284
compositionState = isCompositionEnabled();
285
} catch (UnsupportedOperationException e) {
286
compositionEnableSupported = false;
287
}
288
}
289
return compositionState;
290
}
291
292
/**
293
* Activate input method.
294
*/
295
public abstract void activate();
296
297
protected abstract boolean createXIC();
298
299
/**
300
* Deactivate input method.
301
*/
302
public abstract void deactivate(boolean isTemporary);
303
304
/**
305
* Explicitly disable the native IME. Native IME is not disabled when
306
* deactivate is called.
307
*/
308
public void disableInputMethod() {
309
if (lastXICFocussedComponent != null) {
310
setXICFocus(getPeer(lastXICFocussedComponent), false, isLastXICActive);
311
lastXICFocussedComponent = null;
312
isLastXICActive = false;
313
314
resetXIC();
315
needResetXICClient.clear();
316
needResetXIC = false;
317
}
318
}
319
320
// implements java.awt.im.spi.InputMethod.hideWindows
321
public abstract void hideWindows();
322
323
/**
324
* @see java.awt.Toolkit#mapInputMethodHighlight
325
*/
326
public static Map<TextAttribute, ?> mapInputMethodHighlight(InputMethodHighlight highlight) {
327
int index;
328
int state = highlight.getState();
329
if (state == InputMethodHighlight.RAW_TEXT) {
330
index = 0;
331
} else if (state == InputMethodHighlight.CONVERTED_TEXT) {
332
index = 2;
333
} else {
334
return null;
335
}
336
if (highlight.isSelected()) {
337
index += 1;
338
}
339
return highlightStyles[index];
340
}
341
342
/**
343
* @see sun.awt.im.InputMethodAdapter#setAWTFocussedComponent
344
*/
345
protected void setAWTFocussedComponent(Component component) {
346
if (component == null) {
347
return;
348
}
349
if (isActive) {
350
// deactivate/activate are being suppressed during a focus change -
351
// this may happen when an input method window is made visible
352
boolean ac = haveActiveClient();
353
setXICFocus(getPeer(awtFocussedComponent), false, ac);
354
setXICFocus(getPeer(component), true, ac);
355
}
356
awtFocussedComponent = component;
357
}
358
359
/**
360
* @see sun.awt.im.InputMethodAdapter#stopListening
361
*/
362
protected void stopListening() {
363
// It is desirable to disable XIM by calling XSetICValues with
364
// XNPreeditState == XIMPreeditDisable. But Solaris 2.6 and
365
// Solaris 7 do not implement this correctly without a patch,
366
// so just call resetXIC here. Prior endComposition call commits
367
// the existing composed text.
368
endComposition();
369
// disable the native input method so that the other input
370
// method could get the input focus.
371
disableInputMethod();
372
if (needResetXIC) {
373
resetXIC();
374
needResetXICClient.clear();
375
needResetXIC = false;
376
}
377
}
378
379
/**
380
* Returns the Window instance in which the client component is
381
* contained. If not found, null is returned. (IS THIS POSSIBLE?)
382
*/
383
// NOTE: This method may be called by privileged threads.
384
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
385
protected Window getClientComponentWindow() {
386
Component client = getClientComponent();
387
Container container;
388
389
if (client instanceof Container) {
390
container = (Container) client;
391
} else {
392
container = getParent(client);
393
}
394
395
while (container != null && !(container instanceof java.awt.Window)) {
396
container = getParent(container);
397
}
398
return (Window) container;
399
}
400
401
protected abstract Container getParent(Component client);
402
403
/**
404
* Returns peer of the given client component. If the given client component
405
* doesn't have peer, peer of the native container of the client is returned.
406
*/
407
protected abstract ComponentPeer getPeer(Component client);
408
409
/**
410
* Used to protect preedit data
411
*/
412
protected abstract void awtLock();
413
protected abstract void awtUnlock();
414
415
/**
416
* Creates an input method event from the arguments given
417
* and posts it on the AWT event queue. For arguments,
418
* see InputMethodEvent. Called by input method.
419
*
420
* @see java.awt.event.InputMethodEvent#InputMethodEvent
421
*/
422
protected void postInputMethodEvent(int id,
423
AttributedCharacterIterator text,
424
int committedCharacterCount,
425
TextHitInfo caret,
426
TextHitInfo visiblePosition,
427
long when) {
428
Component source = getClientComponent();
429
if (source != null) {
430
InputMethodEvent event = new InputMethodEvent(source,
431
id, when, text, committedCharacterCount, caret, visiblePosition);
432
SunToolkit.postEvent(SunToolkit.targetToAppContext(source), (AWTEvent)event);
433
}
434
}
435
436
private void postInputMethodEvent(int id,
437
AttributedCharacterIterator text,
438
int committedCharacterCount,
439
TextHitInfo caret,
440
TextHitInfo visiblePosition) {
441
postInputMethodEvent(id, text, committedCharacterCount,
442
caret, visiblePosition, EventQueue.getMostRecentEventTime());
443
}
444
445
/**
446
* Dispatches committed text from XIM to the awt event queue. This
447
* method is invoked from the event handler in canvas.c in the
448
* AWT Toolkit thread context and thus inside the AWT Lock.
449
* @param str committed text
450
* @param when when
451
*/
452
// NOTE: This method may be called by privileged threads.
453
// This functionality is implemented in a package-private method
454
// to insure that it cannot be overridden by client subclasses.
455
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
456
void dispatchCommittedText(String str, long when) {
457
if (str == null)
458
return;
459
460
if (composedText == null) {
461
AttributedString attrstr = new AttributedString(str);
462
postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
463
attrstr.getIterator(),
464
str.length(),
465
null,
466
null,
467
when);
468
} else {
469
// if there is composed text, wait until the preedit
470
// callback is invoked.
471
committedText = str;
472
}
473
}
474
475
private void dispatchCommittedText(String str) {
476
dispatchCommittedText(str, EventQueue.getMostRecentEventTime());
477
}
478
479
/**
480
* Updates composed text with XIM preedit information and
481
* posts composed text to the awt event queue. The args of
482
* this method correspond to the XIM preedit callback
483
* information. The XIM highlight attributes are translated via
484
* fixed mapping (i.e., independent from any underlying input
485
* method engine). This method is invoked in the AWT Toolkit
486
* (X event loop) thread context and thus inside the AWT Lock.
487
*/
488
// NOTE: This method may be called by privileged threads.
489
// This functionality is implemented in a package-private method
490
// to insure that it cannot be overridden by client subclasses.
491
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
492
abstract void dispatchComposedText(String chgText,
493
int[] chgStyles,
494
int chgOffset,
495
int chgLength,
496
int caretPosition,
497
long when);
498
499
/**
500
* Flushes composed and committed text held in this context.
501
* This method is invoked in the AWT Toolkit (X event loop) thread context
502
* and thus inside the AWT Lock.
503
*/
504
// NOTE: This method may be called by privileged threads.
505
// This functionality is implemented in a package-private method
506
// to insure that it cannot be overridden by client subclasses.
507
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
508
void flushText() {
509
String flush = (committedText != null ? committedText : "");
510
if (composedText != null) {
511
flush += composedText.toString();
512
}
513
514
if (!flush.isEmpty()) {
515
AttributedString attrstr = new AttributedString(flush);
516
postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
517
attrstr.getIterator(),
518
flush.length(),
519
null,
520
null,
521
EventQueue.getMostRecentEventTime());
522
composedText = null;
523
committedText = null;
524
}
525
}
526
527
/*
528
* Subclasses should override disposeImpl() instead of dispose(). Client
529
* code should always invoke dispose(), never disposeImpl().
530
*/
531
protected abstract void disposeImpl();
532
533
/**
534
* Frees all X Window resources associated with this object.
535
*
536
* @see java.awt.im.spi.InputMethod#dispose
537
*/
538
public final void dispose() {
539
boolean call_disposeImpl = false;
540
541
if (!disposed) {
542
synchronized (this) {
543
if (!disposed) {
544
disposed = call_disposeImpl = true;
545
}
546
}
547
}
548
549
if (call_disposeImpl) {
550
disposeImpl();
551
}
552
}
553
554
/**
555
* Returns null.
556
*
557
* @see java.awt.im.spi.InputMethod#getControlObject
558
*/
559
public Object getControlObject() {
560
return null;
561
}
562
563
/**
564
* @see java.awt.im.spi.InputMethod#removeNotify
565
*/
566
public synchronized void removeNotify() {
567
dispose();
568
}
569
570
/**
571
* @see java.awt.im.spi.InputMethod#setCompositionEnabled(boolean)
572
*/
573
public abstract void setCompositionEnabled(boolean enable);
574
575
/**
576
* @see java.awt.im.spi.InputMethod#isCompositionEnabled
577
*/
578
public boolean isCompositionEnabled() {
579
/* isCompositionEnabledNative may throw UnsupportedOperationException.
580
Don't try to catch it since this method may be called by clients.
581
Use package private method 'getCompositionState' if you want the
582
exception to be caught.
583
*/
584
return isCompositionEnabledNative();
585
}
586
587
/**
588
* Ends any input composition that may currently be going on in this
589
* context. Depending on the platform and possibly user preferences,
590
* this may commit or delete uncommitted text. Any changes to the text
591
* are communicated to the active component using an input method event.
592
*
593
* <p>
594
* A text editing component may call this in a variety of situations,
595
* for example, when the user moves the insertion point within the text
596
* (but outside the composed text), or when the component's text is
597
* saved to a file or copied to the clipboard.
598
*
599
*/
600
public void endComposition() {
601
if (disposed) {
602
return;
603
}
604
605
/* Before calling resetXIC, record the current composition mode
606
so that it can be restored later. */
607
savedCompositionState = getCompositionState();
608
boolean active = haveActiveClient();
609
if (active && composedText == null && committedText == null){
610
needResetXIC = true;
611
needResetXICClient = new WeakReference<>(getClientComponent());
612
return;
613
}
614
615
String text = resetXIC();
616
/* needResetXIC is only set to true for active client. So passive
617
client should not reset the flag to false. */
618
if (active) {
619
needResetXIC = false;
620
}
621
622
// Remove any existing composed text by posting an InputMethodEvent
623
// with null composed text. It would be desirable to wait for a
624
// dispatchComposedText call from X input method engine, but some
625
// input method does not conform to the XIM specification and does
626
// not call the preedit callback to erase preedit text on calling
627
// XmbResetIC. To work around this problem, do it here by ourselves.
628
awtLock();
629
try {
630
composedText = null;
631
postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
632
null,
633
0,
634
null,
635
null);
636
637
if (text != null && text.length() > 0) {
638
dispatchCommittedText(text);
639
}
640
} finally {
641
// Put awtUnlock into finally block in case an exception is thrown.
642
awtUnlock();
643
}
644
645
// Restore the preedit state if it was enabled
646
if (savedCompositionState) {
647
resetCompositionState();
648
}
649
}
650
651
/**
652
* Returns a string with information about the current input method server, or null.
653
* On both Linux & SunOS, the value of environment variable XMODIFIERS is
654
* returned if set. Otherwise, on SunOS, $HOME/.dtprofile will be parsed
655
* to find out the language service engine (atok or wnn) since there is
656
* no API in Xlib which returns the information of native
657
* IM server or language service and we want to try our best to return as much
658
* information as possible.
659
*
660
* Note: This method could return null on Linux if XMODIFIERS is not set properly or
661
* if any IOException is thrown.
662
* See man page of XSetLocaleModifiers(3X11) for the usgae of XMODIFIERS,
663
* atok12setup(1) and wnn6setup(1) for the information written to
664
* $HOME/.dtprofile when you run these two commands.
665
*
666
*/
667
public String getNativeInputMethodInfo() {
668
String xmodifiers = System.getenv("XMODIFIERS");
669
String imInfo = null;
670
671
// If XMODIFIERS is set, return the value
672
if (xmodifiers != null) {
673
int imIndex = xmodifiers.indexOf("@im=");
674
if (imIndex != -1) {
675
imInfo = xmodifiers.substring(imIndex + 4);
676
}
677
}
678
679
return imInfo;
680
}
681
682
683
/**
684
* Performs mapping from an XIM visible feedback value to Java IM highlight.
685
* @return Java input method highlight
686
*/
687
protected InputMethodHighlight convertVisualFeedbackToHighlight(int feedback) {
688
InputMethodHighlight highlight;
689
690
switch (feedback) {
691
case XIMUnderline:
692
highlight = InputMethodHighlight.UNSELECTED_CONVERTED_TEXT_HIGHLIGHT;
693
break;
694
case XIMReverse:
695
highlight = InputMethodHighlight.SELECTED_CONVERTED_TEXT_HIGHLIGHT;
696
break;
697
case XIMHighlight:
698
highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
699
break;
700
case 0: //None of the values are set by Wnn
701
case XIMPrimary:
702
highlight = InputMethodHighlight.UNSELECTED_CONVERTED_TEXT_HIGHLIGHT;
703
break;
704
case XIMSecondary:
705
highlight = InputMethodHighlight.SELECTED_CONVERTED_TEXT_HIGHLIGHT;
706
break;
707
case XIMTertiary:
708
highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
709
break;
710
default:
711
highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
712
break;
713
}
714
return highlight;
715
}
716
717
// initial capacity size for string buffer, etc.
718
protected static final int INITIAL_SIZE = 64;
719
720
/**
721
* IntBuffer is an inner class that manipulates an int array and
722
* provides UNIX file io stream-like programming interfaces to
723
* access it. (An alternative would be to use ArrayList which may
724
* be too expensive for the work.)
725
*/
726
protected final class IntBuffer {
727
private int[] intArray;
728
private int size;
729
private int index;
730
731
IntBuffer(int initialCapacity) {
732
intArray = new int[initialCapacity];
733
size = 0;
734
index = 0;
735
}
736
737
void insert(int offset, int[] values) {
738
int newSize = size + values.length;
739
if (intArray.length < newSize) {
740
int[] newIntArray = new int[newSize * 2];
741
System.arraycopy(intArray, 0, newIntArray, 0, size);
742
intArray = newIntArray;
743
}
744
System.arraycopy(intArray, offset, intArray, offset+values.length,
745
size - offset);
746
System.arraycopy(values, 0, intArray, offset, values.length);
747
size += values.length;
748
if (index > offset)
749
index = offset;
750
}
751
752
void remove(int offset, int length) {
753
if (offset + length != size)
754
System.arraycopy(intArray, offset+length, intArray, offset,
755
size - offset - length);
756
size -= length;
757
if (index > offset)
758
index = offset;
759
}
760
761
void replace(int offset, int[] values) {
762
System.arraycopy(values, 0, intArray, offset, values.length);
763
}
764
765
void removeAll() {
766
size = 0;
767
index = 0;
768
}
769
770
void rewind() {
771
index = 0;
772
}
773
774
int getNext() {
775
if (index == size)
776
return -1;
777
return intArray[index++];
778
}
779
780
void unget() {
781
if (index != 0)
782
index--;
783
}
784
785
int getOffset() {
786
return index;
787
}
788
789
public String toString() {
790
StringBuilder s = new StringBuilder();
791
for (int i = 0; i < size;) {
792
s.append(intArray[i++]);
793
if (i < size)
794
s.append(",");
795
}
796
return s.toString();
797
}
798
}
799
800
/*
801
* Native methods
802
*/
803
804
/**
805
* Initialize JNI field and method IDs for fields that may be
806
* accessed from C.
807
*/
808
private static native void initIDs();
809
810
protected native void turnoffStatusWindow();
811
812
protected native void disposeXIC();
813
814
private native String resetXIC();
815
816
protected native boolean setCompositionEnabledNative(boolean enable);
817
818
private native boolean isCompositionEnabledNative();
819
}
820
821