< prev index next >

src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c

Print this page
rev 50172 : 8201429: Support AIX Input Method Editor (IME) for AWT Input Method Framework (IMF)
   1 /*
   2  * Copyright (c) 1997, 2016, 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 #ifdef HEADLESS
  27     #error This file should not be included in headless library
  28 #endif


  29 
  30 #include <stdio.h>
  31 #include <stdlib.h>
  32 #include <X11/Xlib.h>
  33 #include <X11/keysym.h>
  34 #include <sys/time.h>


  35 
  36 #include "awt.h"
  37 #include "awt_p.h"
  38 
  39 #include <sun_awt_X11InputMethod.h>
  40 #include <sun_awt_X11_XInputMethod.h>
  41 
  42 #define THROW_OUT_OF_MEMORY_ERROR() \
  43         JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL)
  44 
  45 struct X11InputMethodIDs {
  46   jfieldID pData;
  47 } x11InputMethodIDs;
  48 
  49 static void PreeditStartCallback(XIC, XPointer, XPointer);
  50 static void PreeditDoneCallback(XIC, XPointer, XPointer);
  51 static void PreeditDrawCallback(XIC, XPointer,
  52                                 XIMPreeditDrawCallbackStruct *);
  53 static void PreeditCaretCallback(XIC, XPointer,
  54                                  XIMPreeditCaretCallbackStruct *);
  55 #if defined(__linux__) || defined(MACOSX)
  56 static void StatusStartCallback(XIC, XPointer, XPointer);
  57 static void StatusDoneCallback(XIC, XPointer, XPointer);
  58 static void StatusDrawCallback(XIC, XPointer,
  59                                XIMStatusDrawCallbackStruct *);
  60 #endif


 519         mblen = XmbLookupString(ic, event, pX11IMData->lookup_buf,
 520                             pX11IMData->lookup_buf_len - 1, &keysym, &status);
 521     }
 522     pX11IMData->lookup_buf[mblen] = 0;
 523 
 524     /* Get keysym without taking modifiers into account first to map
 525      * to AWT keyCode table.
 526      */
 527     switch (status) {
 528     case XLookupBoth:
 529         if (!composing) {
 530             if (event->keycode != 0) {
 531                 *keysymp = keysym;
 532                 result = False;
 533                 break;
 534             }
 535         }
 536         composing = False;
 537         /*FALLTHRU*/
 538     case XLookupChars:
 539     /*
 540      printf("lookupString: status=XLookupChars, type=%d, state=%x, keycode=%x, keysym=%x\n",
 541        event->type, event->state, event->keycode, keysym);
 542     */
 543         javastr = JNU_NewStringPlatform(env, (const char *)pX11IMData->lookup_buf);
 544         if (javastr != NULL) {
 545             JNU_CallMethodByName(env, NULL,
 546                                  currentX11InputMethodInstance,
 547                                  "dispatchCommittedText",
 548                                  "(Ljava/lang/String;J)V",
 549                                  javastr,
 550                                  event->time);
 551         }
 552         break;
 553 
 554     case XLookupKeySym:
 555     /*
 556      printf("lookupString: status=XLookupKeySym, type=%d, state=%x, keycode=%x, keysym=%x\n",
 557        event->type, event->state, event->keycode, keysym);
 558     */
 559         if (keysym == XK_Multi_key)
 560             composing = True;
 561         if (! composing) {
 562             *keysymp = keysym;
 563             result = False;
 564         }
 565         break;
 566 
 567     case XLookupNone:
 568     /*
 569      printf("lookupString: status=XLookupNone, type=%d, state=%x, keycode=%x, keysym=%x\n",
 570         event->type, event->state, event->keycode, keysym);
 571     */
 572         break;
 573     }
 574 
 575     return result;
 576 }
 577 
 578 #if defined(__linux__) || defined(MACOSX)
 579 static StatusWindow *createStatusWindow(
 580                                 Window parent) {
 581     StatusWindow *statusWindow;
 582     XSetWindowAttributes attrib;
 583     unsigned long attribmask;
 584     Window containerWindow;
 585     Window status;
 586     Window child;
 587     XWindowAttributes xwa;
 588     XWindowAttributes xxwa;
 589     /* Variable for XCreateFontSet()*/
 590     char **mclr;
 591     int  mccr = 0;
 592     char *dsr;
 593     unsigned long bg, fg, light, dim;
 594     int x, y, off_x, off_y, xx, yy;
 595     unsigned int w, h, bw, depth;
 596     XGCValues values;
 597     unsigned long valuemask = 0;  /*ignore XGCvalue and use defaults*/
 598     int screen = 0;
 599     int i;
 600     AwtGraphicsConfigDataPtr adata;
 601     extern int awt_numScreens;
 602     /*hardcode the size right now, should get the size base on font*/
 603     int   width=80, height=22;
 604     Window rootWindow;
 605     Window *ignoreWindowPtr;
 606     unsigned int ignoreUnit;
 607 
 608     XGetGeometry(dpy, parent, &rootWindow, &x, &y, &w, &h, &bw, &depth);
 609 
 610     attrib.override_redirect = True;
 611     attribmask = CWOverrideRedirect;
 612     for (i = 0; i < awt_numScreens; i++) {
 613         if (RootWindow(dpy, i) == rootWindow) {
 614             screen = i;
 615             break;
 616         }
 617     }
 618     adata = getDefaultConfig(screen);
 619     bg    = adata->AwtColorMatch(255, 255, 255, adata);
 620     fg    = adata->AwtColorMatch(0, 0, 0, adata);
 621     light = adata->AwtColorMatch(195, 195, 195, adata);
 622     dim   = adata->AwtColorMatch(128, 128, 128, adata);
 623 


 635                 &ignoreWindowPtr,
 636                 &ignoreUnit);
 637     XGetWindowAttributes(dpy, containerWindow, &xxwa);
 638 
 639     off_x = (xxwa.width - xwa.width) / 2;
 640     off_y = xxwa.height - xwa.height - off_x; /*it's magic:-) */
 641 
 642     /*get the size of root window*/
 643     XGetWindowAttributes(dpy, rootWindow, &xxwa);
 644 
 645     XTranslateCoordinates(dpy,
 646                           parent, xwa.root,
 647                           xwa.x, xwa.y,
 648                           &x, &y,
 649                           &child);
 650     xx = x - off_x;
 651     yy = y + xwa.height - off_y;
 652     if (xx < 0 ){
 653         xx = 0;
 654     }
 655     if (xx + width > xxwa.width){
 656         xx = xxwa.width - width;
 657     }
 658     if (yy + height > xxwa.height){
 659         yy = xxwa.height - height;
 660     }
 661 
 662     status =  XCreateWindow(dpy,
 663                             xwa.root,
 664                             xx, yy,
 665                             width, height,
 666                             0,
 667                             xwa.depth,
 668                             InputOutput,
 669                             adata->awt_visInfo.visual,
 670                             attribmask, &attrib);
 671     XSelectInput(dpy, status,
 672                  ExposureMask | StructureNotifyMask | EnterWindowMask |
 673                  LeaveWindowMask | VisibilityChangeMask);
 674     statusWindow = (StatusWindow*) calloc(1, sizeof(StatusWindow));
 675     if (statusWindow == NULL){
 676         THROW_OUT_OF_MEMORY_ERROR();
 677         return NULL;
 678     }


 707     statusWindow->bgGC = XCreateGC(dpy, status, valuemask, &values);
 708     XSetForeground(dpy, statusWindow->bgGC, bg);
 709     return statusWindow;
 710 }
 711 
 712 /* This method is to turn off or turn on the status window. */
 713 static void onoffStatusWindow(X11InputMethodData* pX11IMData,
 714                                 Window parent,
 715                                 Bool ON){
 716     XWindowAttributes xwa;
 717     Window child;
 718     int x, y;
 719     StatusWindow *statusWindow = NULL;
 720 
 721     if (NULL == currentX11InputMethodInstance ||
 722         NULL == pX11IMData ||
 723         NULL == (statusWindow =  pX11IMData->statusWindow)){
 724         return;
 725     }
 726 
 727     if (ON == False){
 728         XUnmapWindow(dpy, statusWindow->w);
 729         statusWindow->on = False;
 730         return;
 731     }
 732     parent = JNU_CallMethodByName(GetJNIEnv(), NULL, pX11IMData->x11inputmethod,
 733                                   "getCurrentParentWindow",
 734                                   "()J").j;
 735     if (statusWindow->parent != parent){
 736         statusWindow->parent = parent;
 737     }
 738     XGetWindowAttributes(dpy, parent, &xwa);
 739     XTranslateCoordinates(dpy,
 740                           parent, xwa.root,
 741                           xwa.x, xwa.y,
 742                           &x, &y,
 743                           &child);
 744     if (statusWindow->x != x
 745         || statusWindow->y != y
 746         || statusWindow->height != xwa.height){

 747         statusWindow->x = x;
 748         statusWindow->y = y;
 749         statusWindow->height = xwa.height;
 750         x = statusWindow->x - statusWindow->off_x;
 751         y = statusWindow->y + statusWindow->height - statusWindow->off_y;
 752         if (x < 0 ){
 753             x = 0;
 754         }
 755         if (x + statusWindow->statusW > statusWindow->rootW){
 756             x = statusWindow->rootW - statusWindow->statusW;
 757         }
 758         if (y + statusWindow->statusH > statusWindow->rootH){
 759             y = statusWindow->rootH - statusWindow->statusH;
 760         }
 761         XMoveWindow(dpy, statusWindow->w, x, y);
 762     }
 763     statusWindow->on = True;
 764     XMapWindow(dpy, statusWindow->w);
 765 }
 766 
 767 void paintStatusWindow(StatusWindow *statusWindow){
 768     Window  win  = statusWindow->w;
 769     GC  lightgc = statusWindow->lightGC;
 770     GC  dimgc = statusWindow->dimGC;
 771     GC  bggc = statusWindow->bgGC;
 772     GC  fggc = statusWindow->fgGC;
 773 
 774     int width = statusWindow->statusW;
 775     int height = statusWindow->statusH;
 776     int bwidth = statusWindow->bWidth;
 777     XFillRectangle(dpy, win, bggc, 0, 0, width, height);
 778     /* draw border */
 779     XDrawLine(dpy, win, fggc, 0, 0, width, 0);
 780     XDrawLine(dpy, win, fggc, 0, height-1, width-1, height-1);
 781     XDrawLine(dpy, win, fggc, 0, 0, 0, height-1);
 782     XDrawLine(dpy, win, fggc, width-1, 0, width-1, height-1);
 783 
 784     XDrawLine(dpy, win, lightgc, 1, 1, width-bwidth, 1);
 785     XDrawLine(dpy, win, lightgc, 1, 1, 1, height-2);
 786     XDrawLine(dpy, win, lightgc, 1, height-2, width-bwidth, height-2);
 787     XDrawLine(dpy, win, lightgc, width-bwidth-1, 1, width-bwidth-1, height-2);
 788 
 789     XDrawLine(dpy, win, dimgc, 2, 2, 2, height-3);
 790     XDrawLine(dpy, win, dimgc, 2, height-3, width-bwidth-1, height-3);
 791     XDrawLine(dpy, win, dimgc, 2, 2, width-bwidth-2, 2);
 792     XDrawLine(dpy, win, dimgc, width-bwidth, 2, width-bwidth, height-3);
 793     if (statusWindow->fontset){
 794         XmbDrawString(dpy, win, statusWindow->fontset, fggc,
 795                       bwidth + 2, height - bwidth - 4,
 796                       statusWindow->status,
 797                       strlen(statusWindow->status));
 798     }
 799     else{
 800         /*too bad we failed to create a fontset for this locale*/
 801         XDrawString(dpy, win, fggc, bwidth + 2, height - bwidth - 4,
 802                     "[InputMethod ON]", strlen("[InputMethod ON]"));
 803     }
 804 }
 805 
 806 void statusWindowEventHandler(XEvent event){
 807     JNIEnv *env = GetJNIEnv();
 808     X11InputMethodData *pX11IMData = NULL;
 809     StatusWindow *statusWindow;
 810 
 811     if (!isX11InputMethodGRefInList(currentX11InputMethodInstance)) {
 812         currentX11InputMethodInstance = NULL;
 813         return;
 814     }
 815 
 816     if (NULL == currentX11InputMethodInstance
 817         || NULL == (pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance))
 818         || NULL == (statusWindow = pX11IMData->statusWindow)
 819         || statusWindow->w != event.xany.window){
 820         return;
 821     }
 822 
 823     switch (event.type){
 824     case Expose:
 825         paintStatusWindow(statusWindow);
 826         break;
 827     case MapNotify:
 828     case ConfigureNotify:
 829         {
 830           /*need to reset the stackMode...*/
 831             XWindowChanges xwc;
 832             int value_make = CWStackMode;
 833             xwc.stack_mode = TopIf;
 834             XConfigureWindow(dpy, statusWindow->w, value_make, &xwc);
 835         }
 836         break;
 837         /*
 838     case UnmapNotify:
 839     case VisibilityNotify:
 840         break;
 841         */
 842     default:
 843         break;
 844   }
 845 }
 846 
 847 static void adjustStatusWindow(Window shell){
 848     JNIEnv *env = GetJNIEnv();
 849     X11InputMethodData *pX11IMData = NULL;
 850     StatusWindow *statusWindow;
 851 
 852     if (NULL == currentX11InputMethodInstance
 853         || !isX11InputMethodGRefInList(currentX11InputMethodInstance)
 854         || NULL == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
 855         || NULL == (statusWindow = pX11IMData->statusWindow)
 856         || !statusWindow->on) {

 857         return;
 858     }

 859     {
 860         XWindowAttributes xwa;
 861         int x, y;
 862         Window child;
 863         XGetWindowAttributes(dpy, shell, &xwa);
 864         XTranslateCoordinates(dpy,
 865                               shell, xwa.root,
 866                               xwa.x, xwa.y,
 867                               &x, &y,
 868                               &child);
 869         if (statusWindow->x != x
 870             || statusWindow->y != y
 871             || statusWindow->height != xwa.height){
 872           statusWindow->x = x;
 873           statusWindow->y = y;
 874           statusWindow->height = xwa.height;
 875 
 876           x = statusWindow->x - statusWindow->off_x;
 877           y = statusWindow->y + statusWindow->height - statusWindow->off_y;
 878           if (x < 0 ){
 879               x = 0;
 880           }
 881           if (x + statusWindow->statusW > statusWindow->rootW){
 882               x = statusWindow->rootW - statusWindow->statusW;
 883           }
 884           if (y + statusWindow->statusH > statusWindow->rootH){
 885               y = statusWindow->rootH - statusWindow->statusH;
 886           }
 887           XMoveWindow(dpy, statusWindow->w, x, y);
 888         }
 889     }
 890 }
 891 #endif  /* __linux__ || MACOSX */

 892 /*
 893  * Creates two XICs, one for active clients and the other for passive
 894  * clients. All information on those XICs are stored in the
 895  * X11InputMethodData given by the pX11IMData parameter.
 896  *
 897  * For active clients: Try to use preedit callback to support
 898  * on-the-spot. If tc is not null, the XIC to be created will
 899  * share the Status Area with Motif widgets (TextComponents). If the
 900  * preferable styles can't be used, fallback to root-window styles. If
 901  * root-window styles failed, fallback to None styles.
 902  *
 903  * For passive clients: Try to use root-window styles. If failed,
 904  * fallback to None styles.
 905  */
 906 static Bool
 907 createXIC(JNIEnv * env, X11InputMethodData *pX11IMData, Window w)
 908 {
 909     XVaNestedList preedit = NULL;
 910     XVaNestedList status = NULL;
 911     XIMStyle on_the_spot_styles = XIMPreeditCallbacks,


 914              no_styles = 0;
 915     XIMCallback *callbacks;
 916     unsigned short i;
 917     XIMStyles *im_styles;
 918     char *ret = NULL;
 919 
 920     if (X11im == NULL) {
 921         return False;
 922     }
 923     if (!w) {
 924         return False;
 925     }
 926 
 927     ret = XGetIMValues(X11im, XNQueryInputStyle, &im_styles, NULL);
 928 
 929     if (ret != NULL) {
 930         jio_fprintf(stderr,"XGetIMValues: %s\n",ret);
 931         return FALSE ;
 932     }
 933 
 934 #if defined(__linux__) || defined(MACOSX)
 935     on_the_spot_styles |= XIMStatusNothing;
 936 

 937     /*kinput does not support XIMPreeditCallbacks and XIMStatusArea
 938       at the same time, so use StatusCallback to draw the status
 939       ourself
 940     */
 941     for (i = 0; i < im_styles->count_styles; i++) {
 942         if (im_styles->supported_styles[i] == (XIMPreeditCallbacks | XIMStatusCallbacks)) {
 943             on_the_spot_styles = (XIMPreeditCallbacks | XIMStatusCallbacks);
 944             break;
 945         }
 946     }
 947 #else /*! __linux__ && !MACOSX */
 948     on_the_spot_styles |= XIMStatusNothing;
 949 #endif /* __linux__ || MACOSX */
 950 
 951     for (i = 0; i < im_styles->count_styles; i++) {
 952         active_styles |= im_styles->supported_styles[i] & on_the_spot_styles;
 953         passive_styles |= im_styles->supported_styles[i] & ROOT_WINDOW_STYLES;
 954         no_styles |= im_styles->supported_styles[i] & NO_STYLES;
 955     }
 956 
 957     XFree(im_styles);
 958 
 959     if (active_styles != on_the_spot_styles) {
 960         if (passive_styles == ROOT_WINDOW_STYLES)
 961             active_styles = passive_styles;
 962         else {
 963             if (no_styles == NO_STYLES)
 964                 active_styles = passive_styles = NO_STYLES;
 965             else
 966                 active_styles = passive_styles = 0;
 967         }
 968     } else {


1006             status = (XVaNestedList)XVaCreateNestedList(0,
1007                         XNStatusStartCallback, &callbacks[StatusStartIndex],
1008                         XNStatusDoneCallback,  &callbacks[StatusDoneIndex],
1009                         XNStatusDrawCallback, &callbacks[StatusDrawIndex],
1010                         NULL);
1011 
1012             if (status == NULL)
1013                 goto err;
1014             pX11IMData->statusWindow = createStatusWindow(w);
1015             pX11IMData->ic_active = XCreateIC(X11im,
1016                                               XNClientWindow, w,
1017                                               XNFocusWindow, w,
1018                                               XNInputStyle, active_styles,
1019                                               XNPreeditAttributes, preedit,
1020                                               XNStatusAttributes, status,
1021                                               NULL);
1022             XFree((void *)status);
1023             XFree((void *)preedit);
1024         }
1025 #else /* !__linux__ && !MACOSX */
1026             pX11IMData->ic_active = XCreateIC(X11im,
1027                                               XNClientWindow, w,
1028                                               XNFocusWindow, w,
1029                                               XNInputStyle, active_styles,
1030                                               XNPreeditAttributes, preedit,
1031                                               NULL);
1032         XFree((void *)preedit);
1033 #endif /* __linux__ || MACOSX */
1034     } else {
1035         pX11IMData->ic_active = XCreateIC(X11im,
1036                                           XNClientWindow, w,
1037                                           XNFocusWindow, w,
1038                                           XNInputStyle, active_styles,
1039                                           NULL);
1040         pX11IMData->ic_passive = pX11IMData->ic_active;
1041     }
1042 
1043     if (pX11IMData->ic_active == (XIC)0
1044         || pX11IMData->ic_passive == (XIC)0) {
1045         return False;
1046     }
1047 
1048     /*
1049      * Use commit string call back if possible.
1050      * This will ensure the correct order of preedit text and commit text
1051      */


1058             XSetICValues (pX11IMData->ic_passive, XNCommitStringCallback, &cb, NULL);
1059         }
1060     }
1061 
1062     /* Add the global reference object to X11InputMethod to the list. */
1063     addToX11InputMethodGRefList(pX11IMData->x11inputmethod);
1064 
1065     return True;
1066 
1067  err:
1068     if (preedit)
1069         XFree((void *)preedit);
1070     THROW_OUT_OF_MEMORY_ERROR();
1071     return False;
1072 }
1073 
1074 static void
1075 PreeditStartCallback(XIC ic, XPointer client_data, XPointer call_data)
1076 {
1077     /*ARGSUSED*/
1078     /* printf("Native: PreeditCaretCallback\n"); */
1079 }
1080 
1081 static void
1082 PreeditDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
1083 {
1084     /*ARGSUSED*/
1085     /* printf("Native: StatusStartCallback\n"); */
1086 }
1087 
1088 /*
1089  * Translate the preedit draw callback items to Java values and invoke
1090  * X11InputMethod.dispatchComposedText().
1091  *
1092  * client_data: X11InputMethod object
1093  */
1094 static void
1095 PreeditDrawCallback(XIC ic, XPointer client_data,
1096                     XIMPreeditDrawCallbackStruct *pre_draw)
1097 {
1098     JNIEnv *env = GetJNIEnv();
1099     X11InputMethodData *pX11IMData = NULL;
1100     jmethodID x11imMethodID;
1101 
1102     XIMText *text;
1103     jstring javastr = NULL;
1104     jintArray style = NULL;
1105 


1170     JNU_CallMethodByName(env, NULL, pX11IMData->x11inputmethod,
1171                          "dispatchComposedText",
1172                          "(Ljava/lang/String;[IIIIJ)V",
1173                          javastr,
1174                          style,
1175                          (jint)pre_draw->chg_first,
1176                          (jint)pre_draw->chg_length,
1177                          (jint)pre_draw->caret,
1178                          awt_util_nowMillisUTC());
1179 finally:
1180     AWT_UNLOCK();
1181     return;
1182 }
1183 
1184 static void
1185 PreeditCaretCallback(XIC ic, XPointer client_data,
1186                      XIMPreeditCaretCallbackStruct *pre_caret)
1187 {
1188     /*ARGSUSED*/
1189     /* printf("Native: PreeditCaretCallback\n"); */
1190 
1191 }
1192 
1193 #if defined(__linux__) || defined(MACOSX)
1194 static void
1195 StatusStartCallback(XIC ic, XPointer client_data, XPointer call_data)
1196 {
1197     /*ARGSUSED*/
1198     /*printf("StatusStartCallback:\n");  */
1199 
1200 }
1201 
1202 static void
1203 StatusDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
1204 {
1205     /*ARGSUSED*/
1206     /*printf("StatusDoneCallback:\n"); */
1207 
1208 }
1209 
1210 static void
1211 StatusDrawCallback(XIC ic, XPointer client_data,
1212                      XIMStatusDrawCallbackStruct *status_draw)
1213 {
1214     /*ARGSUSED*/
1215     /*printf("StatusDrawCallback:\n"); */
1216     JNIEnv *env = GetJNIEnv();
1217     X11InputMethodData *pX11IMData = NULL;
1218     StatusWindow *statusWindow;
1219 
1220     AWT_LOCK();
1221 
1222     if (!isX11InputMethodGRefInList((jobject)client_data)) {
1223         if ((jobject)client_data == currentX11InputMethodInstance) {
1224             currentX11InputMethodInstance = NULL;
1225         }
1226         goto finally;
1227     }
1228 
1229     if (NULL == (pX11IMData = getX11InputMethodData(env, (jobject)client_data))
1230         || NULL == (statusWindow = pX11IMData->statusWindow)){
1231         goto finally;
1232     }
1233    currentX11InputMethodInstance = (jobject)client_data;
1234 
1235     if (status_draw->type == XIMTextType){
1236         XIMText *text = (status_draw->data).text;
1237         if (text != NULL){
1238           if (text->string.multi_byte != NULL) {
1239               strncpy(statusWindow->status, text->string.multi_byte, MAX_STATUS_LEN);
1240               statusWindow->status[MAX_STATUS_LEN - 1] = '\0';
1241           }
1242           else {
1243               char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
1244               strncpy(statusWindow->status, mbstr, MAX_STATUS_LEN);
1245               statusWindow->status[MAX_STATUS_LEN - 1] = '\0';
1246           }
1247           statusWindow->on = True;
1248           onoffStatusWindow(pX11IMData, statusWindow->parent, True);
1249           paintStatusWindow(statusWindow);
1250         }
1251         else {
1252             statusWindow->on = False;
1253             /*just turnoff the status window
1254             paintStatusWindow(statusWindow);
1255             */
1256             onoffStatusWindow(pX11IMData, 0, False);
1257         }
1258     }
1259 
1260  finally:
1261     AWT_UNLOCK();
1262 }
1263 #endif /* __linux__ || MACOSX */
1264 
1265 static void CommitStringCallback(XIC ic, XPointer client_data, XPointer call_data) {
1266     JNIEnv *env = GetJNIEnv();
1267     XIMText * text = (XIMText *)call_data;
1268     X11InputMethodData *pX11IMData = NULL;
1269     jstring javastr;
1270 
1271     AWT_LOCK();


1310 
1311     X11im = XOpenIM(display, NULL, NULL, NULL);
1312     if (X11im == NULL) {
1313         return;
1314     }
1315 
1316     ximCallback.callback = (XIMProc)DestroyXIMCallback;
1317     ximCallback.client_data = NULL;
1318     XSetIMValues(X11im, XNDestroyCallback, &ximCallback, NULL);
1319 }
1320 
1321 static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) {
1322     /* mark that XIM server was destroyed */
1323     X11im = NULL;
1324     JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1325     /* free the old pX11IMData and set it to null. this also avoids crashing
1326      * the jvm if the XIM server reappears */
1327     X11InputMethodData *pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
1328 }
1329 
1330 /*
1331  * Class:     sun_awt_X11InputMethod
1332  * Method:    initIDs
1333  * Signature: ()V
1334  */
1335 
1336 /* This function gets called from the static initializer for
1337    X11InputMethod.java
1338    to initialize the fieldIDs for fields that may be accessed from C */
1339 JNIEXPORT void JNICALL
1340 Java_sun_awt_X11InputMethod_initIDs(JNIEnv *env, jclass cls)
1341 {
1342     x11InputMethodIDs.pData = (*env)->GetFieldID(env, cls, "pData", "J");
1343 }
1344 
1345 
1346 JNIEXPORT jboolean JNICALL
1347 Java_sun_awt_X11_XInputMethod_openXIMNative(JNIEnv *env,
1348                                           jobject this,
1349                                           jlong display)
1350 {
1351     Bool registered;
1352 
1353     AWT_LOCK();
1354 
1355     dpy = (Display *)jlong_to_ptr(display);
1356 
1357 /* Use IMInstantiate call back only on Linux, as there is a bug in Solaris
1358    (4768335)
1359 */
1360 #if defined(__linux__) || defined(MACOSX)
1361     registered = XRegisterIMInstantiateCallback(dpy, NULL, NULL,
1362                      NULL, (XIDProc)OpenXIMCallback, NULL);
1363     if (!registered) {
1364         /* directly call openXIM callback */
1365 #endif
1366         OpenXIMCallback(dpy, NULL, NULL);
1367 #if defined(__linux__) || defined(MACOSX)
1368     }
1369 #endif
1370 
1371     AWT_UNLOCK();
1372 
1373     return JNI_TRUE;
1374 }
1375 
1376 JNIEXPORT jboolean JNICALL
1377 Java_sun_awt_X11_XInputMethod_createXICNative(JNIEnv *env,
1378                                                   jobject this,
1379                                                   jlong window)
1380 {
1381     X11InputMethodData *pX11IMData;
1382     jobject globalRef;
1383     XIC ic;
1384 
1385     AWT_LOCK();
1386 
1387     if (!window) {
1388         JNU_ThrowNullPointerException(env, "NullPointerException");
1389         AWT_UNLOCK();
1390         return JNI_FALSE;
1391     }
1392 
1393     pX11IMData = (X11InputMethodData *) calloc(1, sizeof(X11InputMethodData));
1394     if (pX11IMData == NULL) {
1395         THROW_OUT_OF_MEMORY_ERROR();
1396         AWT_UNLOCK();
1397         return JNI_FALSE;
1398     }
1399 


1406     pX11IMData->lookup_buf = 0;
1407     pX11IMData->lookup_buf_len = 0;
1408 
1409     if (createXIC(env, pX11IMData, (Window)window) == False) {
1410         destroyX11InputMethodData((JNIEnv *) NULL, pX11IMData);
1411         pX11IMData = (X11InputMethodData *) NULL;
1412         if ((*env)->ExceptionCheck(env)) {
1413             goto finally;
1414         }
1415     }
1416 
1417     setX11InputMethodData(env, this, pX11IMData);
1418 
1419 finally:
1420     AWT_UNLOCK();
1421     return (pX11IMData != NULL);
1422 }
1423 
1424 JNIEXPORT void JNICALL
1425 Java_sun_awt_X11_XInputMethod_setXICFocusNative(JNIEnv *env,
1426                                               jobject this,
1427                                               jlong w,
1428                                               jboolean req,
1429                                               jboolean active)
1430 {
1431     X11InputMethodData *pX11IMData;
1432     AWT_LOCK();
1433     pX11IMData = getX11InputMethodData(env, this);
1434     if (pX11IMData == NULL) {
1435         AWT_UNLOCK();
1436         return;
1437     }
1438 
1439     if (req) {
1440         if (!w) {
1441             AWT_UNLOCK();
1442             return;
1443         }
1444         pX11IMData->current_ic = active ?
1445                         pX11IMData->ic_active : pX11IMData->ic_passive;
1446         /*
1447          * On Solaris2.6, setXICWindowFocus() has to be invoked
1448          * before setting focus.
1449          */


1454 #if defined(__linux__) || defined(MACOSX)
1455         if (active && pX11IMData->statusWindow && pX11IMData->statusWindow->on)
1456             onoffStatusWindow(pX11IMData, w, True);
1457 #endif
1458     } else {
1459         currentX11InputMethodInstance = NULL;
1460         currentFocusWindow = 0;
1461 #if defined(__linux__) || defined(MACOSX)
1462         onoffStatusWindow(pX11IMData, 0, False);
1463         if (pX11IMData->current_ic != NULL)
1464 #endif
1465         setXICFocus(pX11IMData->current_ic, req);
1466 
1467         pX11IMData->current_ic = (XIC)0;
1468     }
1469 
1470     XFlush(dpy);
1471     AWT_UNLOCK();
1472 }
1473 
1474 JNIEXPORT void JNICALL
1475 Java_sun_awt_X11InputMethod_turnoffStatusWindow(JNIEnv *env,
1476                                                 jobject this)


















1477 {
1478 #if defined(__linux__) || defined(MACOSX)
1479     X11InputMethodData *pX11IMData;
1480     StatusWindow *statusWindow;
1481 
1482     AWT_LOCK();
1483 
1484     if (NULL == currentX11InputMethodInstance
1485         || !isX11InputMethodGRefInList(currentX11InputMethodInstance)
1486         || NULL == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
1487         || NULL == (statusWindow = pX11IMData->statusWindow)
1488         || !statusWindow->on ){
1489         AWT_UNLOCK();
1490         return;
1491     }
1492     onoffStatusWindow(pX11IMData, 0, False);
1493 
1494     AWT_UNLOCK();
1495 #endif
1496 }
1497 
1498 JNIEXPORT void JNICALL
1499 Java_sun_awt_X11InputMethod_disposeXIC(JNIEnv *env,
1500                                              jobject this)




1501 {
1502     X11InputMethodData *pX11IMData = NULL;
1503 
1504     AWT_LOCK();
1505     pX11IMData = getX11InputMethodData(env, this);
1506     if (pX11IMData == NULL) {
1507         AWT_UNLOCK();
1508         return;
1509     }
1510 
1511     setX11InputMethodData(env, this, NULL);
1512 
1513     if (pX11IMData->x11inputmethod == currentX11InputMethodInstance) {
1514         currentX11InputMethodInstance = NULL;
1515         currentFocusWindow = 0;
1516     }
1517     destroyX11InputMethodData(env, pX11IMData);
1518     AWT_UNLOCK();
1519 }
1520 
1521 JNIEXPORT jstring JNICALL
1522 Java_sun_awt_X11InputMethod_resetXIC(JNIEnv *env,
1523                                            jobject this)




1524 {
1525     X11InputMethodData *pX11IMData;
1526     char *xText = NULL;
1527     jstring jText = (jstring)0;
1528 
1529     AWT_LOCK();
1530     pX11IMData = getX11InputMethodData(env, this);
1531     if (pX11IMData == NULL) {
1532         AWT_UNLOCK();
1533         return jText;
1534     }
1535 
1536     if (pX11IMData->current_ic)
1537         xText = XmbResetIC(pX11IMData->current_ic);
1538     else {
1539         /*
1540          * If there is no reference to the current XIC, try to reset both XICs.
1541          */
1542         xText = XmbResetIC(pX11IMData->ic_active);
1543         /*it may also means that the real client component does


1547         */
1548         setXICFocus(pX11IMData->ic_active, FALSE);
1549         if (pX11IMData->ic_active != pX11IMData->ic_passive) {
1550             char *tmpText = XmbResetIC(pX11IMData->ic_passive);
1551             setXICFocus(pX11IMData->ic_passive, FALSE);
1552             if (xText == (char *)NULL && tmpText)
1553                 xText = tmpText;
1554         }
1555 
1556     }
1557     if (xText != NULL) {
1558         jText = JNU_NewStringPlatform(env, (const char *)xText);
1559         XFree((void *)xText);
1560     }
1561 
1562     AWT_UNLOCK();
1563     return jText;
1564 }
1565 
1566 /*
1567  * Class:     sun_awt_X11InputMethod
1568  * Method:    setCompositionEnabledNative
1569  * Signature: (ZJ)V
1570  *
1571  * This method tries to set the XNPreeditState attribute associated with the current
1572  * XIC to the passed in 'enable' state.
1573  *
1574  * Return JNI_TRUE if XNPreeditState attribute is successfully changed to the
1575  * 'enable' state; Otherwise, if XSetICValues fails to set this attribute,
1576  * java.lang.UnsupportedOperationException will be thrown. JNI_FALSE is returned if this
1577  * method fails due to other reasons.
1578  *
1579  */
1580 JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethod_setCompositionEnabledNative
1581   (JNIEnv *env, jobject this, jboolean enable)
1582 {
1583     X11InputMethodData *pX11IMData;
1584     char * ret = NULL;
1585 
1586     AWT_LOCK();
1587     pX11IMData = getX11InputMethodData(env, this);
1588 
1589     if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
1590         AWT_UNLOCK();
1591         return JNI_FALSE;
1592     }
1593 
1594     ret = XSetICValues(pX11IMData->current_ic, XNPreeditState,
1595                        (enable ? XIMPreeditEnable : XIMPreeditDisable), NULL);
1596     AWT_UNLOCK();
1597 
1598     if ((ret != 0) && (strcmp(ret, XNPreeditState) == 0)) {
1599         JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
1600     }
1601 
1602     return (jboolean)(ret == 0);
1603 }
1604 
1605 /*
1606  * Class:     sun_awt_X11InputMethod
1607  * Method:    isCompositionEnabledNative
1608  * Signature: (J)Z
1609  *
1610  * This method tries to get the XNPreeditState attribute associated with the current XIC.
1611  *
1612  * Return JNI_TRUE if the XNPreeditState is successfully retrieved. Otherwise, if
1613  * XGetICValues fails to get this attribute, java.lang.UnsupportedOperationException
1614  * will be thrown. JNI_FALSE is returned if this method fails due to other reasons.
1615  *
1616  */
1617 JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethod_isCompositionEnabledNative
1618   (JNIEnv *env, jobject this)
1619 {
1620     X11InputMethodData *pX11IMData = NULL;
1621     char * ret = NULL;
1622     XIMPreeditState state;
1623 
1624     AWT_LOCK();
1625     pX11IMData = getX11InputMethodData(env, this);
1626 
1627     if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
1628         AWT_UNLOCK();
1629         return JNI_FALSE;
1630     }
1631 
1632     ret = XGetICValues(pX11IMData->current_ic, XNPreeditState, &state, NULL);
1633     AWT_UNLOCK();
1634 
1635     if ((ret != 0) && (strcmp(ret, XNPreeditState) == 0)) {
1636         JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
1637         return JNI_FALSE;
   1 /*
   2  * Copyright (c) 1997, 2018, 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 #include "awt.h"
  27 #include "awt_p.h"
  28 
  29 #include <sun_awt_X11InputMethodBase.h>
  30 #include <sun_awt_X11_XInputMethod.h>
  31 
  32 #include <stdio.h>
  33 #include <stdlib.h>


  34 #include <sys/time.h>
  35 #include <X11/keysym.h>
  36 #include <X11/Xlib.h>
  37 
  38 #ifdef HEADLESS
  39     #error This file should not be included in headless library
  40 #endif


  41 
  42 #define THROW_OUT_OF_MEMORY_ERROR() \
  43         JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL)
  44 
  45 struct X11InputMethodIDs {
  46   jfieldID pData;
  47 } x11InputMethodIDs;
  48 
  49 static void PreeditStartCallback(XIC, XPointer, XPointer);
  50 static void PreeditDoneCallback(XIC, XPointer, XPointer);
  51 static void PreeditDrawCallback(XIC, XPointer,
  52                                 XIMPreeditDrawCallbackStruct *);
  53 static void PreeditCaretCallback(XIC, XPointer,
  54                                  XIMPreeditCaretCallbackStruct *);
  55 #if defined(__linux__) || defined(MACOSX)
  56 static void StatusStartCallback(XIC, XPointer, XPointer);
  57 static void StatusDoneCallback(XIC, XPointer, XPointer);
  58 static void StatusDrawCallback(XIC, XPointer,
  59                                XIMStatusDrawCallbackStruct *);
  60 #endif


 519         mblen = XmbLookupString(ic, event, pX11IMData->lookup_buf,
 520                             pX11IMData->lookup_buf_len - 1, &keysym, &status);
 521     }
 522     pX11IMData->lookup_buf[mblen] = 0;
 523 
 524     /* Get keysym without taking modifiers into account first to map
 525      * to AWT keyCode table.
 526      */
 527     switch (status) {
 528     case XLookupBoth:
 529         if (!composing) {
 530             if (event->keycode != 0) {
 531                 *keysymp = keysym;
 532                 result = False;
 533                 break;
 534             }
 535         }
 536         composing = False;
 537         /*FALLTHRU*/
 538     case XLookupChars:
 539         /*
 540         printf("lookupString: status=XLookupChars, type=%d, state=%x, keycode=%x, keysym=%x\n",
 541                event->type, event->state, event->keycode, keysym);
 542         */
 543         javastr = JNU_NewStringPlatform(env, (const char *)pX11IMData->lookup_buf);
 544         if (javastr != NULL) {
 545             JNU_CallMethodByName(env, NULL,
 546                                  currentX11InputMethodInstance,
 547                                  "dispatchCommittedText",
 548                                  "(Ljava/lang/String;J)V",
 549                                  javastr,
 550                                  event->time);
 551         }
 552         break;
 553 
 554     case XLookupKeySym:
 555         /*
 556         printf("lookupString: status=XLookupKeySym, type=%d, state=%x, keycode=%x, keysym=%x\n",
 557                event->type, event->state, event->keycode, keysym);
 558         */
 559         if (keysym == XK_Multi_key)
 560             composing = True;
 561         if (! composing) {
 562             *keysymp = keysym;
 563             result = False;
 564         }
 565         break;
 566 
 567     case XLookupNone:
 568         /*
 569         printf("lookupString: status=XLookupNone, type=%d, state=%x, keycode=%x, keysym=%x\n",
 570                event->type, event->state, event->keycode, keysym);
 571         */
 572         break;
 573     }
 574 
 575     return result;
 576 }
 577 
 578 #if defined(__linux__) || defined(MACOSX)
 579 static StatusWindow *createStatusWindow(Window parent) {

 580     StatusWindow *statusWindow;
 581     XSetWindowAttributes attrib;
 582     unsigned long attribmask;
 583     Window containerWindow;
 584     Window status;
 585     Window child;
 586     XWindowAttributes xwa;
 587     XWindowAttributes xxwa;
 588     /* Variable for XCreateFontSet()*/
 589     char **mclr;
 590     int  mccr = 0;
 591     char *dsr;
 592     unsigned long bg, fg, light, dim;
 593     int x, y, off_x, off_y, xx, yy;
 594     unsigned int w, h, bw, depth;
 595     XGCValues values;
 596     unsigned long valuemask = 0;  /*ignore XGCvalue and use defaults*/
 597     int screen = 0;
 598     int i;
 599     AwtGraphicsConfigDataPtr adata;
 600     extern int awt_numScreens;
 601     /*hardcode the size right now, should get the size base on font*/
 602     int width=80, height=22;
 603     Window rootWindow;
 604     Window *ignoreWindowPtr;
 605     unsigned int ignoreUnit;
 606 
 607     XGetGeometry(dpy, parent, &rootWindow, &x, &y, &w, &h, &bw, &depth);
 608 
 609     attrib.override_redirect = True;
 610     attribmask = CWOverrideRedirect;
 611     for (i = 0; i < awt_numScreens; i++) {
 612         if (RootWindow(dpy, i) == rootWindow) {
 613             screen = i;
 614             break;
 615         }
 616     }
 617     adata = getDefaultConfig(screen);
 618     bg    = adata->AwtColorMatch(255, 255, 255, adata);
 619     fg    = adata->AwtColorMatch(0, 0, 0, adata);
 620     light = adata->AwtColorMatch(195, 195, 195, adata);
 621     dim   = adata->AwtColorMatch(128, 128, 128, adata);
 622 


 634                 &ignoreWindowPtr,
 635                 &ignoreUnit);
 636     XGetWindowAttributes(dpy, containerWindow, &xxwa);
 637 
 638     off_x = (xxwa.width - xwa.width) / 2;
 639     off_y = xxwa.height - xwa.height - off_x; /*it's magic:-) */
 640 
 641     /*get the size of root window*/
 642     XGetWindowAttributes(dpy, rootWindow, &xxwa);
 643 
 644     XTranslateCoordinates(dpy,
 645                           parent, xwa.root,
 646                           xwa.x, xwa.y,
 647                           &x, &y,
 648                           &child);
 649     xx = x - off_x;
 650     yy = y + xwa.height - off_y;
 651     if (xx < 0 ){
 652         xx = 0;
 653     }
 654     if (xx + width > xxwa.width) {
 655         xx = xxwa.width - width;
 656     }
 657     if (yy + height > xxwa.height) {
 658         yy = xxwa.height - height;
 659     }
 660 
 661     status =  XCreateWindow(dpy,
 662                             xwa.root,
 663                             xx, yy,
 664                             width, height,
 665                             0,
 666                             xwa.depth,
 667                             InputOutput,
 668                             adata->awt_visInfo.visual,
 669                             attribmask, &attrib);
 670     XSelectInput(dpy, status,
 671                  ExposureMask | StructureNotifyMask | EnterWindowMask |
 672                  LeaveWindowMask | VisibilityChangeMask);
 673     statusWindow = (StatusWindow*) calloc(1, sizeof(StatusWindow));
 674     if (statusWindow == NULL){
 675         THROW_OUT_OF_MEMORY_ERROR();
 676         return NULL;
 677     }


 706     statusWindow->bgGC = XCreateGC(dpy, status, valuemask, &values);
 707     XSetForeground(dpy, statusWindow->bgGC, bg);
 708     return statusWindow;
 709 }
 710 
 711 /* This method is to turn off or turn on the status window. */
 712 static void onoffStatusWindow(X11InputMethodData* pX11IMData,
 713                                 Window parent,
 714                                 Bool ON){
 715     XWindowAttributes xwa;
 716     Window child;
 717     int x, y;
 718     StatusWindow *statusWindow = NULL;
 719 
 720     if (NULL == currentX11InputMethodInstance ||
 721         NULL == pX11IMData ||
 722         NULL == (statusWindow =  pX11IMData->statusWindow)){
 723         return;
 724     }
 725 
 726     if (ON == False) {
 727         XUnmapWindow(dpy, statusWindow->w);
 728         statusWindow->on = False;
 729         return;
 730     }
 731     parent = JNU_CallMethodByName(GetJNIEnv(), NULL, pX11IMData->x11inputmethod,
 732                                   "getCurrentParentWindow",
 733                                   "()J").j;
 734     if (statusWindow->parent != parent) {
 735         statusWindow->parent = parent;
 736     }
 737     XGetWindowAttributes(dpy, parent, &xwa);
 738     XTranslateCoordinates(dpy,
 739                           parent, xwa.root,
 740                           xwa.x, xwa.y,
 741                           &x, &y,
 742                           &child);
 743     if (statusWindow->x != x ||
 744         statusWindow->y != y ||
 745         statusWindow->height != xwa.height)
 746     {
 747         statusWindow->x = x;
 748         statusWindow->y = y;
 749         statusWindow->height = xwa.height;
 750         x = statusWindow->x - statusWindow->off_x;
 751         y = statusWindow->y + statusWindow->height - statusWindow->off_y;
 752         if (x < 0 ) {
 753             x = 0;
 754         }
 755         if (x + statusWindow->statusW > statusWindow->rootW) {
 756             x = statusWindow->rootW - statusWindow->statusW;
 757         }
 758         if (y + statusWindow->statusH > statusWindow->rootH) {
 759             y = statusWindow->rootH - statusWindow->statusH;
 760         }
 761         XMoveWindow(dpy, statusWindow->w, x, y);
 762     }
 763     statusWindow->on = True;
 764     XMapWindow(dpy, statusWindow->w);
 765 }
 766 
 767 void paintStatusWindow(StatusWindow *statusWindow){
 768     Window  win  = statusWindow->w;
 769     GC  lightgc = statusWindow->lightGC;
 770     GC  dimgc = statusWindow->dimGC;
 771     GC  bggc = statusWindow->bgGC;
 772     GC  fggc = statusWindow->fgGC;
 773 
 774     int width = statusWindow->statusW;
 775     int height = statusWindow->statusH;
 776     int bwidth = statusWindow->bWidth;
 777     XFillRectangle(dpy, win, bggc, 0, 0, width, height);
 778     /* draw border */
 779     XDrawLine(dpy, win, fggc, 0, 0, width, 0);
 780     XDrawLine(dpy, win, fggc, 0, height-1, width-1, height-1);
 781     XDrawLine(dpy, win, fggc, 0, 0, 0, height-1);
 782     XDrawLine(dpy, win, fggc, width-1, 0, width-1, height-1);
 783 
 784     XDrawLine(dpy, win, lightgc, 1, 1, width-bwidth, 1);
 785     XDrawLine(dpy, win, lightgc, 1, 1, 1, height-2);
 786     XDrawLine(dpy, win, lightgc, 1, height-2, width-bwidth, height-2);
 787     XDrawLine(dpy, win, lightgc, width-bwidth-1, 1, width-bwidth-1, height-2);
 788 
 789     XDrawLine(dpy, win, dimgc, 2, 2, 2, height-3);
 790     XDrawLine(dpy, win, dimgc, 2, height-3, width-bwidth-1, height-3);
 791     XDrawLine(dpy, win, dimgc, 2, 2, width-bwidth-2, 2);
 792     XDrawLine(dpy, win, dimgc, width-bwidth, 2, width-bwidth, height-3);
 793     if (statusWindow->fontset) {
 794         XmbDrawString(dpy, win, statusWindow->fontset, fggc,
 795                       bwidth + 2, height - bwidth - 4,
 796                       statusWindow->status,
 797                       strlen(statusWindow->status));
 798     } else {

 799         /*too bad we failed to create a fontset for this locale*/
 800         XDrawString(dpy, win, fggc, bwidth + 2, height - bwidth - 4,
 801                     "[InputMethod ON]", strlen("[InputMethod ON]"));
 802     }
 803 }
 804 
 805 static void adjustStatusWindow(Window shell) {









































 806     JNIEnv *env = GetJNIEnv();
 807     X11InputMethodData *pX11IMData = NULL;
 808     StatusWindow *statusWindow;
 809 
 810     if (NULL == currentX11InputMethodInstance
 811         || !isX11InputMethodGRefInList(currentX11InputMethodInstance)
 812         || NULL == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
 813         || NULL == (statusWindow = pX11IMData->statusWindow)
 814         || !statusWindow->on)
 815     {
 816         return;
 817     }
 818 
 819     {
 820         XWindowAttributes xwa;
 821         int x, y;
 822         Window child;
 823         XGetWindowAttributes(dpy, shell, &xwa);
 824         XTranslateCoordinates(dpy,
 825                               shell, xwa.root,
 826                               xwa.x, xwa.y,
 827                               &x, &y,
 828                               &child);
 829         if (statusWindow->x != x
 830             || statusWindow->y != y
 831             || statusWindow->height != xwa.height){
 832           statusWindow->x = x;
 833           statusWindow->y = y;
 834           statusWindow->height = xwa.height;
 835 
 836           x = statusWindow->x - statusWindow->off_x;
 837           y = statusWindow->y + statusWindow->height - statusWindow->off_y;
 838           if (x < 0 ) {
 839               x = 0;
 840           }
 841           if (x + statusWindow->statusW > statusWindow->rootW){
 842               x = statusWindow->rootW - statusWindow->statusW;
 843           }
 844           if (y + statusWindow->statusH > statusWindow->rootH){
 845               y = statusWindow->rootH - statusWindow->statusH;
 846           }
 847           XMoveWindow(dpy, statusWindow->w, x, y);
 848         }
 849     }
 850 }
 851 #endif  /* __linux__ || MACOSX */
 852 
 853 /*
 854  * Creates two XICs, one for active clients and the other for passive
 855  * clients. All information on those XICs are stored in the
 856  * X11InputMethodData given by the pX11IMData parameter.
 857  *
 858  * For active clients: Try to use preedit callback to support
 859  * on-the-spot. If tc is not null, the XIC to be created will
 860  * share the Status Area with Motif widgets (TextComponents). If the
 861  * preferable styles can't be used, fallback to root-window styles. If
 862  * root-window styles failed, fallback to None styles.
 863  *
 864  * For passive clients: Try to use root-window styles. If failed,
 865  * fallback to None styles.
 866  */
 867 static Bool
 868 createXIC(JNIEnv * env, X11InputMethodData *pX11IMData, Window w)
 869 {
 870     XVaNestedList preedit = NULL;
 871     XVaNestedList status = NULL;
 872     XIMStyle on_the_spot_styles = XIMPreeditCallbacks,


 875              no_styles = 0;
 876     XIMCallback *callbacks;
 877     unsigned short i;
 878     XIMStyles *im_styles;
 879     char *ret = NULL;
 880 
 881     if (X11im == NULL) {
 882         return False;
 883     }
 884     if (!w) {
 885         return False;
 886     }
 887 
 888     ret = XGetIMValues(X11im, XNQueryInputStyle, &im_styles, NULL);
 889 
 890     if (ret != NULL) {
 891         jio_fprintf(stderr,"XGetIMValues: %s\n",ret);
 892         return FALSE ;
 893     }
 894 

 895     on_the_spot_styles |= XIMStatusNothing;
 896 
 897 #if defined(__linux__) || defined(MACOSX)
 898     /*kinput does not support XIMPreeditCallbacks and XIMStatusArea
 899       at the same time, so use StatusCallback to draw the status
 900       ourself
 901     */
 902     for (i = 0; i < im_styles->count_styles; i++) {
 903         if (im_styles->supported_styles[i] == (XIMPreeditCallbacks | XIMStatusCallbacks)) {
 904             on_the_spot_styles = (XIMPreeditCallbacks | XIMStatusCallbacks);
 905             break;
 906         }
 907     }


 908 #endif /* __linux__ || MACOSX */
 909 
 910     for (i = 0; i < im_styles->count_styles; i++) {
 911         active_styles |= im_styles->supported_styles[i] & on_the_spot_styles;
 912         passive_styles |= im_styles->supported_styles[i] & ROOT_WINDOW_STYLES;
 913         no_styles |= im_styles->supported_styles[i] & NO_STYLES;
 914     }
 915 
 916     XFree(im_styles);
 917 
 918     if (active_styles != on_the_spot_styles) {
 919         if (passive_styles == ROOT_WINDOW_STYLES)
 920             active_styles = passive_styles;
 921         else {
 922             if (no_styles == NO_STYLES)
 923                 active_styles = passive_styles = NO_STYLES;
 924             else
 925                 active_styles = passive_styles = 0;
 926         }
 927     } else {


 965             status = (XVaNestedList)XVaCreateNestedList(0,
 966                         XNStatusStartCallback, &callbacks[StatusStartIndex],
 967                         XNStatusDoneCallback,  &callbacks[StatusDoneIndex],
 968                         XNStatusDrawCallback, &callbacks[StatusDrawIndex],
 969                         NULL);
 970 
 971             if (status == NULL)
 972                 goto err;
 973             pX11IMData->statusWindow = createStatusWindow(w);
 974             pX11IMData->ic_active = XCreateIC(X11im,
 975                                               XNClientWindow, w,
 976                                               XNFocusWindow, w,
 977                                               XNInputStyle, active_styles,
 978                                               XNPreeditAttributes, preedit,
 979                                               XNStatusAttributes, status,
 980                                               NULL);
 981             XFree((void *)status);
 982             XFree((void *)preedit);
 983         }
 984 #else /* !__linux__ && !MACOSX */
 985         pX11IMData->ic_active = XCreateIC(X11im,
 986                                           XNClientWindow, w,
 987                                           XNFocusWindow, w,
 988                                           XNInputStyle, active_styles,
 989                                           XNPreeditAttributes, preedit,
 990                                           NULL);
 991         XFree((void *)preedit);
 992 #endif /* __linux__ || MACOSX */
 993     } else {
 994         pX11IMData->ic_active = XCreateIC(X11im,
 995                                           XNClientWindow, w,
 996                                           XNFocusWindow, w,
 997                                           XNInputStyle, active_styles,
 998                                           NULL);
 999         pX11IMData->ic_passive = pX11IMData->ic_active;
1000     }
1001 
1002     if (pX11IMData->ic_active == (XIC)0
1003         || pX11IMData->ic_passive == (XIC)0) {
1004         return False;
1005     }
1006 
1007     /*
1008      * Use commit string call back if possible.
1009      * This will ensure the correct order of preedit text and commit text
1010      */


1017             XSetICValues (pX11IMData->ic_passive, XNCommitStringCallback, &cb, NULL);
1018         }
1019     }
1020 
1021     /* Add the global reference object to X11InputMethod to the list. */
1022     addToX11InputMethodGRefList(pX11IMData->x11inputmethod);
1023 
1024     return True;
1025 
1026  err:
1027     if (preedit)
1028         XFree((void *)preedit);
1029     THROW_OUT_OF_MEMORY_ERROR();
1030     return False;
1031 }
1032 
1033 static void
1034 PreeditStartCallback(XIC ic, XPointer client_data, XPointer call_data)
1035 {
1036     /*ARGSUSED*/
1037     /* printf("Native: PreeditStartCallback\n"); */
1038 }
1039 
1040 static void
1041 PreeditDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
1042 {
1043     /*ARGSUSED*/
1044     /* printf("Native: PreeditDoneCallback\n"); */
1045 }
1046 
1047 /*
1048  * Translate the preedit draw callback items to Java values and invoke
1049  * X11InputMethod.dispatchComposedText().
1050  *
1051  * client_data: X11InputMethod object
1052  */
1053 static void
1054 PreeditDrawCallback(XIC ic, XPointer client_data,
1055                     XIMPreeditDrawCallbackStruct *pre_draw)
1056 {
1057     JNIEnv *env = GetJNIEnv();
1058     X11InputMethodData *pX11IMData = NULL;
1059     jmethodID x11imMethodID;
1060 
1061     XIMText *text;
1062     jstring javastr = NULL;
1063     jintArray style = NULL;
1064 


1129     JNU_CallMethodByName(env, NULL, pX11IMData->x11inputmethod,
1130                          "dispatchComposedText",
1131                          "(Ljava/lang/String;[IIIIJ)V",
1132                          javastr,
1133                          style,
1134                          (jint)pre_draw->chg_first,
1135                          (jint)pre_draw->chg_length,
1136                          (jint)pre_draw->caret,
1137                          awt_util_nowMillisUTC());
1138 finally:
1139     AWT_UNLOCK();
1140     return;
1141 }
1142 
1143 static void
1144 PreeditCaretCallback(XIC ic, XPointer client_data,
1145                      XIMPreeditCaretCallbackStruct *pre_caret)
1146 {
1147     /*ARGSUSED*/
1148     /* printf("Native: PreeditCaretCallback\n"); */

1149 }
1150 
1151 #if defined(__linux__) || defined(MACOSX)
1152 static void
1153 StatusStartCallback(XIC ic, XPointer client_data, XPointer call_data)
1154 {
1155     /*ARGSUSED*/
1156     /*printf("StatusStartCallback:\n");  */

1157 }
1158 
1159 static void
1160 StatusDoneCallback(XIC ic, XPointer client_data, XPointer call_data)
1161 {
1162     /*ARGSUSED*/
1163     /*printf("StatusDoneCallback:\n"); */

1164 }
1165 
1166 static void
1167 StatusDrawCallback(XIC ic, XPointer client_data,
1168                      XIMStatusDrawCallbackStruct *status_draw)
1169 {
1170     /*ARGSUSED*/
1171     /*printf("StatusDrawCallback:\n"); */
1172     JNIEnv *env = GetJNIEnv();
1173     X11InputMethodData *pX11IMData = NULL;
1174     StatusWindow *statusWindow;
1175 
1176     AWT_LOCK();
1177 
1178     if (!isX11InputMethodGRefInList((jobject)client_data)) {
1179         if ((jobject)client_data == currentX11InputMethodInstance) {
1180             currentX11InputMethodInstance = NULL;
1181         }
1182         goto finally;
1183     }
1184 
1185     if (NULL == (pX11IMData = getX11InputMethodData(env, (jobject)client_data))
1186         || NULL == (statusWindow = pX11IMData->statusWindow)){
1187         goto finally;
1188     }
1189     currentX11InputMethodInstance = (jobject)client_data;
1190 
1191     if (status_draw->type == XIMTextType) {
1192         XIMText *text = (status_draw->data).text;
1193         if (text != NULL) {
1194             if (text->string.multi_byte != NULL) {
1195                 strncpy(statusWindow->status, text->string.multi_byte, MAX_STATUS_LEN);
1196                 statusWindow->status[MAX_STATUS_LEN - 1] = '\0';
1197             } else {
1198                 char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
1199                 strncpy(statusWindow->status, mbstr, MAX_STATUS_LEN);
1200                 statusWindow->status[MAX_STATUS_LEN - 1] = '\0';
1201             }
1202             statusWindow->on = True;
1203             onoffStatusWindow(pX11IMData, statusWindow->parent, True);
1204             paintStatusWindow(statusWindow);
1205         } else {


1206             statusWindow->on = False;
1207             /*just turnoff the status window
1208             paintStatusWindow(statusWindow);
1209             */
1210             onoffStatusWindow(pX11IMData, 0, False);
1211         }
1212     }
1213 
1214  finally:
1215     AWT_UNLOCK();
1216 }
1217 #endif /* __linux__ || MACOSX */
1218 
1219 static void CommitStringCallback(XIC ic, XPointer client_data, XPointer call_data) {
1220     JNIEnv *env = GetJNIEnv();
1221     XIMText * text = (XIMText *)call_data;
1222     X11InputMethodData *pX11IMData = NULL;
1223     jstring javastr;
1224 
1225     AWT_LOCK();


1264 
1265     X11im = XOpenIM(display, NULL, NULL, NULL);
1266     if (X11im == NULL) {
1267         return;
1268     }
1269 
1270     ximCallback.callback = (XIMProc)DestroyXIMCallback;
1271     ximCallback.client_data = NULL;
1272     XSetIMValues(X11im, XNDestroyCallback, &ximCallback, NULL);
1273 }
1274 
1275 static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) {
1276     /* mark that XIM server was destroyed */
1277     X11im = NULL;
1278     JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1279     /* free the old pX11IMData and set it to null. this also avoids crashing
1280      * the jvm if the XIM server reappears */
1281     X11InputMethodData *pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
1282 }
1283 
















1284 JNIEXPORT jboolean JNICALL
1285 Java_sun_awt_X11_XInputMethod_openXIMNative(JNIEnv *env,
1286                                             jobject this,
1287                                             jlong display)
1288 {
1289     Bool registered;
1290 
1291     AWT_LOCK();
1292 
1293     dpy = (Display *)jlong_to_ptr(display);
1294 
1295 /* Use IMInstantiate call back only on Linux, as there is a bug in Solaris
1296    (4768335)
1297 */
1298 #if defined(__linux__) || defined(MACOSX)
1299     registered = XRegisterIMInstantiateCallback(dpy, NULL, NULL,
1300                      NULL, (XIDProc)OpenXIMCallback, NULL);
1301     if (!registered) {
1302         /* directly call openXIM callback */
1303 #endif
1304         OpenXIMCallback(dpy, NULL, NULL);
1305 #if defined(__linux__) || defined(MACOSX)
1306     }
1307 #endif
1308 
1309     AWT_UNLOCK();
1310 
1311     return JNI_TRUE;
1312 }
1313 
1314 JNIEXPORT jboolean JNICALL
1315 Java_sun_awt_X11_XInputMethod_createXICNative(JNIEnv *env,
1316                                               jobject this,
1317                                               jlong window)
1318 {
1319     X11InputMethodData *pX11IMData;
1320     jobject globalRef;
1321     XIC ic;
1322 
1323     AWT_LOCK();
1324 
1325     if (!window) {
1326         JNU_ThrowNullPointerException(env, "NullPointerException");
1327         AWT_UNLOCK();
1328         return JNI_FALSE;
1329     }
1330 
1331     pX11IMData = (X11InputMethodData *) calloc(1, sizeof(X11InputMethodData));
1332     if (pX11IMData == NULL) {
1333         THROW_OUT_OF_MEMORY_ERROR();
1334         AWT_UNLOCK();
1335         return JNI_FALSE;
1336     }
1337 


1344     pX11IMData->lookup_buf = 0;
1345     pX11IMData->lookup_buf_len = 0;
1346 
1347     if (createXIC(env, pX11IMData, (Window)window) == False) {
1348         destroyX11InputMethodData((JNIEnv *) NULL, pX11IMData);
1349         pX11IMData = (X11InputMethodData *) NULL;
1350         if ((*env)->ExceptionCheck(env)) {
1351             goto finally;
1352         }
1353     }
1354 
1355     setX11InputMethodData(env, this, pX11IMData);
1356 
1357 finally:
1358     AWT_UNLOCK();
1359     return (pX11IMData != NULL);
1360 }
1361 
1362 JNIEXPORT void JNICALL
1363 Java_sun_awt_X11_XInputMethod_setXICFocusNative(JNIEnv *env,
1364                                                 jobject this,
1365                                                 jlong w,
1366                                                 jboolean req,
1367                                                 jboolean active)
1368 {
1369     X11InputMethodData *pX11IMData;
1370     AWT_LOCK();
1371     pX11IMData = getX11InputMethodData(env, this);
1372     if (pX11IMData == NULL) {
1373         AWT_UNLOCK();
1374         return;
1375     }
1376 
1377     if (req) {
1378         if (!w) {
1379             AWT_UNLOCK();
1380             return;
1381         }
1382         pX11IMData->current_ic = active ?
1383                         pX11IMData->ic_active : pX11IMData->ic_passive;
1384         /*
1385          * On Solaris2.6, setXICWindowFocus() has to be invoked
1386          * before setting focus.
1387          */


1392 #if defined(__linux__) || defined(MACOSX)
1393         if (active && pX11IMData->statusWindow && pX11IMData->statusWindow->on)
1394             onoffStatusWindow(pX11IMData, w, True);
1395 #endif
1396     } else {
1397         currentX11InputMethodInstance = NULL;
1398         currentFocusWindow = 0;
1399 #if defined(__linux__) || defined(MACOSX)
1400         onoffStatusWindow(pX11IMData, 0, False);
1401         if (pX11IMData->current_ic != NULL)
1402 #endif
1403         setXICFocus(pX11IMData->current_ic, req);
1404 
1405         pX11IMData->current_ic = (XIC)0;
1406     }
1407 
1408     XFlush(dpy);
1409     AWT_UNLOCK();
1410 }
1411 
1412 /*
1413  * Class:     sun_awt_X11InputMethodBase
1414  * Method:    initIDs
1415  * Signature: ()V
1416  * This function gets called from the static initializer for
1417  * X11InputMethod.java to initialize the fieldIDs for fields
1418  * that may be accessed from C
1419  */
1420 JNIEXPORT void JNICALL Java_sun_awt_X11InputMethodBase_initIDs
1421   (JNIEnv *env, jclass cls)
1422 {
1423     x11InputMethodIDs.pData = (*env)->GetFieldID(env, cls, "pData", "J");
1424 }
1425 
1426 /*
1427  * Class:     sun_awt_X11InputMethodBase
1428  * Method:    turnoffStatusWindow
1429  * Signature: ()V
1430  */
1431 JNIEXPORT void JNICALL Java_sun_awt_X11InputMethodBase_turnoffStatusWindow
1432   (JNIEnv *env, jobject this)
1433 {
1434 #if defined(__linux__) || defined(MACOSX)
1435     X11InputMethodData *pX11IMData;
1436     StatusWindow *statusWindow;
1437 
1438     AWT_LOCK();
1439 
1440     if (NULL == currentX11InputMethodInstance
1441         || !isX11InputMethodGRefInList(currentX11InputMethodInstance)
1442         || NULL == (pX11IMData = getX11InputMethodData(env,currentX11InputMethodInstance))
1443         || NULL == (statusWindow = pX11IMData->statusWindow)
1444         || !statusWindow->on ){
1445         AWT_UNLOCK();
1446         return;
1447     }
1448     onoffStatusWindow(pX11IMData, 0, False);
1449 
1450     AWT_UNLOCK();
1451 #endif
1452 }
1453 
1454 /*
1455  * Class:     sun_awt_X11InputMethodBase
1456  * Method:    disposeXIC
1457  * Signature: ()V
1458  */
1459 JNIEXPORT void JNICALL Java_sun_awt_X11InputMethodBase_disposeXIC
1460   (JNIEnv *env, jobject this)
1461 {
1462     X11InputMethodData *pX11IMData = NULL;
1463 
1464     AWT_LOCK();
1465     pX11IMData = getX11InputMethodData(env, this);
1466     if (pX11IMData == NULL) {
1467         AWT_UNLOCK();
1468         return;
1469     }
1470 
1471     setX11InputMethodData(env, this, NULL);
1472 
1473     if (pX11IMData->x11inputmethod == currentX11InputMethodInstance) {
1474         currentX11InputMethodInstance = NULL;
1475         currentFocusWindow = 0;
1476     }
1477     destroyX11InputMethodData(env, pX11IMData);
1478     AWT_UNLOCK();
1479 }
1480 
1481 /*
1482  * Class:     sun_awt_X11InputMethodBase
1483  * Method:    resetXIC
1484  * Signature: ()Ljava/lang/String;
1485  */
1486 JNIEXPORT jstring JNICALL Java_sun_awt_X11InputMethodBase_resetXIC
1487   (JNIEnv *env, jobject this)
1488 {
1489     X11InputMethodData *pX11IMData;
1490     char *xText = NULL;
1491     jstring jText = (jstring)0;
1492 
1493     AWT_LOCK();
1494     pX11IMData = getX11InputMethodData(env, this);
1495     if (pX11IMData == NULL) {
1496         AWT_UNLOCK();
1497         return jText;
1498     }
1499 
1500     if (pX11IMData->current_ic)
1501         xText = XmbResetIC(pX11IMData->current_ic);
1502     else {
1503         /*
1504          * If there is no reference to the current XIC, try to reset both XICs.
1505          */
1506         xText = XmbResetIC(pX11IMData->ic_active);
1507         /*it may also means that the real client component does


1511         */
1512         setXICFocus(pX11IMData->ic_active, FALSE);
1513         if (pX11IMData->ic_active != pX11IMData->ic_passive) {
1514             char *tmpText = XmbResetIC(pX11IMData->ic_passive);
1515             setXICFocus(pX11IMData->ic_passive, FALSE);
1516             if (xText == (char *)NULL && tmpText)
1517                 xText = tmpText;
1518         }
1519 
1520     }
1521     if (xText != NULL) {
1522         jText = JNU_NewStringPlatform(env, (const char *)xText);
1523         XFree((void *)xText);
1524     }
1525 
1526     AWT_UNLOCK();
1527     return jText;
1528 }
1529 
1530 /*
1531  * Class:     sun_awt_X11InputMethodBase
1532  * Method:    setCompositionEnabledNative
1533  * Signature: (Z)Z
1534  *
1535  * This method tries to set the XNPreeditState attribute associated with the current
1536  * XIC to the passed in 'enable' state.
1537  *
1538  * Return JNI_TRUE if XNPreeditState attribute is successfully changed to the
1539  * 'enable' state; Otherwise, if XSetICValues fails to set this attribute,
1540  * java.lang.UnsupportedOperationException will be thrown. JNI_FALSE is returned if this
1541  * method fails due to other reasons.

1542  */
1543 JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_setCompositionEnabledNative
1544   (JNIEnv *env, jobject this, jboolean enable)
1545 {
1546     X11InputMethodData *pX11IMData;
1547     char * ret = NULL;
1548 
1549     AWT_LOCK();
1550     pX11IMData = getX11InputMethodData(env, this);
1551 
1552     if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
1553         AWT_UNLOCK();
1554         return JNI_FALSE;
1555     }
1556 
1557     ret = XSetICValues(pX11IMData->current_ic, XNPreeditState,
1558                        (enable ? XIMPreeditEnable : XIMPreeditDisable), NULL);
1559     AWT_UNLOCK();
1560 
1561     if ((ret != 0) && (strcmp(ret, XNPreeditState) == 0)) {
1562         JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
1563     }
1564 
1565     return (jboolean)(ret == 0);
1566 }
1567 
1568 /*
1569  * Class:     sun_awt_X11InputMethodBase
1570  * Method:    isCompositionEnabledNative
1571  * Signature: ()Z
1572  *
1573  * This method tries to get the XNPreeditState attribute associated with the current XIC.
1574  *
1575  * Return JNI_TRUE if the XNPreeditState is successfully retrieved. Otherwise, if
1576  * XGetICValues fails to get this attribute, java.lang.UnsupportedOperationException
1577  * will be thrown. JNI_FALSE is returned if this method fails due to other reasons.

1578  */
1579 JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_isCompositionEnabledNative
1580   (JNIEnv *env, jobject this)
1581 {
1582     X11InputMethodData *pX11IMData = NULL;
1583     char * ret = NULL;
1584     XIMPreeditState state;
1585 
1586     AWT_LOCK();
1587     pX11IMData = getX11InputMethodData(env, this);
1588 
1589     if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
1590         AWT_UNLOCK();
1591         return JNI_FALSE;
1592     }
1593 
1594     ret = XGetICValues(pX11IMData->current_ic, XNPreeditState, &state, NULL);
1595     AWT_UNLOCK();
1596 
1597     if ((ret != 0) && (strcmp(ret, XNPreeditState) == 0)) {
1598         JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", "");
1599         return JNI_FALSE;
< prev index next >