src/solaris/classes/sun/awt/X11InputMethod.java

Print this page




  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,