40 import java.awt.im.spi.InputMethodContext;
41 import sun.awt.im.InputMethodAdapter;
42 import java.awt.event.InputEvent;
43 import java.awt.event.KeyEvent;
44 import java.awt.event.MouseEvent;
45 import java.awt.event.FocusEvent;
46 import java.awt.event.ComponentEvent;
47 import java.awt.event.WindowEvent;
48 import java.awt.event.InputMethodEvent;
49 import java.awt.font.TextAttribute;
50 import java.awt.font.TextHitInfo;
51 import java.awt.peer.ComponentPeer;
52 import java.lang.Character.Subset;
53 import java.text.AttributedString;
54 import java.text.AttributedCharacterIterator;
55
56 import java.io.File;
57 import java.io.FileReader;
58 import java.io.BufferedReader;
59 import java.io.IOException;
60 import sun.util.logging.PlatformLogger;
61 import java.util.StringTokenizer;
62 import java.util.regex.Pattern;
63
64
65 /**
66 * Input Method Adapter for XIM
67 *
68 * @author JavaSoft International
69 */
70 public abstract class X11InputMethod extends InputMethodAdapter {
71 private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11InputMethod");
72 /*
73 * The following XIM* values must be the same as those defined in
74 * Xlib.h
75 */
76 private static final int XIMReverse = (1<<0);
77 private static final int XIMUnderline = (1<<1);
78 private static final int XIMHighlight = (1<<2);
79 private static final int XIMPrimary = (1<<5);
87 private static final int XIMVisibleToBackward = (1<<9);
88 private static final int XIMVisibleCenter = (1<<10);
89 private static final int XIMVisibleMask = (XIMVisibleToForward|
90 XIMVisibleToBackward|
91 XIMVisibleCenter);
92
93 private Locale locale;
94 private static boolean isXIMOpened = false;
95 protected Container clientComponentWindow = null;
96 private Component awtFocussedComponent = null;
97 private Component lastXICFocussedComponent = null;
98 private boolean isLastXICActive = false;
99 private boolean isLastTemporary = false;
100 private boolean isActive = false;
101 private boolean isActiveClient = false;
102 private static Map[] highlightStyles;
103 private boolean disposed = false;
104
105 //reset the XIC if necessary
106 private boolean needResetXIC = false;
107 private Component needResetXICClient = null;
108
109 // The use of compositionEnableSupported is to reduce unnecessary
110 // native calls if set/isCompositionEnabled
111 // throws UnsupportedOperationException.
112 // It is set to false if that exception is thrown first time
113 // either of the two methods are called.
114 private boolean compositionEnableSupported = true;
115 // The savedCompositionState indicates the composition mode when
116 // endComposition or setCompositionEnabled is called. It doesn't always
117 // reflect the actual composition state because it doesn't get updated
118 // when the user changes the composition state through direct interaction
119 // with the input method. It is used to save the composition mode when
120 // focus is traversed across different client components sharing the
121 // same java input context. Also if set/isCompositionEnabled are not
122 // supported, it remains false.
123 private boolean savedCompositionState = false;
124
125 // variables to keep track of preedit context.
126 // these variables need to be accessed within AWT_LOCK/UNLOCK
127 private String committedText = null;
255 public void setCharacterSubsets(Subset[] subsets) {
256 }
257
258 /**
259 * Dispatch event to input method. InputContext dispatch event with this
260 * method. Input method set consume flag if event is consumed in
261 * input method.
262 *
263 * @param e event
264 */
265 public void dispatchEvent(AWTEvent e) {
266 }
267
268
269 protected final void resetXICifneeded(){
270 /* needResetXIC is used to indicate whether to call
271 resetXIC on the active client. resetXIC will always be
272 called on the passive client when endComposition is called.
273 */
274 if (needResetXIC && haveActiveClient() &&
275 getClientComponent() != needResetXICClient){
276 resetXIC();
277
278 // needs to reset the last xic focussed component.
279 lastXICFocussedComponent = null;
280 isLastXICActive = false;
281
282 needResetXICClient = null;
283 needResetXIC = false;
284 }
285 }
286
287 /**
288 * Reset the composition state to the current composition state.
289 */
290 private void resetCompositionState() {
291 if (compositionEnableSupported) {
292 try {
293 /* Restore the composition mode to the last saved composition
294 mode. */
295 setCompositionEnabled(savedCompositionState);
296 } catch (UnsupportedOperationException e) {
297 compositionEnableSupported = false;
298 }
299 }
300 }
301
302 /**
400 /* Delay resetting the XIC focus until activate is called and the newly
401 focussed component has a different peer as the last focussed component.
402 */
403 lastXICFocussedComponent = awtFocussedComponent;
404 isLastXICActive = isAc;
405 isLastTemporary = isTemporary;
406 isActive = false;
407 }
408
409 /**
410 * Explicitly disable the native IME. Native IME is not disabled when
411 * deactivate is called.
412 */
413 public void disableInputMethod() {
414 if (lastXICFocussedComponent != null) {
415 setXICFocus(getPeer(lastXICFocussedComponent), false, isLastXICActive);
416 lastXICFocussedComponent = null;
417 isLastXICActive = false;
418
419 resetXIC();
420 needResetXICClient = null;
421 needResetXIC = false;
422 }
423 }
424
425 // implements java.awt.im.spi.InputMethod.hideWindows
426 public void hideWindows() {
427 // ??? need real implementation
428 }
429
430 /**
431 * @see java.awt.Toolkit#mapInputMethodHighlight
432 */
433 public static Map mapInputMethodHighlight(InputMethodHighlight highlight) {
434 int index;
435 int state = highlight.getState();
436 if (state == InputMethodHighlight.RAW_TEXT) {
437 index = 0;
438 } else if (state == InputMethodHighlight.CONVERTED_TEXT) {
439 index = 2;
440 } else {
461 setXICFocus(getPeer(component), true, ac);
462 }
463 awtFocussedComponent = component;
464 }
465
466 /**
467 * @see sun.awt.im.InputMethodAdapter#stopListening
468 */
469 protected void stopListening() {
470 // It is desirable to disable XIM by calling XSetICValues with
471 // XNPreeditState == XIMPreeditDisable. But Solaris 2.6 and
472 // Solaris 7 do not implement this correctly without a patch,
473 // so just call resetXIC here. Prior endComposition call commits
474 // the existing composed text.
475 endComposition();
476 // disable the native input method so that the other input
477 // method could get the input focus.
478 disableInputMethod();
479 if (needResetXIC) {
480 resetXIC();
481 needResetXICClient = null;
482 needResetXIC = false;
483 }
484 }
485
486 /**
487 * Returns the Window instance in which the client component is
488 * contained. If not found, null is returned. (IS THIS POSSIBLE?)
489 */
490 // NOTE: This method may be called by privileged threads.
491 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
492 private Window getClientComponentWindow() {
493 Component client = getClientComponent();
494 Container container;
495
496 if (client instanceof Container) {
497 container = (Container) client;
498 } else {
499 container = getParent(client);
500 }
501
860 * are communicated to the active component using an input method event.
861 *
862 * <p>
863 * A text editing component may call this in a variety of situations,
864 * for example, when the user moves the insertion point within the text
865 * (but outside the composed text), or when the component's text is
866 * saved to a file or copied to the clipboard.
867 *
868 */
869 public void endComposition() {
870 if (disposed) {
871 return;
872 }
873
874 /* Before calling resetXIC, record the current composition mode
875 so that it can be restored later. */
876 savedCompositionState = getCompositionState();
877 boolean active = haveActiveClient();
878 if (active && composedText == null && committedText == null){
879 needResetXIC = true;
880 needResetXICClient = getClientComponent();
881 return;
882 }
883
884 String text = resetXIC();
885 /* needResetXIC is only set to true for active client. So passive
886 client should not reset the flag to false. */
887 if (active) {
888 needResetXIC = false;
889 }
890
891 // Remove any existing composed text by posting an InputMethodEvent
892 // with null composed text. It would be desirable to wait for a
893 // dispatchComposedText call from X input method engine, but some
894 // input method does not conform to the XIM specification and does
895 // not call the preedit callback to erase preedit text on calling
896 // XmbResetIC. To work around this problem, do it here by ourselves.
897 awtLock();
898 composedText = null;
899 postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
900 null,
|
40 import java.awt.im.spi.InputMethodContext;
41 import sun.awt.im.InputMethodAdapter;
42 import java.awt.event.InputEvent;
43 import java.awt.event.KeyEvent;
44 import java.awt.event.MouseEvent;
45 import java.awt.event.FocusEvent;
46 import java.awt.event.ComponentEvent;
47 import java.awt.event.WindowEvent;
48 import java.awt.event.InputMethodEvent;
49 import java.awt.font.TextAttribute;
50 import java.awt.font.TextHitInfo;
51 import java.awt.peer.ComponentPeer;
52 import java.lang.Character.Subset;
53 import java.text.AttributedString;
54 import java.text.AttributedCharacterIterator;
55
56 import java.io.File;
57 import java.io.FileReader;
58 import java.io.BufferedReader;
59 import java.io.IOException;
60 import java.lang.ref.WeakReference;
61 import sun.util.logging.PlatformLogger;
62 import java.util.StringTokenizer;
63 import java.util.regex.Pattern;
64
65
66 /**
67 * Input Method Adapter for XIM
68 *
69 * @author JavaSoft International
70 */
71 public abstract class X11InputMethod extends InputMethodAdapter {
72 private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11InputMethod");
73 /*
74 * The following XIM* values must be the same as those defined in
75 * Xlib.h
76 */
77 private static final int XIMReverse = (1<<0);
78 private static final int XIMUnderline = (1<<1);
79 private static final int XIMHighlight = (1<<2);
80 private static final int XIMPrimary = (1<<5);
88 private static final int XIMVisibleToBackward = (1<<9);
89 private static final int XIMVisibleCenter = (1<<10);
90 private static final int XIMVisibleMask = (XIMVisibleToForward|
91 XIMVisibleToBackward|
92 XIMVisibleCenter);
93
94 private Locale locale;
95 private static boolean isXIMOpened = false;
96 protected Container clientComponentWindow = null;
97 private Component awtFocussedComponent = null;
98 private Component lastXICFocussedComponent = null;
99 private boolean isLastXICActive = false;
100 private boolean isLastTemporary = false;
101 private boolean isActive = false;
102 private boolean isActiveClient = false;
103 private static Map[] highlightStyles;
104 private boolean disposed = false;
105
106 //reset the XIC if necessary
107 private boolean needResetXIC = false;
108 private WeakReference<Component> needResetXICClient = new WeakReference<>(null);
109
110 // The use of compositionEnableSupported is to reduce unnecessary
111 // native calls if set/isCompositionEnabled
112 // throws UnsupportedOperationException.
113 // It is set to false if that exception is thrown first time
114 // either of the two methods are called.
115 private boolean compositionEnableSupported = true;
116 // The savedCompositionState indicates the composition mode when
117 // endComposition or setCompositionEnabled is called. It doesn't always
118 // reflect the actual composition state because it doesn't get updated
119 // when the user changes the composition state through direct interaction
120 // with the input method. It is used to save the composition mode when
121 // focus is traversed across different client components sharing the
122 // same java input context. Also if set/isCompositionEnabled are not
123 // supported, it remains false.
124 private boolean savedCompositionState = false;
125
126 // variables to keep track of preedit context.
127 // these variables need to be accessed within AWT_LOCK/UNLOCK
128 private String committedText = null;
256 public void setCharacterSubsets(Subset[] subsets) {
257 }
258
259 /**
260 * Dispatch event to input method. InputContext dispatch event with this
261 * method. Input method set consume flag if event is consumed in
262 * input method.
263 *
264 * @param e event
265 */
266 public void dispatchEvent(AWTEvent e) {
267 }
268
269
270 protected final void resetXICifneeded(){
271 /* needResetXIC is used to indicate whether to call
272 resetXIC on the active client. resetXIC will always be
273 called on the passive client when endComposition is called.
274 */
275 if (needResetXIC && haveActiveClient() &&
276 getClientComponent() != needResetXICClient.get()){
277 resetXIC();
278
279 // needs to reset the last xic focussed component.
280 lastXICFocussedComponent = null;
281 isLastXICActive = false;
282
283 needResetXICClient.clear();
284 needResetXIC = false;
285 }
286 }
287
288 /**
289 * Reset the composition state to the current composition state.
290 */
291 private void resetCompositionState() {
292 if (compositionEnableSupported) {
293 try {
294 /* Restore the composition mode to the last saved composition
295 mode. */
296 setCompositionEnabled(savedCompositionState);
297 } catch (UnsupportedOperationException e) {
298 compositionEnableSupported = false;
299 }
300 }
301 }
302
303 /**
401 /* Delay resetting the XIC focus until activate is called and the newly
402 focussed component has a different peer as the last focussed component.
403 */
404 lastXICFocussedComponent = awtFocussedComponent;
405 isLastXICActive = isAc;
406 isLastTemporary = isTemporary;
407 isActive = false;
408 }
409
410 /**
411 * Explicitly disable the native IME. Native IME is not disabled when
412 * deactivate is called.
413 */
414 public void disableInputMethod() {
415 if (lastXICFocussedComponent != null) {
416 setXICFocus(getPeer(lastXICFocussedComponent), false, isLastXICActive);
417 lastXICFocussedComponent = null;
418 isLastXICActive = false;
419
420 resetXIC();
421 needResetXICClient.clear();
422 needResetXIC = false;
423 }
424 }
425
426 // implements java.awt.im.spi.InputMethod.hideWindows
427 public void hideWindows() {
428 // ??? need real implementation
429 }
430
431 /**
432 * @see java.awt.Toolkit#mapInputMethodHighlight
433 */
434 public static Map mapInputMethodHighlight(InputMethodHighlight highlight) {
435 int index;
436 int state = highlight.getState();
437 if (state == InputMethodHighlight.RAW_TEXT) {
438 index = 0;
439 } else if (state == InputMethodHighlight.CONVERTED_TEXT) {
440 index = 2;
441 } else {
462 setXICFocus(getPeer(component), true, ac);
463 }
464 awtFocussedComponent = component;
465 }
466
467 /**
468 * @see sun.awt.im.InputMethodAdapter#stopListening
469 */
470 protected void stopListening() {
471 // It is desirable to disable XIM by calling XSetICValues with
472 // XNPreeditState == XIMPreeditDisable. But Solaris 2.6 and
473 // Solaris 7 do not implement this correctly without a patch,
474 // so just call resetXIC here. Prior endComposition call commits
475 // the existing composed text.
476 endComposition();
477 // disable the native input method so that the other input
478 // method could get the input focus.
479 disableInputMethod();
480 if (needResetXIC) {
481 resetXIC();
482 needResetXICClient.clear();
483 needResetXIC = false;
484 }
485 }
486
487 /**
488 * Returns the Window instance in which the client component is
489 * contained. If not found, null is returned. (IS THIS POSSIBLE?)
490 */
491 // NOTE: This method may be called by privileged threads.
492 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
493 private Window getClientComponentWindow() {
494 Component client = getClientComponent();
495 Container container;
496
497 if (client instanceof Container) {
498 container = (Container) client;
499 } else {
500 container = getParent(client);
501 }
502
861 * are communicated to the active component using an input method event.
862 *
863 * <p>
864 * A text editing component may call this in a variety of situations,
865 * for example, when the user moves the insertion point within the text
866 * (but outside the composed text), or when the component's text is
867 * saved to a file or copied to the clipboard.
868 *
869 */
870 public void endComposition() {
871 if (disposed) {
872 return;
873 }
874
875 /* Before calling resetXIC, record the current composition mode
876 so that it can be restored later. */
877 savedCompositionState = getCompositionState();
878 boolean active = haveActiveClient();
879 if (active && composedText == null && committedText == null){
880 needResetXIC = true;
881 needResetXICClient = new WeakReference<>(getClientComponent());
882 return;
883 }
884
885 String text = resetXIC();
886 /* needResetXIC is only set to true for active client. So passive
887 client should not reset the flag to false. */
888 if (active) {
889 needResetXIC = false;
890 }
891
892 // Remove any existing composed text by posting an InputMethodEvent
893 // with null composed text. It would be desirable to wait for a
894 // dispatchComposedText call from X input method engine, but some
895 // input method does not conform to the XIM specification and does
896 // not call the preedit callback to erase preedit text on calling
897 // XmbResetIC. To work around this problem, do it here by ourselves.
898 awtLock();
899 composedText = null;
900 postInputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
901 null,
|