158 159 Window currentFocusWindow = 0; /* current window that has focus for input 160 method. (the best place to put this 161 information should be 162 currentX11InputMethodInstance's pData) */ 163 static XIM X11im = NULL; 164 Display * dpy = NULL; 165 166 #define GetJNIEnv() (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2) 167 168 static void DestroyXIMCallback(XIM, XPointer, XPointer); 169 static void OpenXIMCallback(Display *, XPointer, XPointer); 170 /* Solaris XIM Extention */ 171 #define XNCommitStringCallback "commitStringCallback" 172 static void CommitStringCallback(XIC, XPointer, XPointer); 173 174 static X11InputMethodData * getX11InputMethodData(JNIEnv *, jobject); 175 static void setX11InputMethodData(JNIEnv *, jobject, X11InputMethodData *); 176 static void destroyX11InputMethodData(JNIEnv *, X11InputMethodData *); 177 static void freeX11InputMethodData(JNIEnv *, X11InputMethodData *); 178 179 #ifdef __solaris__ 180 /* Prototype for this function is missing in Solaris X11R6 Xlib.h */ 181 extern char *XSetIMValues( 182 #if NeedVarargsPrototypes 183 XIM /* im */, ... 184 #endif 185 ); 186 #endif 187 188 /* 189 * This function is stolen from /src/solaris/hpi/src/system_md.c 190 * It is used in setting the time in Java-level InputEvents 191 */ 192 jlong 193 awt_util_nowMillisUTC() 194 { 195 struct timeval t; 196 gettimeofday(&t, NULL); 197 return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/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 */ 1011 { 1012 XIMCallback cb; 1013 cb.client_data = (XPointer) pX11IMData->x11inputmethod; 1014 cb.callback = (XIMProc) CommitStringCallback; 1015 XSetICValues (pX11IMData->ic_active, XNCommitStringCallback, &cb, NULL); 1016 if (pX11IMData->ic_active != pX11IMData->ic_passive) { 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*/ 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 } 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; 1600 } 1601 1602 return (jboolean)(state == XIMPreeditEnable); 1603 } 1604 1605 JNIEXPORT void JNICALL Java_sun_awt_X11_XInputMethod_adjustStatusWindow 1606 (JNIEnv *env, jobject this, jlong window) 1607 { 1608 #if defined(__linux__) || defined(MACOSX) 1609 AWT_LOCK(); 1610 adjustStatusWindow(window); 1611 AWT_UNLOCK(); 1612 #endif 1613 } | 158 159 Window currentFocusWindow = 0; /* current window that has focus for input 160 method. (the best place to put this 161 information should be 162 currentX11InputMethodInstance's pData) */ 163 static XIM X11im = NULL; 164 Display * dpy = NULL; 165 166 #define GetJNIEnv() (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2) 167 168 static void DestroyXIMCallback(XIM, XPointer, XPointer); 169 static void OpenXIMCallback(Display *, XPointer, XPointer); 170 /* Solaris XIM Extention */ 171 #define XNCommitStringCallback "commitStringCallback" 172 static void CommitStringCallback(XIC, XPointer, XPointer); 173 174 static X11InputMethodData * getX11InputMethodData(JNIEnv *, jobject); 175 static void setX11InputMethodData(JNIEnv *, jobject, X11InputMethodData *); 176 static void destroyX11InputMethodData(JNIEnv *, X11InputMethodData *); 177 static void freeX11InputMethodData(JNIEnv *, X11InputMethodData *); 178 #if defined(__linux__) || defined(MACOSX) 179 static Window getParentWindow(Window); 180 #endif 181 182 #ifdef __solaris__ 183 /* Prototype for this function is missing in Solaris X11R6 Xlib.h */ 184 extern char *XSetIMValues( 185 #if NeedVarargsPrototypes 186 XIM /* im */, ... 187 #endif 188 ); 189 #endif 190 191 /* 192 * This function is stolen from /src/solaris/hpi/src/system_md.c 193 * It is used in setting the time in Java-level InputEvents 194 */ 195 jlong 196 awt_util_nowMillisUTC() 197 { 198 struct timeval t; 199 gettimeofday(&t, NULL); 200 return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000); 1004 1005 if (pX11IMData->ic_active == (XIC)0 1006 || pX11IMData->ic_passive == (XIC)0) { 1007 return False; 1008 } 1009 1010 /* 1011 * Use commit string call back if possible. 1012 * This will ensure the correct order of preedit text and commit text 1013 */ 1014 { 1015 XIMCallback cb; 1016 cb.client_data = (XPointer) pX11IMData->x11inputmethod; 1017 cb.callback = (XIMProc) CommitStringCallback; 1018 XSetICValues (pX11IMData->ic_active, XNCommitStringCallback, &cb, NULL); 1019 if (pX11IMData->ic_active != pX11IMData->ic_passive) { 1020 XSetICValues (pX11IMData->ic_passive, XNCommitStringCallback, &cb, NULL); 1021 } 1022 } 1023 1024 // The code set the IC mode that the preedit state is not initialied 1025 // at XmbResetIC. This attribute can be set at XCreateIC. I separately 1026 // set the attribute to avoid the failure of XCreateIC at some platform 1027 // which does not support the attribute. 1028 if (pX11IMData->ic_active != 0) 1029 XSetICValues(pX11IMData->ic_active, 1030 XNResetState, XIMInitialState, 1031 NULL); 1032 if (pX11IMData->ic_passive != 0 1033 && pX11IMData->ic_active != pX11IMData->ic_passive) 1034 XSetICValues(pX11IMData->ic_passive, 1035 XNResetState, XIMInitialState, 1036 NULL); 1037 1038 /* Add the global reference object to X11InputMethod to the list. */ 1039 addToX11InputMethodGRefList(pX11IMData->x11inputmethod); 1040 1041 /* Unset focus to avoid unexpected IM on */ 1042 setXICFocus(pX11IMData->ic_active, False); 1043 if (pX11IMData->ic_active != pX11IMData->ic_passive) 1044 setXICFocus(pX11IMData->ic_passive, False); 1045 1046 return True; 1047 1048 err: 1049 if (preedit) 1050 XFree((void *)preedit); 1051 THROW_OUT_OF_MEMORY_ERROR(); 1052 return False; 1053 } 1054 1055 static void 1056 PreeditStartCallback(XIC ic, XPointer client_data, XPointer call_data) 1057 { 1058 /*ARGSUSED*/ 1059 /* printf("Native: PreeditStartCallback\n"); */ 1060 } 1061 1062 static void 1063 PreeditDoneCallback(XIC ic, XPointer client_data, XPointer call_data) 1064 { 1065 /*ARGSUSED*/ 1166 PreeditCaretCallback(XIC ic, XPointer client_data, 1167 XIMPreeditCaretCallbackStruct *pre_caret) 1168 { 1169 /*ARGSUSED*/ 1170 /* printf("Native: PreeditCaretCallback\n"); */ 1171 } 1172 1173 #if defined(__linux__) || defined(MACOSX) 1174 static void 1175 StatusStartCallback(XIC ic, XPointer client_data, XPointer call_data) 1176 { 1177 /*ARGSUSED*/ 1178 /*printf("StatusStartCallback:\n"); */ 1179 } 1180 1181 static void 1182 StatusDoneCallback(XIC ic, XPointer client_data, XPointer call_data) 1183 { 1184 /*ARGSUSED*/ 1185 /*printf("StatusDoneCallback:\n"); */ 1186 JNIEnv *env = GetJNIEnv(); 1187 X11InputMethodData *pX11IMData = NULL; 1188 StatusWindow *statusWindow; 1189 1190 AWT_LOCK(); 1191 1192 if (!isX11InputMethodGRefInList((jobject)client_data)) { 1193 if ((jobject)client_data == currentX11InputMethodInstance) { 1194 currentX11InputMethodInstance = NULL; 1195 } 1196 goto finally; 1197 } 1198 1199 if (NULL == (pX11IMData = getX11InputMethodData(env, (jobject)client_data)) 1200 || NULL == (statusWindow = pX11IMData->statusWindow)){ 1201 goto finally; 1202 } 1203 currentX11InputMethodInstance = (jobject)client_data; 1204 1205 onoffStatusWindow(pX11IMData, 0, False); 1206 1207 finally: 1208 AWT_UNLOCK(); 1209 } 1210 1211 static void 1212 StatusDrawCallback(XIC ic, XPointer client_data, 1213 XIMStatusDrawCallbackStruct *status_draw) 1214 { 1215 /*ARGSUSED*/ 1216 /*printf("StatusDrawCallback:\n"); */ 1217 JNIEnv *env = GetJNIEnv(); 1218 X11InputMethodData *pX11IMData = NULL; 1219 StatusWindow *statusWindow; 1220 1221 AWT_LOCK(); 1222 1223 if (!isX11InputMethodGRefInList((jobject)client_data)) { 1224 if ((jobject)client_data == currentX11InputMethodInstance) { 1225 currentX11InputMethodInstance = NULL; 1226 } 1227 goto finally; 1228 } 1573 } 1574 1575 /* 1576 * Class: sun_awt_X11InputMethodBase 1577 * Method: setCompositionEnabledNative 1578 * Signature: (Z)Z 1579 * 1580 * This method tries to set the XNPreeditState attribute associated with the current 1581 * XIC to the passed in 'enable' state. 1582 * 1583 * Return JNI_TRUE if XNPreeditState attribute is successfully changed to the 1584 * 'enable' state; Otherwise, if XSetICValues fails to set this attribute, 1585 * java.lang.UnsupportedOperationException will be thrown. JNI_FALSE is returned if this 1586 * method fails due to other reasons. 1587 */ 1588 JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_setCompositionEnabledNative 1589 (JNIEnv *env, jobject this, jboolean enable) 1590 { 1591 X11InputMethodData *pX11IMData; 1592 char * ret = NULL; 1593 XVaNestedList pr_atrb; 1594 #if defined(__linux__) || defined(MACOSX) 1595 Boolean calledXSetICFocus = False; 1596 #endif 1597 1598 AWT_LOCK(); 1599 pX11IMData = getX11InputMethodData(env, this); 1600 1601 if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) { 1602 AWT_UNLOCK(); 1603 return JNI_FALSE; 1604 } 1605 1606 #if defined(__linux__) || defined(MACOSX) 1607 if (NULL != pX11IMData->statusWindow) { 1608 Window focus = 0; 1609 int revert_to; 1610 Window w = 0; 1611 XGetInputFocus(awt_display, &focus, &revert_to); 1612 XGetICValues(pX11IMData->current_ic, XNFocusWindow, &w, NULL); 1613 if (RevertToPointerRoot == revert_to 1614 && pX11IMData->ic_active != pX11IMData->ic_passive) { 1615 if (pX11IMData->current_ic == pX11IMData->ic_active) { 1616 if (getParentWindow(focus) == getParentWindow(w)) { 1617 XUnsetICFocus(pX11IMData->ic_active); 1618 calledXSetICFocus = True; 1619 } 1620 } 1621 } 1622 } 1623 #endif 1624 pr_atrb = XVaCreateNestedList(0, 1625 XNPreeditState, (enable ? XIMPreeditEnable : XIMPreeditDisable), 1626 NULL); 1627 ret = XSetICValues(pX11IMData->current_ic, XNPreeditAttributes, pr_atrb, NULL); 1628 XFree((void *)pr_atrb); 1629 #if defined(__linux__) || defined(MACOSX) 1630 if (calledXSetICFocus) { 1631 XSetICFocus(pX11IMData->ic_active); 1632 } 1633 #endif 1634 AWT_UNLOCK(); 1635 1636 if ((ret != 0) 1637 && ((strcmp(ret, XNPreeditAttributes) == 0) 1638 || (strcmp(ret, XNPreeditState) == 0))) { 1639 JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", ""); 1640 } 1641 1642 return (jboolean)(ret == 0); 1643 } 1644 1645 /* 1646 * Class: sun_awt_X11InputMethodBase 1647 * Method: isCompositionEnabledNative 1648 * Signature: ()Z 1649 * 1650 * This method tries to get the XNPreeditState attribute associated with the current XIC. 1651 * 1652 * Return JNI_TRUE if the XNPreeditState is successfully retrieved. Otherwise, if 1653 * XGetICValues fails to get this attribute, java.lang.UnsupportedOperationException 1654 * will be thrown. JNI_FALSE is returned if this method fails due to other reasons. 1655 */ 1656 JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_isCompositionEnabledNative 1657 (JNIEnv *env, jobject this) 1658 { 1659 X11InputMethodData *pX11IMData = NULL; 1660 char * ret = NULL; 1661 XIMPreeditState state = XIMPreeditUnKnown; 1662 XVaNestedList pr_atrb; 1663 1664 AWT_LOCK(); 1665 pX11IMData = getX11InputMethodData(env, this); 1666 1667 if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) { 1668 AWT_UNLOCK(); 1669 return JNI_FALSE; 1670 } 1671 1672 pr_atrb = XVaCreateNestedList(0, XNPreeditState, &state, NULL); 1673 ret = XGetICValues(pX11IMData->current_ic, XNPreeditAttributes, pr_atrb, NULL); 1674 XFree((void *)pr_atrb); 1675 AWT_UNLOCK(); 1676 1677 if ((ret != 0) 1678 && ((strcmp(ret, XNPreeditAttributes) == 0) 1679 || (strcmp(ret, XNPreeditState) == 0))) { 1680 JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", ""); 1681 return JNI_FALSE; 1682 } 1683 1684 return (jboolean)(state == XIMPreeditEnable); 1685 } 1686 1687 JNIEXPORT void JNICALL Java_sun_awt_X11_XInputMethod_adjustStatusWindow 1688 (JNIEnv *env, jobject this, jlong window) 1689 { 1690 #if defined(__linux__) || defined(MACOSX) 1691 AWT_LOCK(); 1692 adjustStatusWindow(window); 1693 AWT_UNLOCK(); 1694 #endif 1695 } 1696 1697 #if defined(__linux__) || defined(MACOSX) 1698 static Window getParentWindow(Window w) 1699 { 1700 Window root=None, parent=None, *ignore_children=NULL; 1701 unsigned int ignore_uint=0; 1702 Status status = 0; 1703 1704 if (w == None) 1705 return None; 1706 status = XQueryTree(dpy, w, &root, &parent, &ignore_children, &ignore_uint); 1707 XFree(ignore_children); 1708 if (status == 0) 1709 return None; 1710 return parent; 1711 } 1712 #endif |