/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifdef HEADLESS
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef XAWT
#else /* !XAWT */
#include <Xm/RowColumn.h>
#include <Xm/MenuShell.h>
#endif /* XAWT */
#include "awt.h"
#include "awt_p.h"
#include <sun_awt_X11InputMethod.h>
#ifdef XAWT
#include <sun_awt_X11_XComponentPeer.h>
#include <sun_awt_X11_XInputMethod.h>
#else /* !XAWT */
#include <sun_awt_motif_MComponentPeer.h>
#include <sun_awt_motif_MInputMethod.h>
#endif /* XAWT */
#define THROW_OUT_OF_MEMORY_ERROR() \
struct X11InputMethodIDs {
#endif
#define PreeditStartIndex 0
#else
#endif
/*
* Callback function pointers: the order has to match the *Index
* values above.
*/
#endif
};
typedef struct {
Window w; /*status window id */
#ifdef XAWT
#else
#endif
int x, y; /*parent's upperleft position */
} StatusWindow;
#endif
/*
* X11InputMethodData keeps per X11InputMethod instance information. A pointer
* to this data structure is kept in an X11InputMethod object (pData).
*/
typedef struct _X11InputMethodData {
#ifndef XAWT
#endif /* XAWT */
/* associated with the XIC */
#else
#ifndef XAWT
#endif /* XAWT */
#endif
/*
* When XIC is created, a global reference is created for
* sun.awt.X11InputMethod object so that it could be used by the XIM callback
* functions. This could be a dangerous thing to do when the original
* X11InputMethod object is garbage collected and as a result,
* destroyX11InputMethodData is called to delete the global reference.
* If any XIM callback function still holds and uses the "already deleted"
* global reference, disaster is going to happen. So we have to maintain
* a list for these global references which is consulted first when the
* callback functions or any function tries to use "currentX11InputMethodObject"
* which always refers to the global reference try to use it.
*
*/
typedef struct _X11InputMethodGRefNode {
/* reference to the current X11InputMethod instance, it is always
point to the global reference to the X11InputMethodObject since
it could be referenced by different threads. */
method. (the best place to put this
information should be
currentX11InputMethodInstance's pData) */
#ifndef XAWT
#endif /* XAWT */
/* Solaris XIM Extention */
#ifdef __solaris__
/* Prototype for this function is missing in Solaris X11R6 Xlib.h */
extern char *XSetIMValues(
XIM /* im */, ...
#endif
);
#endif
#ifdef XAWT_HACK
/*
* This function is stolen from /src/solaris/hpi/src/system_md.c
* It is used in setting the time in Java-level InputEvents
*/
{
struct timeval t;
gettimeofday(&t, NULL);
}
#endif /* XAWT_HACK */
/*
* Converts the wchar_t string to a multi-byte string calling wcstombs(). A
* buffer is allocated by malloc() to store the multi-byte string. NULL is
* returned if the given wchar_t string pointer is NULL or buffer allocation is
* failed.
*/
static char *
{
size_t n;
char *mbs;
return NULL;
return NULL;
}
/* TODO: check return values... Handle invalid characters properly... */
return NULL;
return mbs;
}
#ifndef XAWT
/*
* Find a class for the given class name and return a global reference to the
* class.
*/
static jobject
{
}
return objectClass;
}
#endif /* XAWT */
/*
* Returns True if the global reference is still in the list,
* otherwise False.
*/
return False;
}
while (pX11InputMethodGRef != NULL) {
return True;
}
}
return False;
}
/*
* Add the new created global reference to the list.
*/
if (newX11InputMethodGRef == NULL ||
return;
}
return;
} else {
}
}
/*
* Remove the global reference from the list.
*/
if (x11InputMethodGRefListHead == NULL ||
x11InputMethodGRef == NULL) {
return;
}
/* cX11InputMethodGRef always refers to the current node while
pX11InputMethodGRef refers to the previous node.
*/
while (cX11InputMethodGRef != NULL) {
break;
}
}
if (cX11InputMethodGRef == NULL) {
return; /* Not found. */
}
} else {
}
return;
}
/*
* In case the XIM server was killed somehow, reset X11InputMethodData.
*/
"flushText",
"()V");
/* IMPORTANT:
The order of the following calls is critical since "imInstance" may
point to the global reference itself, if "freeX11InputMethodData" is called
first, the global reference will be destroyed and "setX11InputMethodData"
will in fact fail silently. So pX11IMData will not be set to NULL.
This could make the original java object refers to a deleted pX11IMData
object.
*/
pX11IMData = NULL;
}
return pX11IMData;
}
static void setX11InputMethodData(JNIEnv * env, jobject imInstance, X11InputMethodData *pX11IMData) {
}
/* this function should be called within AWT_LOCK() */
static void
{
/*
* Destroy XICs
*/
if (pX11IMData == NULL) {
return;
}
}
}
}
}
static void
{
}
}
#endif
if (pX11IMData->callbacks)
if (env) {
#ifndef XAWT
#endif /* XAWT */
/* Remove the global reference from the list, so that
the callback function or whoever refers to it could know.
*/
}
if (pX11IMData->lookup_buf) {
}
free((void *)pX11IMData);
}
/*
* Sets or unsets the focus to the given XIC.
*/
static void
{
return;
}
if (req == 1)
else
}
/*
* Sets the focus window to the given XIC.
*/
static void
{
return;
}
}
/*
* Invokes XmbLookupString() to get something from the XIM. It invokes
* X11InputMethod.dispatchCommittedText() if XmbLookupString() returns
* committed text. This function is called from handleKeyEvent in canvas.c and
* it's under the Motif event loop thread context.
*
* Buffer usage: There is a bug in XFree86-4.3.0 XmbLookupString implementation,
* where it never returns XBufferOverflow. We need to allocate the initial lookup buffer
* big enough, so that the possibility that user encounters this problem is relatively
* small. When this bug gets fixed, we can make the initial buffer size smaller.
* Note that XmbLookupString() sometimes produces a non-null-terminated string.
*
* Returns True when there is a keysym value to be handled.
*/
{
int mblen;
/*
printf("lookupString: entering...\n");
*/
return False;
}
if (pX11IMData == NULL) {
return False;
#else
return result;
#endif
}
return False;
#else
return result;
#endif
}
/* allocate the lookup buffer at the first invocation */
if (pX11IMData->lookup_buf_len == 0) {
return result;
}
}
/*
* In case of overflow, a buffer is allocated and it retries
* XmbLookupString().
*/
if (status == XBufferOverflow) {
pX11IMData->lookup_buf_len = 0;
return result;
}
}
/* Get keysym without taking modifiers into account first to map
* to AWT keyCode table.
*/
#ifndef XAWT
{
}
#endif
switch (status) {
case XLookupBoth:
if (!composing) {
#ifdef XAWT
#else
#endif
break;
}
}
/*FALLTHRU*/
case XLookupChars:
/*
printf("lookupString: status=XLookupChars, type=%d, state=%x, keycode=%x, keysym=%x\n",
event->type, event->state, event->keycode, keysym);
*/
"dispatchCommittedText",
#ifndef XAWT_HACK
#else
#endif
}
break;
case XLookupKeySym:
/*
printf("lookupString: status=XLookupKeySym, type=%d, state=%x, keycode=%x, keysym=%x\n",
event->type, event->state, event->keycode, keysym);
*/
if (keysym == XK_Multi_key)
if (! composing) {
}
break;
case XLookupNone:
/*
printf("lookupString: status=XLookupNone, type=%d, state=%x, keycode=%x, keysym=%x\n",
event->type, event->state, event->keycode, keysym);
*/
break;
}
return result;
}
#ifdef XAWT
#else
#endif
unsigned long attribmask;
/* Variable for XCreateFontSet()*/
char **mclr;
int mccr = 0;
char *dsr;
int screen = 0;
int i;
extern int awt_numScreens;
/*hardcode the size right now, should get the size base on font*/
unsigned int ignoreUnit;
#ifdef XAWT
#else
}
#endif
for (i = 0; i < awt_numScreens; i++) {
#ifdef XAWT
#else
#endif
screen = i;
break;
}
}
/*compare the size difference between parent container
and shell widget, the diff should be the border frame
and title bar height (?)*/
&ignoreUnit);
/*get the size of root window*/
&x, &y,
&child);
if (xx < 0 ){
xx = 0;
}
}
}
0,
attribmask, &attrib);
if (statusWindow == NULL){
return NULL;
}
statusWindow->w = status;
//12-point font
"-*-*-medium-r-normal-*-*-120-*-*-*-*",
/* In case we didn't find the font set, release the list of missing characters */
if (mccr > 0) {
}
statusWindow->x = x;
statusWindow->y = y;
return statusWindow;
}
/* This method is to turn off or turn on the status window. */
#ifdef XAWT
#else
#endif
int x, y;
if (NULL == currentX11InputMethodInstance ||
NULL == pX11IMData ||
return;
}
return;
}
#ifdef XAWT
"getCurrentParentWindow",
"()J").j;
#else
}
#endif
}
&x, &y,
&child);
if (statusWindow->x != x
|| statusWindow->y != y
statusWindow->x = x;
statusWindow->y = y;
if (x < 0 ){
x = 0;
}
}
}
}
}
/* draw border */
if (statusWindow->fontset){
}
else{
/*too bad we failed to create a fontset for this locale*/
}
}
return;
}
return;
}
case Expose:
break;
case MapNotify:
case ConfigureNotify:
{
/*need to reset the stackMode...*/
}
break;
/*
case UnmapNotify:
case VisibilityNotify:
break;
*/
default:
break;
}
}
#ifdef XAWT
#else
#endif
|| !statusWindow->on) {
return;
}
#ifdef XAWT
{
#else
#endif
int x, y;
&x, &y,
&child);
if (statusWindow->x != x
|| statusWindow->y != y
statusWindow->x = x;
statusWindow->y = y;
if (x < 0 ){
x = 0;
}
}
}
}
}
}
#endif /* __linux__ || MACOSX */
/*
* Creates two XICs, one for active clients and the other for passive
* clients. All information on those XICs are stored in the
* X11InputMethodData given by the pX11IMData parameter.
*
* For active clients: Try to use preedit callback to support
* on-the-spot. If tc is not null, the XIC to be created will
* share the Status Area with Motif widgets (TextComponents). If the
* preferable styles can't be used, fallback to root-window styles. If
* root-window styles failed, fallback to None styles.
*
* For passive clients: Try to use root-window styles. If failed,
* fallback to None styles.
*/
static Bool
#ifdef XAWT
#else /* !XAWT */
#endif /* XAWT */
{
active_styles = 0,
passive_styles = 0,
no_styles = 0;
unsigned short i;
return False;
}
#ifdef XAWT
if (!w) {
return False;
}
#else /* !XAWT */
/*
* If the parent window has one or more TextComponents, the status
* area of Motif will be shared with the created XIC. Otherwise,
* root-window style status is used.
*/
#endif /* XAWT */
return FALSE ;
}
/*kinput does not support XIMPreeditCallbacks and XIMStatusArea
at the same time, so use StatusCallback to draw the status
ourself
*/
for (i = 0; i < im_styles->count_styles; i++) {
break;
}
}
#else /*! __linux__ && !MACOSX */
#ifdef XAWT
#else /* !XAWT */
/*
* If the parent window has one or more TextComponents, the status
* area of Motif will be shared with the created XIC. Otherwise,
* root-window style status is used.
*/
}
else
}
else
#endif /* XAWT */
#endif /* __linux__ || MACOSX */
for (i = 0; i < im_styles->count_styles; i++) {
}
if (active_styles != on_the_spot_styles) {
if (passive_styles == ROOT_WINDOW_STYLES)
else {
else
active_styles = passive_styles = 0;
}
} else {
if (passive_styles != ROOT_WINDOW_STYLES) {
else
active_styles = passive_styles = 0;
}
}
if (active_styles == on_the_spot_styles) {
return False;
for (i = 0; i < NCALLBACKS; i++, callbacks++) {
}
NULL);
goto err;
/*always try XIMStatusCallbacks for active client...*/
{
NULL);
goto err;
XNClientWindow, w,
XNFocusWindow, w,
NULL);
}
#else /* !__linux__ && !MACOSX */
#ifndef XAWT
if (on_the_spot_styles & XIMStatusArea) {
goto err;
XNFocusWindow, w,
NULL);
} else {
#endif /* XAWT */
XNClientWindow, w,
XNFocusWindow, w,
NULL);
#ifndef XAWT
}
#endif /* XAWT */
#endif /* __linux__ || MACOSX */
XNClientWindow, w,
XNFocusWindow, w,
NULL);
} else {
XNClientWindow, w,
XNFocusWindow, w,
NULL);
}
return False;
}
/*
* Use commit string call back if possible.
* This will ensure the correct order of preedit text and commit text
*/
{
}
}
/* Add the global reference object to X11InputMethod to the list. */
return True;
err:
if (preedit)
return False;
}
static void
{
/*ARGSUSED*/
/* printf("Native: PreeditCaretCallback\n"); */
}
static void
{
/*ARGSUSED*/
/* printf("Native: StatusStartCallback\n"); */
}
/*
* Translate the preedit draw callback items to Java values and invoke
* X11InputMethod.dispatchComposedText().
*
* client_data: X11InputMethod object
*/
static void
{
/* printf("Native: PreeditDrawCallback() \n"); */
return;
}
AWT_LOCK();
}
goto finally;
}
goto finally;
}
} else {
goto finally;
}
}
}
int cnt;
goto finally;
}
if (sizeof(XIMFeedback) == sizeof(jint)) {
/*
* Optimization to avoid copying the array
*/
} else {
goto finally;
}
}
}
}
"dispatchComposedText",
AWT_UNLOCK();
return;
}
static void
{
/*ARGSUSED*/
/* printf("Native: PreeditCaretCallback\n"); */
}
static void
{
/*ARGSUSED*/
/*printf("StatusStartCallback:\n"); */
}
static void
{
/*ARGSUSED*/
/*printf("StatusDoneCallback:\n"); */
}
static void
{
/*ARGSUSED*/
/*printf("StatusDrawCallback:\n"); */
AWT_LOCK();
}
goto finally;
}
goto finally;
}
}
else{
}
}
else {
/*just turnoff the status window
paintStatusWindow(statusWindow);
*/
}
}
AWT_UNLOCK();
}
#endif /* __linux__ || MACOSX */
AWT_LOCK();
}
goto finally;
}
goto finally;
}
} else {
goto finally;
}
}
"dispatchCommittedText",
}
AWT_UNLOCK();
}
return;
}
}
/* mark that XIM server was destroyed */
/* free the old pX11IMData and set it to null. this also avoids crashing
* the jvm if the XIM server reappears */
}
/*
* Class: java_sun_awt_motif_X11InputMethod
* Method: initIDs
* Signature: ()V
*/
/* This function gets called from the static initializer for
to initialize the fieldIDs for fields that may be accessed from C */
{
}
#ifdef XAWT
#else
#endif
{
AWT_LOCK();
#ifdef XAWT
#else
dpy = awt_display;
#endif
/* Use IMInstantiate call back only on Linux, as there is a bug in Solaris
(4768335)
*/
if (!registered) {
/* directly call openXIM callback */
#endif
}
#endif
AWT_UNLOCK();
return JNI_TRUE;
}
#ifdef XAWT
{
#else /* !XAWT */
{
struct ComponentData *cdata;
#endif /* XAWT */
AWT_LOCK();
#ifdef XAWT
if (!window) {
#else /* !XAWT */
#endif /* XAWT */
AWT_UNLOCK();
return JNI_FALSE;
}
if (pX11IMData == NULL) {
AWT_UNLOCK();
return JNI_FALSE;
}
#ifndef XAWT
if (mcompClass == NULL) {
}
if (cdata == 0) {
free((void *)pX11IMData);
AWT_UNLOCK();
return JNI_FALSE;
}
#endif /* XAWT */
#else /* !__linux__ && !MACOSX */
#ifndef XAWT
#endif /* XAWT */
#endif /* __linux__ || MACOSX */
pX11IMData->lookup_buf = 0;
pX11IMData->lookup_buf_len = 0;
#ifdef XAWT
#else /* !XAWT */
#endif /* XAWT */
== False) {
}
AWT_UNLOCK();
return (pX11IMData != NULL);
}
#ifndef XAWT
{
AWT_LOCK();
if (pX11IMData == NULL) {
AWT_UNLOCK();
return;
}
} else {
struct ComponentData *cdata;
if (mcompClass == NULL) {
}
if (cdata == 0) {
}
/*
* On Solaris2.6, setXICWindowFocus() has to be invoked
* before setting focus.
*/
} else {
}
}
AWT_UNLOCK();
}
{
struct ComponentData *cdata;
Widget w;
#else /* !XAWT */
jlong w,
{
#endif /* XAWT */
AWT_LOCK();
if (pX11IMData == NULL) {
AWT_UNLOCK();
return;
}
if (req) {
#ifdef XAWT
if (!w) {
AWT_UNLOCK();
return;
}
#else /* !XAWT */
struct ComponentData *cdata;
AWT_UNLOCK();
return;
}
if (mcompClass == NULL) {
}
if (cdata == 0) {
AWT_UNLOCK();
return;
}
#endif /* XAWT */
/*
* On Solaris2.6, setXICWindowFocus() has to be invoked
* before setting focus.
*/
#ifndef XAWT
#endif /* XAWT */
currentFocusWindow = w;
#endif
} else {
currentFocusWindow = 0;
#endif
}
AWT_UNLOCK();
}
{
AWT_LOCK();
|| !statusWindow->on ){
AWT_UNLOCK();
return;
}
AWT_UNLOCK();
#endif
}
{
AWT_LOCK();
if (pX11IMData == NULL) {
AWT_UNLOCK();
return;
}
currentFocusWindow = 0;
}
AWT_UNLOCK();
}
{
AWT_LOCK();
if (pX11IMData == NULL) {
AWT_UNLOCK();
return jText;
}
if (pX11IMData->current_ic)
else {
/*
* If there is no reference to the current XIC, try to reset both XICs.
*/
/*it may also means that the real client component does
not have focus -- has been deactivated... its xic should
not have the focus, bug#4284651 showes reset XIC for htt
may bring the focus back, so de-focus it again.
*/
}
}
}
AWT_UNLOCK();
return jText;
}
#ifndef XAWT
{
/*do nothing for linux? */
#else
AWT_LOCK();
AWT_UNLOCK();
return;
}
if (pX11IMData->statusWidget) {
NULL);
}
}
AWT_UNLOCK();
#endif
}
#endif /* XAWT */
/*
* Class: sun_awt_X11InputMethod
* Method: setCompositionEnabledNative
* Signature: (ZJ)V
*
* This method tries to set the XNPreeditState attribute associated with the current
* XIC to the passed in 'enable' state.
*
* Return JNI_TRUE if XNPreeditState attribute is successfully changed to the
* 'enable' state; Otherwise, if XSetICValues fails to set this attribute,
* java.lang.UnsupportedOperationException will be thrown. JNI_FALSE is returned if this
* method fails due to other reasons.
*
*/
{
AWT_LOCK();
AWT_UNLOCK();
return JNI_FALSE;
}
AWT_UNLOCK();
}
}
/*
* Class: sun_awt_X11InputMethod
* Method: isCompositionEnabledNative
* Signature: (J)Z
*
* This method tries to get the XNPreeditState attribute associated with the current XIC.
*
* Return JNI_TRUE if the XNPreeditState is successfully retrieved. Otherwise, if
* XGetICValues fails to get this attribute, java.lang.UnsupportedOperationException
* will be thrown. JNI_FALSE is returned if this method fails due to other reasons.
*
*/
{
AWT_LOCK();
AWT_UNLOCK();
return JNI_FALSE;
}
AWT_UNLOCK();
return JNI_FALSE;
}
}
#ifdef XAWT
{
AWT_LOCK();
AWT_UNLOCK();
#endif
}
#endif