0N/A/*
3261N/A * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A#ifdef HEADLESS
0N/A #error This file should not be included in headless library
0N/A#endif
0N/A
0N/A#include <stdio.h>
0N/A#include <stdlib.h>
0N/A#include <X11/Xlib.h>
0N/A#ifdef XAWT
0N/A#include <sys/time.h>
0N/A#else /* !XAWT */
0N/A#include <Xm/Xm.h>
0N/A#include <Xm/RowColumn.h>
0N/A#include <Xm/MwmUtil.h>
0N/A#include <Xm/MenuShell.h>
0N/A#endif /* XAWT */
0N/A
0N/A#include "awt.h"
0N/A#include "awt_p.h"
0N/A
0N/A#include <sun_awt_X11InputMethod.h>
0N/A#ifdef XAWT
0N/A#include <sun_awt_X11_XComponentPeer.h>
0N/A#include <sun_awt_X11_XInputMethod.h>
0N/A#else /* !XAWT */
0N/A#include <sun_awt_motif_MComponentPeer.h>
0N/A#include <sun_awt_motif_MInputMethod.h>
0N/A
0N/A#define MCOMPONENTPEER_CLASS_NAME "sun/awt/motif/MComponentPeer"
0N/A#endif /* XAWT */
0N/A
0N/A#define THROW_OUT_OF_MEMORY_ERROR() \
0N/A JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL)
0N/A#define SETARG(name, value) XtSetArg(args[argc], name, value); argc++
0N/A
0N/Astruct X11InputMethodIDs {
0N/A jfieldID pData;
0N/A} x11InputMethodIDs;
0N/A
0N/Astatic void PreeditStartCallback(XIC, XPointer, XPointer);
0N/Astatic void PreeditDoneCallback(XIC, XPointer, XPointer);
0N/Astatic void PreeditDrawCallback(XIC, XPointer,
0N/A XIMPreeditDrawCallbackStruct *);
0N/Astatic void PreeditCaretCallback(XIC, XPointer,
0N/A XIMPreeditCaretCallbackStruct *);
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/Astatic void StatusStartCallback(XIC, XPointer, XPointer);
0N/Astatic void StatusDoneCallback(XIC, XPointer, XPointer);
0N/Astatic void StatusDrawCallback(XIC, XPointer,
0N/A XIMStatusDrawCallbackStruct *);
0N/A#endif
0N/A
0N/A#define ROOT_WINDOW_STYLES (XIMPreeditNothing | XIMStatusNothing)
0N/A#define NO_STYLES (XIMPreeditNone | XIMStatusNone)
0N/A
0N/A#define PreeditStartIndex 0
0N/A#define PreeditDoneIndex 1
0N/A#define PreeditDrawIndex 2
0N/A#define PreeditCaretIndex 3
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A#define StatusStartIndex 4
0N/A#define StatusDoneIndex 5
0N/A#define StatusDrawIndex 6
0N/A#define NCALLBACKS 7
0N/A#else
0N/A#define NCALLBACKS 4
0N/A#endif
0N/A
0N/A/*
0N/A * Callback function pointers: the order has to match the *Index
0N/A * values above.
0N/A */
0N/Astatic XIMProc callback_funcs[NCALLBACKS] = {
0N/A (XIMProc)PreeditStartCallback,
0N/A (XIMProc)PreeditDoneCallback,
0N/A (XIMProc)PreeditDrawCallback,
0N/A (XIMProc)PreeditCaretCallback,
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A (XIMProc)StatusStartCallback,
0N/A (XIMProc)StatusDoneCallback,
0N/A (XIMProc)StatusDrawCallback,
0N/A#endif
0N/A};
0N/A
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A#define MAX_STATUS_LEN 100
0N/Atypedef struct {
0N/A Window w; /*status window id */
0N/A Window root; /*the root window id */
0N/A#ifdef XAWT
0N/A Window parent; /*parent shell window */
0N/A#else
0N/A Widget parent; /*parent shell window */
0N/A#endif
0N/A int x, y; /*parent's upperleft position */
0N/A int width, height; /*parent's width, height */
0N/A GC lightGC; /*gc for light border */
0N/A GC dimGC; /*gc for dim border */
0N/A GC bgGC; /*normal painting */
0N/A GC fgGC; /*normal painting */
0N/A int statusW, statusH; /*status window's w, h */
0N/A int rootW, rootH; /*root window's w, h */
0N/A int bWidth; /*border width */
0N/A char status[MAX_STATUS_LEN]; /*status text */
0N/A XFontSet fontset; /*fontset for drawing */
0N/A int off_x, off_y;
0N/A Bool on; /*if the status window on*/
0N/A} StatusWindow;
0N/A#endif
0N/A
0N/A/*
0N/A * X11InputMethodData keeps per X11InputMethod instance information. A pointer
0N/A * to this data structure is kept in an X11InputMethod object (pData).
0N/A */
0N/Atypedef struct _X11InputMethodData {
0N/A XIC current_ic; /* current X Input Context */
0N/A XIC ic_active; /* X Input Context for active clients */
0N/A XIC ic_passive; /* X Input Context for passive clients */
0N/A XIMCallback *callbacks; /* callback parameters */
0N/A#ifndef XAWT
0N/A jobject peer; /* MComponentPeer of client Window */
0N/A#endif /* XAWT */
0N/A jobject x11inputmethod; /* global ref to X11InputMethod instance */
0N/A /* associated with the XIC */
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A StatusWindow *statusWindow; /* our own status window */
0N/A#else
0N/A#ifndef XAWT
0N/A Widget statusWidget; /* IM status window widget */
0N/A#endif /* XAWT */
0N/A#endif
0N/A char *lookup_buf; /* buffer used for XmbLookupString */
0N/A int lookup_buf_len; /* lookup buffer size in bytes */
0N/A} X11InputMethodData;
0N/A
0N/A/*
0N/A * When XIC is created, a global reference is created for
0N/A * sun.awt.X11InputMethod object so that it could be used by the XIM callback
0N/A * functions. This could be a dangerous thing to do when the original
0N/A * X11InputMethod object is garbage collected and as a result,
0N/A * destroyX11InputMethodData is called to delete the global reference.
0N/A * If any XIM callback function still holds and uses the "already deleted"
0N/A * global reference, disaster is going to happen. So we have to maintain
0N/A * a list for these global references which is consulted first when the
0N/A * callback functions or any function tries to use "currentX11InputMethodObject"
0N/A * which always refers to the global reference try to use it.
0N/A *
0N/A */
0N/Atypedef struct _X11InputMethodGRefNode {
0N/A jobject inputMethodGRef;
0N/A struct _X11InputMethodGRefNode* next;
0N/A} X11InputMethodGRefNode;
0N/A
0N/AX11InputMethodGRefNode *x11InputMethodGRefListHead = NULL;
0N/A
0N/A/* reference to the current X11InputMethod instance, it is always
0N/A point to the global reference to the X11InputMethodObject since
0N/A it could be referenced by different threads. */
0N/Ajobject currentX11InputMethodInstance = NULL;
0N/A
0N/AWindow currentFocusWindow = 0; /* current window that has focus for input
0N/A method. (the best place to put this
0N/A information should be
0N/A currentX11InputMethodInstance's pData) */
0N/Astatic XIM X11im = NULL;
0N/ADisplay * dpy = NULL;
0N/A
0N/A#define GetJNIEnv() (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2)
0N/A
0N/A#ifndef XAWT
0N/Astatic jobject mcompClass = NULL;
0N/Astatic jobject awteventClass = NULL;
0N/Astatic jfieldID mcompPDataID = NULL;
0N/A#endif /* XAWT */
0N/A
0N/Astatic void DestroyXIMCallback(XIM, XPointer, XPointer);
0N/Astatic void OpenXIMCallback(Display *, XPointer, XPointer);
0N/A/* Solaris XIM Extention */
0N/A#define XNCommitStringCallback "commitStringCallback"
0N/Astatic void CommitStringCallback(XIC, XPointer, XPointer);
0N/A
0N/Astatic X11InputMethodData * getX11InputMethodData(JNIEnv *, jobject);
0N/Astatic void setX11InputMethodData(JNIEnv *, jobject, X11InputMethodData *);
0N/Astatic void destroyX11InputMethodData(JNIEnv *, X11InputMethodData *);
0N/Astatic void freeX11InputMethodData(JNIEnv *, X11InputMethodData *);
0N/A
0N/A#ifdef __solaris__
0N/A/* Prototype for this function is missing in Solaris X11R6 Xlib.h */
0N/Aextern char *XSetIMValues(
0N/A#if NeedVarargsPrototypes
0N/A XIM /* im */, ...
0N/A#endif
0N/A);
0N/A#endif
0N/A
0N/A#ifdef XAWT_HACK
0N/A/*
0N/A * This function is stolen from /src/solaris/hpi/src/system_md.c
0N/A * It is used in setting the time in Java-level InputEvents
0N/A */
0N/Ajlong
0N/Aawt_util_nowMillisUTC()
0N/A{
0N/A struct timeval t;
0N/A gettimeofday(&t, NULL);
0N/A return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000);
0N/A}
0N/A#endif /* XAWT_HACK */
0N/A
0N/A/*
0N/A * Converts the wchar_t string to a multi-byte string calling wcstombs(). A
0N/A * buffer is allocated by malloc() to store the multi-byte string. NULL is
0N/A * returned if the given wchar_t string pointer is NULL or buffer allocation is
0N/A * failed.
0N/A */
0N/Astatic char *
0N/Awcstombsdmp(wchar_t *wcs, int len)
0N/A{
0N/A size_t n;
0N/A char *mbs;
0N/A
0N/A if (wcs == NULL)
0N/A return NULL;
0N/A
0N/A n = len*MB_CUR_MAX + 1;
0N/A
0N/A mbs = (char *) malloc(n * sizeof(char));
0N/A if (mbs == NULL) {
0N/A THROW_OUT_OF_MEMORY_ERROR();
0N/A return NULL;
0N/A }
0N/A
0N/A /* TODO: check return values... Handle invalid characters properly... */
0N/A if (wcstombs(mbs, wcs, n) == (size_t)-1)
0N/A return NULL;
0N/A
0N/A return mbs;
0N/A}
0N/A
0N/A#ifndef XAWT
0N/A/*
0N/A * Find a class for the given class name and return a global reference to the
0N/A * class.
0N/A */
0N/Astatic jobject
0N/AfindClass(const char *className)
0N/A{
0N/A JNIEnv *env = GetJNIEnv();
0N/A jclass classClass;
0N/A jobject objectClass;
0N/A
0N/A classClass = (*env)->FindClass(env, className);
0N/A objectClass = (*env)->NewGlobalRef(env,classClass);
0N/A
0N/A if (JNU_IsNull(env, objectClass)) {
0N/A JNU_ThrowClassNotFoundException(env, className);
0N/A }
0N/A return objectClass;
0N/A}
0N/A#endif /* XAWT */
0N/A
0N/A/*
0N/A * Returns True if the global reference is still in the list,
0N/A * otherwise False.
0N/A */
0N/Astatic Bool isX11InputMethodGRefInList(jobject imGRef) {
0N/A X11InputMethodGRefNode *pX11InputMethodGRef = x11InputMethodGRefListHead;
0N/A
0N/A if (imGRef == NULL) {
0N/A return False;
0N/A }
0N/A
0N/A while (pX11InputMethodGRef != NULL) {
0N/A if (pX11InputMethodGRef->inputMethodGRef == imGRef) {
0N/A return True;
0N/A }
0N/A pX11InputMethodGRef = pX11InputMethodGRef->next;
0N/A }
0N/A
0N/A return False;
0N/A}
0N/A
0N/A/*
0N/A * Add the new created global reference to the list.
0N/A */
0N/Astatic void addToX11InputMethodGRefList(jobject newX11InputMethodGRef) {
0N/A X11InputMethodGRefNode *newNode = NULL;
0N/A
0N/A if (newX11InputMethodGRef == NULL ||
0N/A isX11InputMethodGRefInList(newX11InputMethodGRef)) {
0N/A return;
0N/A }
0N/A
0N/A newNode = (X11InputMethodGRefNode *)malloc(sizeof(X11InputMethodGRefNode));
0N/A
0N/A if (newNode == NULL) {
0N/A return;
0N/A } else {
0N/A newNode->inputMethodGRef = newX11InputMethodGRef;
0N/A newNode->next = x11InputMethodGRefListHead;
0N/A x11InputMethodGRefListHead = newNode;
0N/A }
0N/A}
0N/A
0N/A/*
0N/A * Remove the global reference from the list.
0N/A */
0N/Astatic void removeX11InputMethodGRefFromList(jobject x11InputMethodGRef) {
0N/A X11InputMethodGRefNode *pX11InputMethodGRef = NULL;
0N/A X11InputMethodGRefNode *cX11InputMethodGRef = x11InputMethodGRefListHead;
0N/A
0N/A if (x11InputMethodGRefListHead == NULL ||
0N/A x11InputMethodGRef == NULL) {
0N/A return;
0N/A }
0N/A
0N/A /* cX11InputMethodGRef always refers to the current node while
0N/A pX11InputMethodGRef refers to the previous node.
0N/A */
0N/A while (cX11InputMethodGRef != NULL) {
0N/A if (cX11InputMethodGRef->inputMethodGRef == x11InputMethodGRef) {
0N/A break;
0N/A }
0N/A pX11InputMethodGRef = cX11InputMethodGRef;
0N/A cX11InputMethodGRef = cX11InputMethodGRef->next;
0N/A }
0N/A
0N/A if (cX11InputMethodGRef == NULL) {
0N/A return; /* Not found. */
0N/A }
0N/A
0N/A if (cX11InputMethodGRef == x11InputMethodGRefListHead) {
0N/A x11InputMethodGRefListHead = x11InputMethodGRefListHead->next;
0N/A } else {
0N/A pX11InputMethodGRef->next = cX11InputMethodGRef->next;
0N/A }
0N/A free(cX11InputMethodGRef);
0N/A
0N/A return;
0N/A}
0N/A
0N/A
0N/Astatic X11InputMethodData * getX11InputMethodData(JNIEnv * env, jobject imInstance) {
0N/A X11InputMethodData *pX11IMData =
0N/A (X11InputMethodData *)JNU_GetLongFieldAsPtr(env, imInstance, x11InputMethodIDs.pData);
0N/A
0N/A /*
0N/A * In case the XIM server was killed somehow, reset X11InputMethodData.
0N/A */
0N/A if (X11im == NULL && pX11IMData != NULL) {
0N/A JNU_CallMethodByName(env, NULL, pX11IMData->x11inputmethod,
0N/A "flushText",
0N/A "()V");
0N/A /* IMPORTANT:
0N/A The order of the following calls is critical since "imInstance" may
0N/A point to the global reference itself, if "freeX11InputMethodData" is called
0N/A first, the global reference will be destroyed and "setX11InputMethodData"
0N/A will in fact fail silently. So pX11IMData will not be set to NULL.
0N/A This could make the original java object refers to a deleted pX11IMData
0N/A object.
0N/A */
0N/A setX11InputMethodData(env, imInstance, NULL);
0N/A freeX11InputMethodData(env, pX11IMData);
0N/A pX11IMData = NULL;
0N/A }
0N/A
0N/A return pX11IMData;
0N/A}
0N/A
0N/Astatic void setX11InputMethodData(JNIEnv * env, jobject imInstance, X11InputMethodData *pX11IMData) {
0N/A JNU_SetLongFieldFromPtr(env, imInstance, x11InputMethodIDs.pData, pX11IMData);
0N/A}
0N/A
0N/A/* this function should be called within AWT_LOCK() */
0N/Astatic void
0N/AdestroyX11InputMethodData(JNIEnv *env, X11InputMethodData *pX11IMData)
0N/A{
0N/A /*
0N/A * Destroy XICs
0N/A */
0N/A if (pX11IMData == NULL) {
0N/A return;
0N/A }
0N/A
0N/A if (pX11IMData->ic_active != (XIC)0) {
0N/A XUnsetICFocus(pX11IMData->ic_active);
0N/A XDestroyIC(pX11IMData->ic_active);
0N/A if (pX11IMData->ic_active != pX11IMData->ic_passive) {
0N/A if (pX11IMData->ic_passive != (XIC)0) {
0N/A XUnsetICFocus(pX11IMData->ic_passive);
0N/A XDestroyIC(pX11IMData->ic_passive);
0N/A }
0N/A pX11IMData->ic_passive = (XIC)0;
0N/A pX11IMData->current_ic = (XIC)0;
0N/A }
0N/A }
0N/A
0N/A freeX11InputMethodData(env, pX11IMData);
0N/A}
0N/A
0N/Astatic void
0N/AfreeX11InputMethodData(JNIEnv *env, X11InputMethodData *pX11IMData)
0N/A{
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A if (pX11IMData->statusWindow != NULL){
0N/A StatusWindow *sw = pX11IMData->statusWindow;
0N/A XFreeGC(awt_display, sw->lightGC);
0N/A XFreeGC(awt_display, sw->dimGC);
0N/A XFreeGC(awt_display, sw->bgGC);
0N/A XFreeGC(awt_display, sw->fgGC);
0N/A if (sw->fontset != NULL) {
0N/A XFreeFontSet(awt_display, sw->fontset);
0N/A }
0N/A XDestroyWindow(awt_display, sw->w);
0N/A free((void*)sw);
0N/A }
0N/A#endif
0N/A
0N/A if (pX11IMData->callbacks)
0N/A free((void *)pX11IMData->callbacks);
0N/A
0N/A if (env) {
0N/A#ifndef XAWT
0N/A (*env)->DeleteGlobalRef(env, pX11IMData->peer);
0N/A#endif /* XAWT */
0N/A /* Remove the global reference from the list, so that
0N/A the callback function or whoever refers to it could know.
0N/A */
0N/A removeX11InputMethodGRefFromList(pX11IMData->x11inputmethod);
0N/A (*env)->DeleteGlobalRef(env, pX11IMData->x11inputmethod);
0N/A }
0N/A
0N/A if (pX11IMData->lookup_buf) {
0N/A free((void *)pX11IMData->lookup_buf);
0N/A }
0N/A
0N/A free((void *)pX11IMData);
0N/A}
0N/A
0N/A/*
0N/A * Sets or unsets the focus to the given XIC.
0N/A */
0N/Astatic void
0N/AsetXICFocus(XIC ic, unsigned short req)
0N/A{
0N/A if (ic == NULL) {
0N/A (void)fprintf(stderr, "Couldn't find X Input Context\n");
0N/A return;
0N/A }
0N/A if (req == 1)
0N/A XSetICFocus(ic);
0N/A else
0N/A XUnsetICFocus(ic);
0N/A}
0N/A
0N/A/*
0N/A * Sets the focus window to the given XIC.
0N/A */
0N/Astatic void
0N/AsetXICWindowFocus(XIC ic, Window w)
0N/A{
0N/A if (ic == NULL) {
0N/A (void)fprintf(stderr, "Couldn't find X Input Context\n");
0N/A return;
0N/A }
0N/A (void) XSetICValues(ic, XNFocusWindow, w, NULL);
0N/A}
0N/A
0N/A/*
0N/A * Invokes XmbLookupString() to get something from the XIM. It invokes
0N/A * X11InputMethod.dispatchCommittedText() if XmbLookupString() returns
0N/A * committed text. This function is called from handleKeyEvent in canvas.c and
0N/A * it's under the Motif event loop thread context.
0N/A *
0N/A * Buffer usage: There is a bug in XFree86-4.3.0 XmbLookupString implementation,
0N/A * where it never returns XBufferOverflow. We need to allocate the initial lookup buffer
0N/A * big enough, so that the possibility that user encounters this problem is relatively
0N/A * small. When this bug gets fixed, we can make the initial buffer size smaller.
0N/A * Note that XmbLookupString() sometimes produces a non-null-terminated string.
0N/A *
0N/A * Returns True when there is a keysym value to be handled.
0N/A */
0N/A#define INITIAL_LOOKUP_BUF_SIZE 512
0N/A
0N/ABool
0N/Aawt_x11inputmethod_lookupString(XKeyPressedEvent *event, KeySym *keysymp)
0N/A{
0N/A JNIEnv *env = GetJNIEnv();
0N/A X11InputMethodData *pX11IMData = NULL;
0N/A KeySym keysym = NoSymbol;
0N/A Status status;
0N/A int mblen;
0N/A jstring javastr;
0N/A XIC ic;
0N/A Bool result = True;
0N/A static Bool composing = False;
0N/A
0N/A /*
0N/A printf("lookupString: entering...\n");
0N/A */
0N/A
0N/A if (!isX11InputMethodGRefInList(currentX11InputMethodInstance)) {
0N/A currentX11InputMethodInstance = NULL;
0N/A return False;
0N/A }
0N/A
0N/A pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
0N/A
0N/A if (pX11IMData == NULL) {
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A return False;
0N/A#else
0N/A return result;
0N/A#endif
0N/A }
0N/A
0N/A if ((ic = pX11IMData->current_ic) == (XIC)0){
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A return False;
0N/A#else
0N/A return result;
0N/A#endif
0N/A }
0N/A
0N/A /* allocate the lookup buffer at the first invocation */
0N/A if (pX11IMData->lookup_buf_len == 0) {
0N/A pX11IMData->lookup_buf = (char *)malloc(INITIAL_LOOKUP_BUF_SIZE);
0N/A if (pX11IMData->lookup_buf == NULL) {
0N/A THROW_OUT_OF_MEMORY_ERROR();
0N/A return result;
0N/A }
0N/A pX11IMData->lookup_buf_len = INITIAL_LOOKUP_BUF_SIZE;
0N/A }
0N/A
0N/A mblen = XmbLookupString(ic, event, pX11IMData->lookup_buf,
0N/A pX11IMData->lookup_buf_len - 1, &keysym, &status);
0N/A
0N/A /*
0N/A * In case of overflow, a buffer is allocated and it retries
0N/A * XmbLookupString().
0N/A */
0N/A if (status == XBufferOverflow) {
0N/A free((void *)pX11IMData->lookup_buf);
0N/A pX11IMData->lookup_buf_len = 0;
0N/A pX11IMData->lookup_buf = (char *)malloc(mblen + 1);
0N/A if (pX11IMData->lookup_buf == NULL) {
0N/A THROW_OUT_OF_MEMORY_ERROR();
0N/A return result;
0N/A }
0N/A pX11IMData->lookup_buf_len = mblen + 1;
0N/A mblen = XmbLookupString(ic, event, pX11IMData->lookup_buf,
0N/A pX11IMData->lookup_buf_len - 1, &keysym, &status);
0N/A }
0N/A pX11IMData->lookup_buf[mblen] = 0;
0N/A
0N/A /* Get keysym without taking modifiers into account first to map
0N/A * to AWT keyCode table.
0N/A */
0N/A#ifndef XAWT
0N/A if (((event->state & ShiftMask) ||
0N/A (event->state & LockMask)) &&
0N/A keysym >= 'A' && keysym <= 'Z')
0N/A {
0N/A keysym = XLookupKeysym(event, 0);
0N/A }
0N/A#endif
0N/A
0N/A switch (status) {
0N/A case XLookupBoth:
0N/A if (!composing) {
0N/A#ifdef XAWT
0N/A if (event->keycode != 0) {
0N/A#else
0N/A if (keysym < 128 || ((keysym & 0xff00) == 0xff00)) {
0N/A#endif
0N/A *keysymp = keysym;
0N/A result = False;
0N/A break;
0N/A }
0N/A }
0N/A composing = False;
0N/A /*FALLTHRU*/
0N/A case XLookupChars:
0N/A /*
0N/A printf("lookupString: status=XLookupChars, type=%d, state=%x, keycode=%x, keysym=%x\n",
0N/A event->type, event->state, event->keycode, keysym);
0N/A */
0N/A javastr = JNU_NewStringPlatform(env, (const char *)pX11IMData->lookup_buf);
0N/A if (javastr != NULL) {
0N/A JNU_CallMethodByName(env, NULL,
0N/A currentX11InputMethodInstance,
0N/A "dispatchCommittedText",
0N/A "(Ljava/lang/String;J)V",
0N/A javastr,
0N/A#ifndef XAWT_HACK
0N/A awt_util_nowMillisUTC_offset(event->time));
0N/A#else
0N/A event->time);
0N/A#endif
0N/A }
0N/A break;
0N/A
0N/A case XLookupKeySym:
0N/A /*
0N/A printf("lookupString: status=XLookupKeySym, type=%d, state=%x, keycode=%x, keysym=%x\n",
0N/A event->type, event->state, event->keycode, keysym);
0N/A */
0N/A if (keysym == XK_Multi_key)
0N/A composing = True;
0N/A if (! composing) {
0N/A *keysymp = keysym;
0N/A result = False;
0N/A }
0N/A break;
0N/A
0N/A case XLookupNone:
0N/A /*
0N/A printf("lookupString: status=XLookupNone, type=%d, state=%x, keycode=%x, keysym=%x\n",
0N/A event->type, event->state, event->keycode, keysym);
0N/A */
0N/A break;
0N/A }
0N/A
0N/A return result;
0N/A}
0N/A
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/Astatic StatusWindow *createStatusWindow(
0N/A#ifdef XAWT
0N/A Window parent) {
0N/A#else
0N/A Widget parent) {
0N/A#endif
0N/A StatusWindow *statusWindow;
0N/A XSetWindowAttributes attrib;
0N/A unsigned long attribmask;
0N/A Window containerWindow;
0N/A Window status;
0N/A Window child;
0N/A XWindowAttributes xwa;
0N/A XWindowAttributes xxwa;
0N/A /* Variable for XCreateFontSet()*/
0N/A char **mclr;
0N/A int mccr = 0;
0N/A char *dsr;
0N/A Pixel bg, fg, light, dim;
2859N/A int x, y, off_x, off_y, xx, yy;
2859N/A unsigned int w, h, bw, depth;
0N/A XGCValues values;
0N/A unsigned long valuemask = 0; /*ignore XGCvalue and use defaults*/
0N/A int screen = 0;
0N/A int i;
0N/A AwtGraphicsConfigDataPtr adata;
0N/A extern int awt_numScreens;
0N/A /*hardcode the size right now, should get the size base on font*/
0N/A int width=80, height=22;
0N/A Window rootWindow;
0N/A Window *ignoreWindowPtr;
0N/A unsigned int ignoreUnit;
0N/A
0N/A#ifdef XAWT
0N/A XGetGeometry(dpy, parent, &rootWindow, &x, &y, &w, &h, &bw, &depth);
0N/A#else
0N/A while (!XtIsShell(parent)){
0N/A parent = XtParent(parent);
0N/A }
0N/A#endif
0N/A
0N/A attrib.override_redirect = True;
0N/A attribmask = CWOverrideRedirect;
0N/A for (i = 0; i < awt_numScreens; i++) {
0N/A#ifdef XAWT
0N/A if (RootWindow(dpy, i) == rootWindow) {
0N/A#else
0N/A if (ScreenOfDisplay(dpy, i) == XtScreen(parent)) {
0N/A#endif
0N/A screen = i;
0N/A break;
0N/A }
0N/A }
0N/A adata = getDefaultConfig(screen);
0N/A bg = adata->AwtColorMatch(255, 255, 255, adata);
0N/A fg = adata->AwtColorMatch(0, 0, 0, adata);
0N/A light = adata->AwtColorMatch(195, 195, 195, adata);
0N/A dim = adata->AwtColorMatch(128, 128, 128, adata);
0N/A
2859N/A XGetWindowAttributes(dpy, parent, &xwa);
0N/A bw = 2; /*xwa.border_width does not have the correct value*/
0N/A
0N/A /*compare the size difference between parent container
0N/A and shell widget, the diff should be the border frame
0N/A and title bar height (?)*/
0N/A
0N/A XQueryTree( dpy,
2859N/A parent,
0N/A &rootWindow,
0N/A &containerWindow,
0N/A &ignoreWindowPtr,
0N/A &ignoreUnit);
0N/A XGetWindowAttributes(dpy, containerWindow, &xxwa);
0N/A
0N/A off_x = (xxwa.width - xwa.width) / 2;
0N/A off_y = xxwa.height - xwa.height - off_x; /*it's magic:-) */
0N/A
0N/A /*get the size of root window*/
0N/A XGetWindowAttributes(dpy, rootWindow, &xxwa);
0N/A
0N/A XTranslateCoordinates(dpy,
2859N/A parent, xwa.root,
0N/A xwa.x, xwa.y,
0N/A &x, &y,
0N/A &child);
0N/A xx = x - off_x;
0N/A yy = y + xwa.height - off_y;
0N/A if (xx < 0 ){
0N/A xx = 0;
0N/A }
0N/A if (xx + width > xxwa.width){
0N/A xx = xxwa.width - width;
0N/A }
0N/A if (yy + height > xxwa.height){
0N/A yy = xxwa.height - height;
0N/A }
0N/A
0N/A status = XCreateWindow(dpy,
0N/A xwa.root,
0N/A xx, yy,
0N/A width, height,
0N/A 0,
0N/A xwa.depth,
0N/A InputOutput,
0N/A adata->awt_visInfo.visual,
0N/A attribmask, &attrib);
0N/A XSelectInput(dpy, status,
0N/A ExposureMask | StructureNotifyMask | EnterWindowMask |
0N/A LeaveWindowMask | VisibilityChangeMask);
0N/A statusWindow = (StatusWindow*) calloc(1, sizeof(StatusWindow));
0N/A if (statusWindow == NULL){
0N/A THROW_OUT_OF_MEMORY_ERROR();
0N/A return NULL;
0N/A }
0N/A statusWindow->w = status;
0N/A //12-point font
0N/A statusWindow->fontset = XCreateFontSet(dpy,
0N/A "-*-*-medium-r-normal-*-*-120-*-*-*-*",
0N/A &mclr, &mccr, &dsr);
0N/A /* In case we didn't find the font set, release the list of missing characters */
0N/A if (mccr > 0) {
0N/A XFreeStringList(mclr);
0N/A }
0N/A statusWindow->parent = parent;
0N/A statusWindow->on = False;
0N/A statusWindow->x = x;
0N/A statusWindow->y = y;
0N/A statusWindow->width = xwa.width;
0N/A statusWindow->height = xwa.height;
0N/A statusWindow->off_x = off_x;
0N/A statusWindow->off_y = off_y;
0N/A statusWindow->bWidth = bw;
0N/A statusWindow->statusH = height;
0N/A statusWindow->statusW = width;
0N/A statusWindow->rootH = xxwa.height;
0N/A statusWindow->rootW = xxwa.width;
0N/A statusWindow->lightGC = XCreateGC(dpy, status, valuemask, &values);
0N/A XSetForeground(dpy, statusWindow->lightGC, light);
0N/A statusWindow->dimGC = XCreateGC(dpy, status, valuemask, &values);
0N/A XSetForeground(dpy, statusWindow->dimGC, dim);
0N/A statusWindow->fgGC = XCreateGC(dpy, status, valuemask, &values);
0N/A XSetForeground(dpy, statusWindow->fgGC, fg);
0N/A statusWindow->bgGC = XCreateGC(dpy, status, valuemask, &values);
0N/A XSetForeground(dpy, statusWindow->bgGC, bg);
0N/A return statusWindow;
0N/A}
0N/A
0N/A/* This method is to turn off or turn on the status window. */
0N/Astatic void onoffStatusWindow(X11InputMethodData* pX11IMData,
0N/A#ifdef XAWT
0N/A Window parent,
0N/A#else
0N/A Widget parent,
0N/A#endif
0N/A Bool ON){
0N/A XWindowAttributes xwa;
0N/A Window child;
0N/A int x, y;
0N/A StatusWindow *statusWindow = NULL;
0N/A
0N/A if (NULL == currentX11InputMethodInstance ||
0N/A NULL == pX11IMData ||
0N/A NULL == (statusWindow = pX11IMData->statusWindow)){
0N/A return;
0N/A }
0N/A
0N/A if (ON == False){
0N/A XUnmapWindow(dpy, statusWindow->w);
0N/A statusWindow->on = False;
0N/A return;
0N/A }
0N/A#ifdef XAWT
0N/A parent = JNU_CallMethodByName(GetJNIEnv(), NULL, pX11IMData->x11inputmethod,
0N/A "getCurrentParentWindow",
0N/A "()J").j;
0N/A#else
0N/A while (!XtIsShell(parent)){
0N/A parent = XtParent(parent);
0N/A }
0N/A#endif
0N/A if (statusWindow->parent != parent){
0N/A statusWindow->parent = parent;
0N/A }
2859N/A XGetWindowAttributes(dpy, parent, &xwa);
0N/A XTranslateCoordinates(dpy,
2859N/A parent, xwa.root,
0N/A xwa.x, xwa.y,
0N/A &x, &y,
0N/A &child);
0N/A if (statusWindow->x != x
0N/A || statusWindow->y != y
0N/A || statusWindow->height != xwa.height){
0N/A statusWindow->x = x;
0N/A statusWindow->y = y;
0N/A statusWindow->height = xwa.height;
0N/A x = statusWindow->x - statusWindow->off_x;
0N/A y = statusWindow->y + statusWindow->height - statusWindow->off_y;
0N/A if (x < 0 ){
0N/A x = 0;
0N/A }
0N/A if (x + statusWindow->statusW > statusWindow->rootW){
0N/A x = statusWindow->rootW - statusWindow->statusW;
0N/A }
0N/A if (y + statusWindow->statusH > statusWindow->rootH){
0N/A y = statusWindow->rootH - statusWindow->statusH;
0N/A }
0N/A XMoveWindow(dpy, statusWindow->w, x, y);
0N/A }
0N/A statusWindow->on = True;
0N/A XMapWindow(dpy, statusWindow->w);
0N/A}
0N/A
0N/Avoid paintStatusWindow(StatusWindow *statusWindow){
0N/A Window win = statusWindow->w;
0N/A GC lightgc = statusWindow->lightGC;
0N/A GC dimgc = statusWindow->dimGC;
0N/A GC bggc = statusWindow->bgGC;
0N/A GC fggc = statusWindow->fgGC;
0N/A
0N/A int width = statusWindow->statusW;
0N/A int height = statusWindow->statusH;
0N/A int bwidth = statusWindow->bWidth;
0N/A XFillRectangle(dpy, win, bggc, 0, 0, width, height);
0N/A /* draw border */
0N/A XDrawLine(dpy, win, fggc, 0, 0, width, 0);
0N/A XDrawLine(dpy, win, fggc, 0, height-1, width-1, height-1);
0N/A XDrawLine(dpy, win, fggc, 0, 0, 0, height-1);
0N/A XDrawLine(dpy, win, fggc, width-1, 0, width-1, height-1);
0N/A
0N/A XDrawLine(dpy, win, lightgc, 1, 1, width-bwidth, 1);
0N/A XDrawLine(dpy, win, lightgc, 1, 1, 1, height-2);
0N/A XDrawLine(dpy, win, lightgc, 1, height-2, width-bwidth, height-2);
0N/A XDrawLine(dpy, win, lightgc, width-bwidth-1, 1, width-bwidth-1, height-2);
0N/A
0N/A XDrawLine(dpy, win, dimgc, 2, 2, 2, height-3);
0N/A XDrawLine(dpy, win, dimgc, 2, height-3, width-bwidth-1, height-3);
0N/A XDrawLine(dpy, win, dimgc, 2, 2, width-bwidth-2, 2);
0N/A XDrawLine(dpy, win, dimgc, width-bwidth, 2, width-bwidth, height-3);
0N/A if (statusWindow->fontset){
0N/A XmbDrawString(dpy, win, statusWindow->fontset, fggc,
0N/A bwidth + 2, height - bwidth - 4,
0N/A statusWindow->status,
0N/A strlen(statusWindow->status));
0N/A }
0N/A else{
0N/A /*too bad we failed to create a fontset for this locale*/
0N/A XDrawString(dpy, win, fggc, bwidth + 2, height - bwidth - 4,
0N/A "[InputMethod ON]", strlen("[InputMethod ON]"));
0N/A }
0N/A}
0N/A
0N/Avoid statusWindowEventHandler(XEvent event){
0N/A JNIEnv *env = GetJNIEnv();
0N/A X11InputMethodData *pX11IMData = NULL;
0N/A StatusWindow *statusWindow;
0N/A
0N/A if (!isX11InputMethodGRefInList(currentX11InputMethodInstance)) {
0N/A currentX11InputMethodInstance = NULL;
0N/A return;
0N/A }
0N/A
0N/A if (NULL == currentX11InputMethodInstance
0N/A || NULL == (pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance))
0N/A || NULL == (statusWindow = pX11IMData->statusWindow)
0N/A || statusWindow->w != event.xany.window){
0N/A return;
0N/A }
0N/A
0N/A switch (event.type){
0N/A case Expose:
0N/A paintStatusWindow(statusWindow);
0N/A break;
0N/A case MapNotify:
0N/A case ConfigureNotify:
0N/A {
0N/A /*need to reset the stackMode...*/
0N/A XWindowChanges xwc;
0N/A int value_make = CWStackMode;
0N/A xwc.stack_mode = TopIf;
0N/A XConfigureWindow(dpy, statusWindow->w, value_make, &xwc);
0N/A }
0N/A break;
0N/A /*
0N/A case UnmapNotify:
0N/A case VisibilityNotify:
0N/A break;
0N/A */
0N/A default:
0N/A break;
0N/A }
0N/A}
0N/A
0N/A#ifdef XAWT
0N/Astatic void adjustStatusWindow(Window shell){
0N/A#else
0N/Avoid adjustStatusWindow(Widget shell){
0N/A#endif
0N/A JNIEnv *env = GetJNIEnv();
0N/A X11InputMethodData *pX11IMData = NULL;
0N/A StatusWindow *statusWindow;
0N/A
0N/A if (NULL == currentX11InputMethodInstance
0N/A || !isX11InputMethodGRefInList(currentX11InputMethodInstance)
0N/A || NULL == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
0N/A || NULL == (statusWindow = pX11IMData->statusWindow)
0N/A || !statusWindow->on) {
0N/A return;
0N/A }
0N/A#ifdef XAWT
0N/A {
0N/A#else
0N/A if (statusWindow->parent == shell) {
0N/A#endif
0N/A XWindowAttributes xwa;
0N/A int x, y;
0N/A Window child;
2859N/A XGetWindowAttributes(dpy, shell, &xwa);
0N/A XTranslateCoordinates(dpy,
2859N/A shell, xwa.root,
0N/A xwa.x, xwa.y,
0N/A &x, &y,
0N/A &child);
0N/A if (statusWindow->x != x
0N/A || statusWindow->y != y
0N/A || statusWindow->height != xwa.height){
0N/A statusWindow->x = x;
0N/A statusWindow->y = y;
0N/A statusWindow->height = xwa.height;
0N/A
0N/A x = statusWindow->x - statusWindow->off_x;
0N/A y = statusWindow->y + statusWindow->height - statusWindow->off_y;
0N/A if (x < 0 ){
0N/A x = 0;
0N/A }
0N/A if (x + statusWindow->statusW > statusWindow->rootW){
0N/A x = statusWindow->rootW - statusWindow->statusW;
0N/A }
0N/A if (y + statusWindow->statusH > statusWindow->rootH){
0N/A y = statusWindow->rootH - statusWindow->statusH;
0N/A }
0N/A XMoveWindow(dpy, statusWindow->w, x, y);
0N/A }
0N/A }
0N/A}
4632N/A#endif /* __linux__ || MACOSX */
0N/A/*
0N/A * Creates two XICs, one for active clients and the other for passive
0N/A * clients. All information on those XICs are stored in the
0N/A * X11InputMethodData given by the pX11IMData parameter.
0N/A *
0N/A * For active clients: Try to use preedit callback to support
0N/A * on-the-spot. If tc is not null, the XIC to be created will
0N/A * share the Status Area with Motif widgets (TextComponents). If the
0N/A * preferable styles can't be used, fallback to root-window styles. If
0N/A * root-window styles failed, fallback to None styles.
0N/A *
0N/A * For passive clients: Try to use root-window styles. If failed,
0N/A * fallback to None styles.
0N/A */
0N/Astatic Bool
0N/A#ifdef XAWT
0N/AcreateXIC(JNIEnv * env, X11InputMethodData *pX11IMData, Window w)
0N/A#else /* !XAWT */
0N/AcreateXIC(Widget w, X11InputMethodData *pX11IMData,
0N/A jobject tc, jobject peer)
0N/A#endif /* XAWT */
0N/A{
0N/A XIC active_ic, passive_ic;
0N/A XVaNestedList preedit = NULL;
0N/A XVaNestedList status = NULL;
0N/A XIMStyle on_the_spot_styles = XIMPreeditCallbacks,
0N/A active_styles = 0,
0N/A passive_styles = 0,
0N/A no_styles = 0;
0N/A XIMCallback *callbacks;
0N/A unsigned short i;
0N/A XIMStyles *im_styles;
0N/A char *ret = NULL;
0N/A
0N/A if (X11im == NULL) {
0N/A return False;
0N/A }
0N/A#ifdef XAWT
2859N/A if (!w) {
0N/A return False;
0N/A }
0N/A#else /* !XAWT */
0N/A /*
0N/A * If the parent window has one or more TextComponents, the status
0N/A * area of Motif will be shared with the created XIC. Otherwise,
0N/A * root-window style status is used.
0N/A */
0N/A#endif /* XAWT */
0N/A
0N/A ret = XGetIMValues(X11im, XNQueryInputStyle, &im_styles, NULL);
0N/A
0N/A if (ret != NULL) {
0N/A jio_fprintf(stderr,"XGetIMValues: %s\n",ret);
0N/A return FALSE ;
0N/A }
0N/A
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A on_the_spot_styles |= XIMStatusNothing;
0N/A
0N/A /*kinput does not support XIMPreeditCallbacks and XIMStatusArea
0N/A at the same time, so use StatusCallback to draw the status
0N/A ourself
0N/A */
0N/A for (i = 0; i < im_styles->count_styles; i++) {
0N/A if (im_styles->supported_styles[i] == (XIMPreeditCallbacks | XIMStatusCallbacks)) {
0N/A on_the_spot_styles = (XIMPreeditCallbacks | XIMStatusCallbacks);
0N/A break;
0N/A }
0N/A }
4632N/A#else /*! __linux__ && !MACOSX */
0N/A#ifdef XAWT
0N/A on_the_spot_styles |= XIMStatusNothing;
0N/A#else /* !XAWT */
0N/A /*
0N/A * If the parent window has one or more TextComponents, the status
0N/A * area of Motif will be shared with the created XIC. Otherwise,
0N/A * root-window style status is used.
0N/A */
0N/A if (tc != NULL){
0N/A XVaNestedList status = NULL;
0N/A status = awt_motif_getXICStatusAreaList(w, tc);
0N/A if (status != NULL){
0N/A on_the_spot_styles |= XIMStatusArea;
0N/A XFree(status);
0N/A }
0N/A else
0N/A on_the_spot_styles |= XIMStatusNothing;
0N/A }
0N/A else
0N/A on_the_spot_styles |= XIMStatusNothing;
0N/A
0N/A#endif /* XAWT */
4632N/A#endif /* __linux__ || MACOSX */
0N/A
0N/A for (i = 0; i < im_styles->count_styles; i++) {
0N/A active_styles |= im_styles->supported_styles[i] & on_the_spot_styles;
0N/A passive_styles |= im_styles->supported_styles[i] & ROOT_WINDOW_STYLES;
0N/A no_styles |= im_styles->supported_styles[i] & NO_STYLES;
0N/A }
0N/A
0N/A XFree(im_styles);
0N/A
0N/A if (active_styles != on_the_spot_styles) {
0N/A if (passive_styles == ROOT_WINDOW_STYLES)
0N/A active_styles = passive_styles;
0N/A else {
0N/A if (no_styles == NO_STYLES)
0N/A active_styles = passive_styles = NO_STYLES;
0N/A else
0N/A active_styles = passive_styles = 0;
0N/A }
0N/A } else {
0N/A if (passive_styles != ROOT_WINDOW_STYLES) {
0N/A if (no_styles == NO_STYLES)
0N/A active_styles = passive_styles = NO_STYLES;
0N/A else
0N/A active_styles = passive_styles = 0;
0N/A }
0N/A }
0N/A
0N/A if (active_styles == on_the_spot_styles) {
0N/A callbacks = (XIMCallback *)malloc(sizeof(XIMCallback) * NCALLBACKS);
0N/A if (callbacks == (XIMCallback *)NULL)
0N/A return False;
0N/A pX11IMData->callbacks = callbacks;
0N/A
0N/A for (i = 0; i < NCALLBACKS; i++, callbacks++) {
0N/A callbacks->client_data = (XPointer) pX11IMData->x11inputmethod;
0N/A callbacks->callback = callback_funcs[i];
0N/A }
0N/A
0N/A callbacks = pX11IMData->callbacks;
0N/A preedit = (XVaNestedList)XVaCreateNestedList(0,
0N/A XNPreeditStartCallback, &callbacks[PreeditStartIndex],
0N/A XNPreeditDoneCallback, &callbacks[PreeditDoneIndex],
0N/A XNPreeditDrawCallback, &callbacks[PreeditDrawIndex],
0N/A XNPreeditCaretCallback, &callbacks[PreeditCaretIndex],
0N/A NULL);
0N/A if (preedit == (XVaNestedList)NULL)
0N/A goto err;
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A /*always try XIMStatusCallbacks for active client...*/
0N/A {
0N/A status = (XVaNestedList)XVaCreateNestedList(0,
0N/A XNStatusStartCallback, &callbacks[StatusStartIndex],
0N/A XNStatusDoneCallback, &callbacks[StatusDoneIndex],
0N/A XNStatusDrawCallback, &callbacks[StatusDrawIndex],
0N/A NULL);
0N/A
0N/A if (status == NULL)
0N/A goto err;
0N/A pX11IMData->statusWindow = createStatusWindow(w);
0N/A pX11IMData->ic_active = XCreateIC(X11im,
2859N/A XNClientWindow, w,
2859N/A XNFocusWindow, w,
0N/A XNInputStyle, active_styles,
0N/A XNPreeditAttributes, preedit,
0N/A XNStatusAttributes, status,
0N/A NULL);
0N/A XFree((void *)status);
0N/A XFree((void *)preedit);
0N/A }
4632N/A#else /* !__linux__ && !MACOSX */
0N/A#ifndef XAWT
0N/A if (on_the_spot_styles & XIMStatusArea) {
0N/A Widget parent;
0N/A status = awt_motif_getXICStatusAreaList(w, tc);
0N/A if (status == NULL)
0N/A goto err;
0N/A pX11IMData->statusWidget = awt_util_getXICStatusAreaWindow(w);
0N/A pX11IMData->ic_active = XCreateIC(X11im,
2859N/A XNClientWindow, pX11IMData->statusWidget,
2859N/A XNFocusWindow, w,
0N/A XNInputStyle, active_styles,
0N/A XNPreeditAttributes, preedit,
0N/A XNStatusAttributes, status,
0N/A NULL);
0N/A XFree((void *)status);
0N/A } else {
0N/A#endif /* XAWT */
0N/A pX11IMData->ic_active = XCreateIC(X11im,
2859N/A XNClientWindow, w,
2859N/A XNFocusWindow, w,
0N/A XNInputStyle, active_styles,
0N/A XNPreeditAttributes, preedit,
0N/A NULL);
0N/A#ifndef XAWT
0N/A }
0N/A#endif /* XAWT */
0N/A XFree((void *)preedit);
4632N/A#endif /* __linux__ || MACOSX */
0N/A pX11IMData->ic_passive = XCreateIC(X11im,
2859N/A XNClientWindow, w,
2859N/A XNFocusWindow, w,
0N/A XNInputStyle, passive_styles,
0N/A NULL);
0N/A
0N/A } else {
0N/A pX11IMData->ic_active = XCreateIC(X11im,
2859N/A XNClientWindow, w,
2859N/A XNFocusWindow, w,
0N/A XNInputStyle, active_styles,
0N/A NULL);
0N/A pX11IMData->ic_passive = pX11IMData->ic_active;
0N/A }
0N/A
0N/A if (pX11IMData->ic_active == (XIC)0
0N/A || pX11IMData->ic_passive == (XIC)0) {
0N/A return False;
0N/A }
0N/A
0N/A /*
0N/A * Use commit string call back if possible.
0N/A * This will ensure the correct order of preedit text and commit text
0N/A */
0N/A {
0N/A XIMCallback cb;
0N/A cb.client_data = (XPointer) pX11IMData->x11inputmethod;
2859N/A cb.callback = (XIMProc) CommitStringCallback;
0N/A XSetICValues (pX11IMData->ic_active, XNCommitStringCallback, &cb, NULL);
0N/A if (pX11IMData->ic_active != pX11IMData->ic_passive) {
0N/A XSetICValues (pX11IMData->ic_passive, XNCommitStringCallback, &cb, NULL);
0N/A }
0N/A }
0N/A
0N/A /* Add the global reference object to X11InputMethod to the list. */
0N/A addToX11InputMethodGRefList(pX11IMData->x11inputmethod);
0N/A
0N/A return True;
0N/A
0N/A err:
0N/A if (preedit)
0N/A XFree((void *)preedit);
0N/A THROW_OUT_OF_MEMORY_ERROR();
0N/A return False;
0N/A}
0N/A
0N/Astatic void
0N/APreeditStartCallback(XIC ic, XPointer client_data, XPointer call_data)
0N/A{
0N/A /*ARGSUSED*/
0N/A /* printf("Native: PreeditCaretCallback\n"); */
0N/A}
0N/A
0N/Astatic void
0N/APreeditDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
0N/A{
0N/A /*ARGSUSED*/
0N/A /* printf("Native: StatusStartCallback\n"); */
0N/A}
0N/A
0N/A/*
0N/A * Translate the preedit draw callback items to Java values and invoke
0N/A * X11InputMethod.dispatchComposedText().
0N/A *
0N/A * client_data: X11InputMethod object
0N/A */
0N/Astatic void
0N/APreeditDrawCallback(XIC ic, XPointer client_data,
0N/A XIMPreeditDrawCallbackStruct *pre_draw)
0N/A{
0N/A JNIEnv *env = GetJNIEnv();
0N/A X11InputMethodData *pX11IMData = NULL;
0N/A jmethodID x11imMethodID;
0N/A
0N/A XIMText *text;
0N/A jstring javastr = NULL;
0N/A jintArray style = NULL;
0N/A
0N/A /* printf("Native: PreeditDrawCallback() \n"); */
0N/A if (pre_draw == NULL) {
0N/A return;
0N/A }
0N/A AWT_LOCK();
0N/A if (!isX11InputMethodGRefInList((jobject)client_data)) {
0N/A if ((jobject)client_data == currentX11InputMethodInstance) {
0N/A currentX11InputMethodInstance = NULL;
0N/A }
0N/A goto finally;
0N/A }
0N/A if ((pX11IMData = getX11InputMethodData(env, (jobject)client_data)) == NULL) {
0N/A goto finally;
0N/A }
0N/A
0N/A if ((text = pre_draw->text) != NULL) {
0N/A if (text->string.multi_byte != NULL) {
0N/A if (pre_draw->text->encoding_is_wchar == False) {
0N/A javastr = JNU_NewStringPlatform(env, (const char *)text->string.multi_byte);
0N/A } else {
0N/A char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
0N/A if (mbstr == NULL) {
0N/A goto finally;
0N/A }
0N/A javastr = JNU_NewStringPlatform(env, (const char *)mbstr);
0N/A free(mbstr);
0N/A }
0N/A }
0N/A if (text->feedback != NULL) {
0N/A int cnt;
0N/A jint *tmpstyle;
0N/A
0N/A style = (*env)->NewIntArray(env, text->length);
0N/A if (JNU_IsNull(env, style)) {
0N/A THROW_OUT_OF_MEMORY_ERROR();
0N/A goto finally;
0N/A }
0N/A
0N/A if (sizeof(XIMFeedback) == sizeof(jint)) {
0N/A /*
0N/A * Optimization to avoid copying the array
0N/A */
0N/A (*env)->SetIntArrayRegion(env, style, 0,
0N/A text->length, (jint *)text->feedback);
0N/A } else {
0N/A tmpstyle = (jint *)malloc(sizeof(jint)*(text->length));
0N/A if (tmpstyle == (jint *) NULL) {
0N/A THROW_OUT_OF_MEMORY_ERROR();
0N/A goto finally;
0N/A }
0N/A for (cnt = 0; cnt < (int)text->length; cnt++)
0N/A tmpstyle[cnt] = text->feedback[cnt];
0N/A (*env)->SetIntArrayRegion(env, style, 0,
0N/A text->length, (jint *)tmpstyle);
0N/A }
0N/A }
0N/A }
0N/A JNU_CallMethodByName(env, NULL, pX11IMData->x11inputmethod,
0N/A "dispatchComposedText",
0N/A "(Ljava/lang/String;[IIIIJ)V",
0N/A javastr,
0N/A style,
0N/A (jint)pre_draw->chg_first,
0N/A (jint)pre_draw->chg_length,
0N/A (jint)pre_draw->caret,
0N/A awt_util_nowMillisUTC());
0N/Afinally:
0N/A AWT_UNLOCK();
0N/A return;
0N/A}
0N/A
0N/Astatic void
0N/APreeditCaretCallback(XIC ic, XPointer client_data,
0N/A XIMPreeditCaretCallbackStruct *pre_caret)
0N/A{
0N/A /*ARGSUSED*/
0N/A /* printf("Native: PreeditCaretCallback\n"); */
0N/A
0N/A}
0N/A
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/Astatic void
0N/AStatusStartCallback(XIC ic, XPointer client_data, XPointer call_data)
0N/A{
0N/A /*ARGSUSED*/
0N/A /*printf("StatusStartCallback:\n"); */
0N/A
0N/A}
0N/A
0N/Astatic void
0N/AStatusDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
0N/A{
0N/A /*ARGSUSED*/
0N/A /*printf("StatusDoneCallback:\n"); */
0N/A
0N/A}
0N/A
0N/Astatic void
0N/AStatusDrawCallback(XIC ic, XPointer client_data,
0N/A XIMStatusDrawCallbackStruct *status_draw)
0N/A{
0N/A /*ARGSUSED*/
0N/A /*printf("StatusDrawCallback:\n"); */
0N/A JNIEnv *env = GetJNIEnv();
0N/A X11InputMethodData *pX11IMData = NULL;
0N/A StatusWindow *statusWindow;
0N/A
0N/A AWT_LOCK();
0N/A
0N/A if (!isX11InputMethodGRefInList((jobject)client_data)) {
0N/A if ((jobject)client_data == currentX11InputMethodInstance) {
0N/A currentX11InputMethodInstance = NULL;
0N/A }
0N/A goto finally;
0N/A }
0N/A
0N/A if (NULL == (pX11IMData = getX11InputMethodData(env, (jobject)client_data))
0N/A || NULL == (statusWindow = pX11IMData->statusWindow)){
0N/A goto finally;
0N/A }
0N/A currentX11InputMethodInstance = (jobject)client_data;
0N/A
0N/A if (status_draw->type == XIMTextType){
0N/A XIMText *text = (status_draw->data).text;
0N/A if (text != NULL){
0N/A if (text->string.multi_byte != NULL){
0N/A strcpy(statusWindow->status, text->string.multi_byte);
0N/A }
0N/A else{
0N/A char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
0N/A strcpy(statusWindow->status, mbstr);
0N/A }
0N/A statusWindow->on = True;
0N/A onoffStatusWindow(pX11IMData, statusWindow->parent, True);
0N/A paintStatusWindow(statusWindow);
0N/A }
0N/A else {
0N/A statusWindow->on = False;
0N/A /*just turnoff the status window
0N/A paintStatusWindow(statusWindow);
0N/A */
0N/A onoffStatusWindow(pX11IMData, 0, False);
0N/A }
0N/A }
0N/A
0N/A finally:
0N/A AWT_UNLOCK();
0N/A}
4632N/A#endif /* __linux__ || MACOSX */
0N/A
0N/Astatic void CommitStringCallback(XIC ic, XPointer client_data, XPointer call_data) {
0N/A JNIEnv *env = GetJNIEnv();
0N/A XIMText * text = (XIMText *)call_data;
0N/A X11InputMethodData *pX11IMData = NULL;
0N/A jstring javastr;
0N/A
0N/A AWT_LOCK();
0N/A
0N/A if (!isX11InputMethodGRefInList((jobject)client_data)) {
0N/A if ((jobject)client_data == currentX11InputMethodInstance) {
0N/A currentX11InputMethodInstance = NULL;
0N/A }
0N/A goto finally;
0N/A }
0N/A
0N/A if ((pX11IMData = getX11InputMethodData(env, (jobject)client_data)) == NULL) {
0N/A goto finally;
0N/A }
0N/A currentX11InputMethodInstance = (jobject)client_data;
0N/A
0N/A if (text->encoding_is_wchar == False) {
0N/A javastr = JNU_NewStringPlatform(env, (const char *)text->string.multi_byte);
0N/A } else {
0N/A char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
0N/A if (mbstr == NULL) {
0N/A goto finally;
0N/A }
0N/A javastr = JNU_NewStringPlatform(env, (const char *)mbstr);
0N/A free(mbstr);
0N/A }
0N/A
0N/A if (javastr != NULL) {
0N/A JNU_CallMethodByName(env, NULL,
0N/A pX11IMData->x11inputmethod,
0N/A "dispatchCommittedText",
0N/A "(Ljava/lang/String;J)V",
0N/A javastr,
0N/A awt_util_nowMillisUTC());
0N/A }
0N/A finally:
0N/A AWT_UNLOCK();
0N/A}
0N/A
0N/Astatic void OpenXIMCallback(Display *display, XPointer client_data, XPointer call_data) {
0N/A XIMCallback ximCallback;
0N/A
0N/A X11im = XOpenIM(display, NULL, NULL, NULL);
0N/A if (X11im == NULL) {
0N/A return;
0N/A }
0N/A
0N/A ximCallback.callback = (XIMProc)DestroyXIMCallback;
0N/A ximCallback.client_data = NULL;
0N/A XSetIMValues(X11im, XNDestroyCallback, &ximCallback, NULL);
0N/A}
0N/A
0N/Astatic void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) {
0N/A /* mark that XIM server was destroyed */
0N/A X11im = NULL;
2789N/A JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
2789N/A /* free the old pX11IMData and set it to null. this also avoids crashing
2789N/A * the jvm if the XIM server reappears */
2789N/A X11InputMethodData *pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
0N/A}
0N/A
0N/A/*
0N/A * Class: java_sun_awt_motif_X11InputMethod
0N/A * Method: initIDs
0N/A * Signature: ()V
0N/A */
0N/A
0N/A/* This function gets called from the static initializer for
0N/A X11InputMethod.java
0N/A to initialize the fieldIDs for fields that may be accessed from C */
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_awt_X11InputMethod_initIDs(JNIEnv *env, jclass cls)
0N/A{
0N/A x11InputMethodIDs.pData = (*env)->GetFieldID(env, cls, "pData", "J");
0N/A}
0N/A
0N/A
0N/AJNIEXPORT jboolean JNICALL
0N/A#ifdef XAWT
0N/AJava_sun_awt_X11_XInputMethod_openXIMNative(JNIEnv *env,
0N/A jobject this,
0N/A jlong display)
0N/A#else
0N/AJava_sun_awt_motif_MInputMethod_openXIMNative(JNIEnv *env,
0N/A jobject this)
0N/A#endif
0N/A{
0N/A Bool registered;
0N/A
0N/A AWT_LOCK();
0N/A
0N/A#ifdef XAWT
2859N/A dpy = (Display *)jlong_to_ptr(display);
0N/A#else
0N/A dpy = awt_display;
0N/A#endif
0N/A
0N/A/* Use IMInstantiate call back only on Linux, as there is a bug in Solaris
0N/A (4768335)
0N/A*/
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A registered = XRegisterIMInstantiateCallback(dpy, NULL, NULL,
2859N/A NULL, (XIDProc)OpenXIMCallback, NULL);
0N/A if (!registered) {
0N/A /* directly call openXIM callback */
0N/A#endif
0N/A OpenXIMCallback(dpy, NULL, NULL);
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A }
0N/A#endif
0N/A
0N/A AWT_UNLOCK();
0N/A
0N/A return JNI_TRUE;
0N/A}
0N/A
0N/AJNIEXPORT jboolean JNICALL
0N/A#ifdef XAWT
0N/AJava_sun_awt_X11_XInputMethod_createXICNative(JNIEnv *env,
0N/A jobject this,
0N/A jlong window)
0N/A{
0N/A#else /* !XAWT */
0N/AJava_sun_awt_motif_MInputMethod_createXICNative(JNIEnv *env,
0N/A jobject this,
0N/A jobject comp,
0N/A jobject tc)
0N/A{
0N/A struct ComponentData *cdata;
0N/A#endif /* XAWT */
0N/A X11InputMethodData *pX11IMData;
0N/A jobject globalRef;
0N/A XIC ic;
0N/A
0N/A AWT_LOCK();
0N/A
0N/A#ifdef XAWT
2859N/A if (!window) {
0N/A#else /* !XAWT */
0N/A if (JNU_IsNull(env, comp)) {
0N/A#endif /* XAWT */
0N/A JNU_ThrowNullPointerException(env, "NullPointerException");
0N/A AWT_UNLOCK();
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A pX11IMData = (X11InputMethodData *) calloc(1, sizeof(X11InputMethodData));
0N/A if (pX11IMData == NULL) {
0N/A THROW_OUT_OF_MEMORY_ERROR();
0N/A AWT_UNLOCK();
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A#ifndef XAWT
0N/A if (mcompClass == NULL) {
0N/A mcompClass = findClass(MCOMPONENTPEER_CLASS_NAME);
0N/A mcompPDataID = (*env)->GetFieldID(env, mcompClass, "pData", "J");
0N/A }
0N/A cdata = (struct ComponentData *) JNU_GetLongFieldAsPtr(env,comp,mcompPDataID);
0N/A
0N/A if (cdata == 0) {
0N/A free((void *)pX11IMData);
0N/A JNU_ThrowNullPointerException(env, "createXIC");
0N/A AWT_UNLOCK();
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A pX11IMData->peer = (*env)->NewGlobalRef(env, comp);
0N/A#endif /* XAWT */
0N/A globalRef = (*env)->NewGlobalRef(env, this);
0N/A pX11IMData->x11inputmethod = globalRef;
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A pX11IMData->statusWindow = NULL;
4632N/A#else /* !__linux__ && !MACOSX */
0N/A#ifndef XAWT
0N/A pX11IMData->statusWidget = (Widget) NULL;
0N/A#endif /* XAWT */
4632N/A#endif /* __linux__ || MACOSX */
0N/A
0N/A pX11IMData->lookup_buf = 0;
0N/A pX11IMData->lookup_buf_len = 0;
0N/A
0N/A#ifdef XAWT
0N/A if (createXIC(env, pX11IMData, (Window)window)
0N/A#else /* !XAWT */
0N/A if (createXIC(cdata->widget, pX11IMData, tc, comp)
0N/A#endif /* XAWT */
0N/A == False) {
0N/A destroyX11InputMethodData((JNIEnv *) NULL, pX11IMData);
0N/A pX11IMData = (X11InputMethodData *) NULL;
0N/A }
0N/A
0N/A setX11InputMethodData(env, this, pX11IMData);
0N/A
0N/A AWT_UNLOCK();
0N/A return (pX11IMData != NULL);
0N/A}
0N/A
0N/A#ifndef XAWT
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_awt_motif_MInputMethod_reconfigureXICNative(JNIEnv *env,
0N/A jobject this,
0N/A jobject comp,
0N/A jobject tc)
0N/A{
0N/A X11InputMethodData *pX11IMData;
0N/A
0N/A AWT_LOCK();
0N/A
0N/A pX11IMData = getX11InputMethodData(env, this);
0N/A if (pX11IMData == NULL) {
0N/A AWT_UNLOCK();
0N/A return;
0N/A }
0N/A
0N/A if (pX11IMData->current_ic == (XIC)0) {
0N/A destroyX11InputMethodData(env, pX11IMData);
0N/A pX11IMData = (X11InputMethodData *)NULL;
0N/A } else {
0N/A Bool active;
0N/A struct ComponentData *cdata;
0N/A
0N/A active = pX11IMData->current_ic == pX11IMData->ic_active;
0N/A if (mcompClass == NULL) {
0N/A mcompClass = findClass(MCOMPONENTPEER_CLASS_NAME);
0N/A mcompPDataID = (*env)->GetFieldID(env, mcompClass, "pData", "J");
0N/A }
0N/A cdata = (struct ComponentData *) JNU_GetLongFieldAsPtr(env,comp,mcompPDataID);
0N/A if (cdata == 0) {
0N/A JNU_ThrowNullPointerException(env, "reconfigureXICNative");
0N/A destroyX11InputMethodData(env, pX11IMData);
0N/A pX11IMData = (X11InputMethodData *)NULL;
0N/A }
0N/A XDestroyIC(pX11IMData->ic_active);
0N/A if (pX11IMData->ic_active != pX11IMData->ic_passive)
0N/A XDestroyIC(pX11IMData->ic_passive);
0N/A pX11IMData->current_ic = (XIC)0;
0N/A pX11IMData->ic_active = (XIC)0;
0N/A pX11IMData->ic_passive = (XIC)0;
0N/A if (createXIC(cdata->widget, pX11IMData, tc, comp)) {
0N/A pX11IMData->current_ic = active ?
0N/A pX11IMData->ic_active : pX11IMData->ic_passive;
0N/A /*
0N/A * On Solaris2.6, setXICWindowFocus() has to be invoked
0N/A * before setting focus.
0N/A */
2859N/A setXICWindowFocus(pX11IMData->current_ic, cdata->widget);
0N/A setXICFocus(pX11IMData->current_ic, True);
0N/A } else {
0N/A destroyX11InputMethodData((JNIEnv *) NULL, pX11IMData);
0N/A pX11IMData = (X11InputMethodData *)NULL;
0N/A }
0N/A }
0N/A
0N/A setX11InputMethodData(env, this, pX11IMData);
0N/A
0N/A AWT_UNLOCK();
0N/A}
0N/A
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_awt_motif_MInputMethod_setXICFocusNative(JNIEnv *env,
0N/A jobject this,
0N/A jobject comp,
0N/A jboolean req,
0N/A jboolean active)
0N/A{
0N/A struct ComponentData *cdata;
0N/A Widget w;
0N/A#else /* !XAWT */
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_awt_X11_XInputMethod_setXICFocusNative(JNIEnv *env,
0N/A jobject this,
0N/A jlong w,
0N/A jboolean req,
0N/A jboolean active)
0N/A{
0N/A#endif /* XAWT */
0N/A X11InputMethodData *pX11IMData;
0N/A AWT_LOCK();
0N/A pX11IMData = getX11InputMethodData(env, this);
0N/A if (pX11IMData == NULL) {
0N/A AWT_UNLOCK();
0N/A return;
0N/A }
0N/A
0N/A if (req) {
0N/A#ifdef XAWT
2859N/A if (!w) {
0N/A AWT_UNLOCK();
0N/A return;
0N/A }
0N/A#else /* !XAWT */
0N/A struct ComponentData *cdata;
0N/A
0N/A if (JNU_IsNull(env, comp)) {
0N/A AWT_UNLOCK();
0N/A return;
0N/A }
0N/A if (mcompClass == NULL) {
0N/A mcompClass = findClass(MCOMPONENTPEER_CLASS_NAME);
0N/A mcompPDataID = (*env)->GetFieldID(env, mcompClass, "pData", "J");
0N/A }
0N/A cdata = (struct ComponentData *)JNU_GetLongFieldAsPtr(env, comp,
0N/A mcompPDataID);
0N/A if (cdata == 0) {
0N/A JNU_ThrowNullPointerException(env, "setXICFocus pData");
0N/A AWT_UNLOCK();
0N/A return;
0N/A }
0N/A#endif /* XAWT */
0N/A
0N/A pX11IMData->current_ic = active ?
0N/A pX11IMData->ic_active : pX11IMData->ic_passive;
0N/A /*
0N/A * On Solaris2.6, setXICWindowFocus() has to be invoked
0N/A * before setting focus.
0N/A */
0N/A#ifndef XAWT
0N/A w = cdata->widget;
0N/A#endif /* XAWT */
2859N/A setXICWindowFocus(pX11IMData->current_ic, w);
0N/A setXICFocus(pX11IMData->current_ic, req);
0N/A currentX11InputMethodInstance = pX11IMData->x11inputmethod;
2859N/A currentFocusWindow = w;
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A if (active && pX11IMData->statusWindow && pX11IMData->statusWindow->on)
0N/A onoffStatusWindow(pX11IMData, w, True);
0N/A#endif
0N/A } else {
0N/A currentX11InputMethodInstance = NULL;
0N/A currentFocusWindow = 0;
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A onoffStatusWindow(pX11IMData, 0, False);
0N/A if (pX11IMData->current_ic != NULL)
0N/A#endif
0N/A setXICFocus(pX11IMData->current_ic, req);
0N/A
0N/A pX11IMData->current_ic = (XIC)0;
0N/A }
0N/A
0N/A XFlush(dpy);
0N/A AWT_UNLOCK();
0N/A}
0N/A
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_awt_X11InputMethod_turnoffStatusWindow(JNIEnv *env,
0N/A jobject this)
0N/A{
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A X11InputMethodData *pX11IMData;
0N/A StatusWindow *statusWindow;
0N/A
0N/A AWT_LOCK();
0N/A
0N/A if (NULL == currentX11InputMethodInstance
0N/A || !isX11InputMethodGRefInList(currentX11InputMethodInstance)
0N/A || NULL == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
0N/A || NULL == (statusWindow = pX11IMData->statusWindow)
0N/A || !statusWindow->on ){
0N/A AWT_UNLOCK();
0N/A return;
0N/A }
0N/A onoffStatusWindow(pX11IMData, 0, False);
0N/A
0N/A AWT_UNLOCK();
0N/A#endif
0N/A}
0N/A
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_awt_X11InputMethod_disposeXIC(JNIEnv *env,
0N/A jobject this)
0N/A{
0N/A X11InputMethodData *pX11IMData = NULL;
0N/A
0N/A AWT_LOCK();
0N/A pX11IMData = getX11InputMethodData(env, this);
0N/A if (pX11IMData == NULL) {
0N/A AWT_UNLOCK();
0N/A return;
0N/A }
0N/A
0N/A setX11InputMethodData(env, this, NULL);
0N/A
0N/A if (pX11IMData->x11inputmethod == currentX11InputMethodInstance) {
0N/A currentX11InputMethodInstance = NULL;
0N/A currentFocusWindow = 0;
0N/A }
0N/A destroyX11InputMethodData(env, pX11IMData);
0N/A AWT_UNLOCK();
0N/A}
0N/A
0N/AJNIEXPORT jstring JNICALL
0N/AJava_sun_awt_X11InputMethod_resetXIC(JNIEnv *env,
0N/A jobject this)
0N/A{
0N/A X11InputMethodData *pX11IMData;
0N/A char *xText = NULL;
0N/A jstring jText = (jstring)0;
0N/A
0N/A AWT_LOCK();
0N/A pX11IMData = getX11InputMethodData(env, this);
0N/A if (pX11IMData == NULL) {
0N/A AWT_UNLOCK();
0N/A return jText;
0N/A }
0N/A
0N/A if (pX11IMData->current_ic)
0N/A xText = XmbResetIC(pX11IMData->current_ic);
0N/A else {
0N/A /*
0N/A * If there is no reference to the current XIC, try to reset both XICs.
0N/A */
0N/A xText = XmbResetIC(pX11IMData->ic_active);
0N/A /*it may also means that the real client component does
0N/A not have focus -- has been deactivated... its xic should
0N/A not have the focus, bug#4284651 showes reset XIC for htt
0N/A may bring the focus back, so de-focus it again.
0N/A */
0N/A setXICFocus(pX11IMData->ic_active, FALSE);
0N/A if (pX11IMData->ic_active != pX11IMData->ic_passive) {
0N/A char *tmpText = XmbResetIC(pX11IMData->ic_passive);
0N/A setXICFocus(pX11IMData->ic_passive, FALSE);
0N/A if (xText == (char *)NULL && tmpText)
0N/A xText = tmpText;
0N/A }
0N/A
0N/A }
0N/A if (xText != NULL) {
0N/A jText = JNU_NewStringPlatform(env, (const char *)xText);
0N/A XFree((void *)xText);
0N/A }
0N/A
0N/A AWT_UNLOCK();
0N/A return jText;
0N/A}
0N/A
0N/A#ifndef XAWT
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_awt_motif_MInputMethod_configureStatusAreaNative(JNIEnv *env,
0N/A jobject this,
0N/A jobject tc)
0N/A{
0N/A X11InputMethodData *pX11IMData;
0N/A XVaNestedList status;
0N/A
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A /*do nothing for linux? */
0N/A#else
0N/A AWT_LOCK();
0N/A pX11IMData = getX11InputMethodData(env, this);
0N/A
0N/A if ((pX11IMData == NULL) || (pX11IMData->ic_active == (XIC)0)) {
0N/A AWT_UNLOCK();
0N/A return;
0N/A }
0N/A
0N/A if (pX11IMData->statusWidget) {
0N/A status = awt_motif_getXICStatusAreaList(pX11IMData->statusWidget, tc);
0N/A if (status != (XVaNestedList)NULL) {
0N/A XSetICValues(pX11IMData->ic_active,
0N/A XNStatusAttributes, status,
0N/A NULL);
0N/A XFree((void *)status);
0N/A }
0N/A }
0N/A AWT_UNLOCK();
0N/A#endif
0N/A}
0N/A#endif /* XAWT */
0N/A
0N/A/*
0N/A * Class: sun_awt_X11InputMethod
0N/A * Method: setCompositionEnabledNative
0N/A * Signature: (ZJ)V
0N/A *
0N/A * This method tries to set the XNPreeditState attribute associated with the current
0N/A * XIC to the passed in 'enable' state.
0N/A *
0N/A * Return JNI_TRUE if XNPreeditState attribute is successfully changed to the
0N/A * 'enable' state; Otherwise, if XSetICValues fails to set this attribute,
0N/A * java.lang.UnsupportedOperationException will be thrown. JNI_FALSE is returned if this
0N/A * method fails due to other reasons.
0N/A *
0N/A */
0N/AJNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethod_setCompositionEnabledNative
0N/A (JNIEnv *env, jobject this, jboolean enable)
0N/A{
0N/A X11InputMethodData *pX11IMData;
0N/A char * ret = NULL;
0N/A
0N/A AWT_LOCK();
0N/A pX11IMData = getX11InputMethodData(env, this);
0N/A
0N/A if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
0N/A AWT_UNLOCK();
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A ret = XSetICValues(pX11IMData->current_ic, XNPreeditState,
0N/A (enable ? XIMPreeditEnable : XIMPreeditDisable), NULL);
0N/A AWT_UNLOCK();
0N/A
0N/A if ((ret != 0) && (strcmp(ret, XNPreeditState) == 0)) {
0N/A JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
0N/A }
0N/A
0N/A return (jboolean)(ret == 0);
0N/A}
0N/A
0N/A/*
0N/A * Class: sun_awt_X11InputMethod
0N/A * Method: isCompositionEnabledNative
0N/A * Signature: (J)Z
0N/A *
0N/A * This method tries to get the XNPreeditState attribute associated with the current XIC.
0N/A *
0N/A * Return JNI_TRUE if the XNPreeditState is successfully retrieved. Otherwise, if
0N/A * XGetICValues fails to get this attribute, java.lang.UnsupportedOperationException
0N/A * will be thrown. JNI_FALSE is returned if this method fails due to other reasons.
0N/A *
0N/A */
0N/AJNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethod_isCompositionEnabledNative
0N/A (JNIEnv *env, jobject this)
0N/A{
0N/A X11InputMethodData *pX11IMData = NULL;
0N/A char * ret = NULL;
0N/A XIMPreeditState state;
0N/A
0N/A AWT_LOCK();
0N/A pX11IMData = getX11InputMethodData(env, this);
0N/A
0N/A if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
0N/A AWT_UNLOCK();
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A ret = XGetICValues(pX11IMData->current_ic, XNPreeditState, &state, NULL);
0N/A AWT_UNLOCK();
0N/A
0N/A if ((ret != 0) && (strcmp(ret, XNPreeditState) == 0)) {
0N/A JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A return (jboolean)(state == XIMPreeditEnable);
0N/A}
0N/A
0N/A#ifdef XAWT
0N/AJNIEXPORT void JNICALL Java_sun_awt_X11_XInputMethod_adjustStatusWindow
0N/A (JNIEnv *env, jobject this, jlong window)
0N/A{
4632N/A#if defined(__linux__) || defined(MACOSX)
0N/A AWT_LOCK();
0N/A adjustStatusWindow(window);
0N/A AWT_UNLOCK();
0N/A#endif
0N/A}
0N/A#endif