1 /*
   2  * Copyright (c) 2003, 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.X11;
  27 
  28 import java.awt.AWTException;
  29 import java.awt.Component;
  30 import java.awt.Container;
  31 import java.awt.Rectangle;
  32 import java.awt.im.spi.InputMethodContext;
  33 import java.awt.peer.ComponentPeer;
  34 import sun.awt.X11InputMethod;
  35 
  36 import java.util.logging.*;
  37 
  38 /**
  39  * Input Method Adapter for XIM (without Motif)
  40  *
  41  * @author JavaSoft International
  42  */
  43 public class XInputMethod extends X11InputMethod {
  44     private static final Logger log = Logger.getLogger("sun.awt.X11.XInputMethod");
  45 
  46     public XInputMethod() throws AWTException {
  47         super();
  48     }
  49 
  50     public void setInputMethodContext(InputMethodContext context) {
  51         context.enableClientWindowNotification(this, true);
  52     }
  53 
  54     public void notifyClientWindowChange(Rectangle location) {
  55         XComponentPeer peer = (XComponentPeer)getPeer(clientComponentWindow);
  56         if (peer != null) {
  57             adjustStatusWindow(peer.getContentWindow());
  58         }
  59     }
  60 
  61     protected boolean openXIM() {
  62         return openXIMNative(XToolkit.getDisplay());
  63     }
  64 
  65     protected boolean createXIC() {
  66         XComponentPeer peer = (XComponentPeer)getPeer(clientComponentWindow);
  67         if (peer == null) {
  68             return false;
  69         }
  70         return createXICNative(peer.getContentWindow());
  71     }
  72 
  73 
  74     private static volatile long xicFocus = 0;
  75 
  76     protected void setXICFocus(ComponentPeer peer,
  77                                     boolean value, boolean active) {
  78         if (peer == null) {
  79             return;
  80         }
  81         xicFocus = ((XComponentPeer)peer).getContentWindow();
  82         setXICFocusNative(((XComponentPeer)peer).getContentWindow(),
  83                           value,
  84                           active);
  85     }
  86 
  87     public static long getXICFocus() {
  88         return xicFocus;
  89     }
  90 
  91 /* XAWT_HACK  FIX ME!
  92    do NOT call client code!
  93 */
  94     protected Container getParent(Component client) {
  95         return client.getParent();
  96     }
  97 
  98     /**
  99      * Returns peer of the given client component. If the given client component
 100      * doesn't have peer, peer of the native container of the client is returned.
 101      */
 102     protected ComponentPeer getPeer(Component client) {
 103         XComponentPeer peer;
 104 
 105         if (log.isLoggable(Level.FINE)) {
 106             log.fine("Client is " + client);
 107         }
 108         peer = (XComponentPeer)XToolkit.targetToPeer(client);
 109         while (client != null && peer == null) {
 110             client = getParent(client);
 111             peer = (XComponentPeer)XToolkit.targetToPeer(client);
 112         }
 113         if (log.isLoggable(Level.FINE)) {
 114             log.log(Level.FINE, "Peer is {0}, client is {1}",
 115                     new Object[] {String.valueOf(peer), String.valueOf(client)});
 116         }
 117         if (peer != null)
 118             return peer;
 119 
 120         return null;
 121     }
 122 
 123     /*
 124      * Subclasses should override disposeImpl() instead of dispose(). Client
 125      * code should always invoke dispose(), never disposeImpl().
 126      */
 127     protected synchronized void disposeImpl() {
 128         super.disposeImpl();
 129         clientComponentWindow = null;
 130     }
 131 
 132     protected void awtLock() {
 133         XToolkit.awtLock();
 134     }
 135 
 136     protected void awtUnlock() {
 137         XToolkit.awtUnlock();
 138     }
 139 
 140     long getCurrentParentWindow() {
 141         return (long)((XWindow)clientComponentWindow.getPeer()).getContentWindow();
 142     }
 143 
 144     /*
 145      * Native methods
 146      */
 147     private native boolean openXIMNative(long display);
 148     private native boolean createXICNative(long window);
 149     private native void setXICFocusNative(long window,
 150                                     boolean value, boolean active);
 151     private native void adjustStatusWindow(long window);
 152 }