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*/ 1145 PreeditCaretCallback(XIC ic, XPointer client_data, 1146 XIMPreeditCaretCallbackStruct *pre_caret) 1147 { 1148 /*ARGSUSED*/ 1149 /* printf("Native: PreeditCaretCallback\n"); */ 1150 } 1151 1152 #if defined(__linux__) || defined(MACOSX) 1153 static void 1154 StatusStartCallback(XIC ic, XPointer client_data, XPointer call_data) 1155 { 1156 /*ARGSUSED*/ 1157 /*printf("StatusStartCallback:\n"); */ 1158 } 1159 1160 static void 1161 StatusDoneCallback(XIC ic, XPointer client_data, XPointer call_data) 1162 { 1163 /*ARGSUSED*/ 1164 /*printf("StatusDoneCallback:\n"); */ 1165 } 1166 1167 static void 1168 StatusDrawCallback(XIC ic, XPointer client_data, 1169 XIMStatusDrawCallbackStruct *status_draw) 1170 { 1171 /*ARGSUSED*/ 1172 /*printf("StatusDrawCallback:\n"); */ 1173 JNIEnv *env = GetJNIEnv(); 1174 X11InputMethodData *pX11IMData = NULL; 1175 StatusWindow *statusWindow; 1176 1177 AWT_LOCK(); 1178 1179 if (!isX11InputMethodGRefInList((jobject)client_data)) { 1180 if ((jobject)client_data == currentX11InputMethodInstance) { 1181 currentX11InputMethodInstance = NULL; 1182 } 1183 goto finally; 1184 } 1529 } 1530 1531 /* 1532 * Class: sun_awt_X11InputMethodBase 1533 * Method: setCompositionEnabledNative 1534 * Signature: (Z)Z 1535 * 1536 * This method tries to set the XNPreeditState attribute associated with the current 1537 * XIC to the passed in 'enable' state. 1538 * 1539 * Return JNI_TRUE if XNPreeditState attribute is successfully changed to the 1540 * 'enable' state; Otherwise, if XSetICValues fails to set this attribute, 1541 * java.lang.UnsupportedOperationException will be thrown. JNI_FALSE is returned if this 1542 * method fails due to other reasons. 1543 */ 1544 JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_setCompositionEnabledNative 1545 (JNIEnv *env, jobject this, jboolean enable) 1546 { 1547 X11InputMethodData *pX11IMData; 1548 char * ret = NULL; 1549 1550 AWT_LOCK(); 1551 pX11IMData = getX11InputMethodData(env, this); 1552 1553 if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) { 1554 AWT_UNLOCK(); 1555 return JNI_FALSE; 1556 } 1557 1558 ret = XSetICValues(pX11IMData->current_ic, XNPreeditState, 1559 (enable ? XIMPreeditEnable : XIMPreeditDisable), NULL); 1560 AWT_UNLOCK(); 1561 1562 if ((ret != 0) && (strcmp(ret, XNPreeditState) == 0)) { 1563 JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", ""); 1564 } 1565 1566 return (jboolean)(ret == 0); 1567 } 1568 1569 /* 1570 * Class: sun_awt_X11InputMethodBase 1571 * Method: isCompositionEnabledNative 1572 * Signature: ()Z 1573 * 1574 * This method tries to get the XNPreeditState attribute associated with the current XIC. 1575 * 1576 * Return JNI_TRUE if the XNPreeditState is successfully retrieved. Otherwise, if 1577 * XGetICValues fails to get this attribute, java.lang.UnsupportedOperationException 1578 * will be thrown. JNI_FALSE is returned if this method fails due to other reasons. 1579 */ 1580 JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_isCompositionEnabledNative 1581 (JNIEnv *env, jobject this) 1582 { 1583 X11InputMethodData *pX11IMData = NULL; 1584 char * ret = NULL; 1585 XIMPreeditState state; 1586 1587 AWT_LOCK(); 1588 pX11IMData = getX11InputMethodData(env, this); 1589 1590 if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) { 1591 AWT_UNLOCK(); 1592 return JNI_FALSE; 1593 } 1594 1595 ret = XGetICValues(pX11IMData->current_ic, XNPreeditState, &state, NULL); 1596 AWT_UNLOCK(); 1597 1598 if ((ret != 0) && (strcmp(ret, XNPreeditState) == 0)) { 1599 JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", ""); 1600 return JNI_FALSE; 1601 } 1602 1603 return (jboolean)(state == XIMPreeditEnable); 1604 } 1605 1606 JNIEXPORT void JNICALL Java_sun_awt_X11_XInputMethod_adjustStatusWindow 1607 (JNIEnv *env, jobject this, jlong window) 1608 { 1609 #if defined(__linux__) || defined(MACOSX) 1610 AWT_LOCK(); 1611 adjustStatusWindow(window); 1612 AWT_UNLOCK(); 1613 #endif 1614 } | 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*/ 1167 PreeditCaretCallback(XIC ic, XPointer client_data, 1168 XIMPreeditCaretCallbackStruct *pre_caret) 1169 { 1170 /*ARGSUSED*/ 1171 /* printf("Native: PreeditCaretCallback\n"); */ 1172 } 1173 1174 #if defined(__linux__) || defined(MACOSX) 1175 static void 1176 StatusStartCallback(XIC ic, XPointer client_data, XPointer call_data) 1177 { 1178 /*ARGSUSED*/ 1179 /*printf("StatusStartCallback:\n"); */ 1180 } 1181 1182 static void 1183 StatusDoneCallback(XIC ic, XPointer client_data, XPointer call_data) 1184 { 1185 /*ARGSUSED*/ 1186 /*printf("StatusDoneCallback:\n"); */ 1187 JNIEnv *env = GetJNIEnv(); 1188 X11InputMethodData *pX11IMData = NULL; 1189 StatusWindow *statusWindow; 1190 1191 AWT_LOCK(); 1192 1193 if (!isX11InputMethodGRefInList((jobject)client_data)) { 1194 if ((jobject)client_data == currentX11InputMethodInstance) { 1195 currentX11InputMethodInstance = NULL; 1196 } 1197 goto finally; 1198 } 1199 1200 if (NULL == (pX11IMData = getX11InputMethodData(env, (jobject)client_data)) 1201 || NULL == (statusWindow = pX11IMData->statusWindow)){ 1202 goto finally; 1203 } 1204 currentX11InputMethodInstance = (jobject)client_data; 1205 1206 onoffStatusWindow(pX11IMData, 0, False); 1207 1208 finally: 1209 AWT_UNLOCK(); 1210 } 1211 1212 static void 1213 StatusDrawCallback(XIC ic, XPointer client_data, 1214 XIMStatusDrawCallbackStruct *status_draw) 1215 { 1216 /*ARGSUSED*/ 1217 /*printf("StatusDrawCallback:\n"); */ 1218 JNIEnv *env = GetJNIEnv(); 1219 X11InputMethodData *pX11IMData = NULL; 1220 StatusWindow *statusWindow; 1221 1222 AWT_LOCK(); 1223 1224 if (!isX11InputMethodGRefInList((jobject)client_data)) { 1225 if ((jobject)client_data == currentX11InputMethodInstance) { 1226 currentX11InputMethodInstance = NULL; 1227 } 1228 goto finally; 1229 } 1574 } 1575 1576 /* 1577 * Class: sun_awt_X11InputMethodBase 1578 * Method: setCompositionEnabledNative 1579 * Signature: (Z)Z 1580 * 1581 * This method tries to set the XNPreeditState attribute associated with the current 1582 * XIC to the passed in 'enable' state. 1583 * 1584 * Return JNI_TRUE if XNPreeditState attribute is successfully changed to the 1585 * 'enable' state; Otherwise, if XSetICValues fails to set this attribute, 1586 * java.lang.UnsupportedOperationException will be thrown. JNI_FALSE is returned if this 1587 * method fails due to other reasons. 1588 */ 1589 JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_setCompositionEnabledNative 1590 (JNIEnv *env, jobject this, jboolean enable) 1591 { 1592 X11InputMethodData *pX11IMData; 1593 char * ret = NULL; 1594 XVaNestedList pr_atrb; 1595 #if defined(__linux__) || defined(MACOSX) 1596 Boolean calledXSetICFocus = False; 1597 #endif 1598 1599 AWT_LOCK(); 1600 pX11IMData = getX11InputMethodData(env, this); 1601 1602 if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) { 1603 AWT_UNLOCK(); 1604 return JNI_FALSE; 1605 } 1606 1607 #if defined(__linux__) || defined(MACOSX) 1608 if (NULL != pX11IMData->statusWindow) { 1609 Window focus = 0; 1610 int revert_to; 1611 Window w = 0; 1612 XGetInputFocus(awt_display, &focus, &revert_to); 1613 XGetICValues(pX11IMData->current_ic, XNFocusWindow, &w, NULL); 1614 if (RevertToPointerRoot == revert_to 1615 && pX11IMData->ic_active != pX11IMData->ic_passive) { 1616 if (pX11IMData->current_ic == pX11IMData->ic_active) { 1617 if (getParentWindow(focus) == getParentWindow(w)) { 1618 XUnsetICFocus(pX11IMData->ic_active); 1619 calledXSetICFocus = True; 1620 } 1621 } 1622 } 1623 } 1624 #endif 1625 pr_atrb = XVaCreateNestedList(0, 1626 XNPreeditState, (enable ? XIMPreeditEnable : XIMPreeditDisable), 1627 NULL); 1628 ret = XSetICValues(pX11IMData->current_ic, XNPreeditAttributes, pr_atrb, NULL); 1629 XFree((void *)pr_atrb); 1630 #if defined(__linux__) || defined(MACOSX) 1631 if (calledXSetICFocus) { 1632 XSetICFocus(pX11IMData->ic_active); 1633 } 1634 #endif 1635 AWT_UNLOCK(); 1636 1637 if ((ret != 0) 1638 && ((strcmp(ret, XNPreeditAttributes) == 0) 1639 || (strcmp(ret, XNPreeditState) == 0))) { 1640 JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", ""); 1641 } 1642 1643 return (jboolean)(ret == 0); 1644 } 1645 1646 /* 1647 * Class: sun_awt_X11InputMethodBase 1648 * Method: isCompositionEnabledNative 1649 * Signature: ()Z 1650 * 1651 * This method tries to get the XNPreeditState attribute associated with the current XIC. 1652 * 1653 * Return JNI_TRUE if the XNPreeditState is successfully retrieved. Otherwise, if 1654 * XGetICValues fails to get this attribute, java.lang.UnsupportedOperationException 1655 * will be thrown. JNI_FALSE is returned if this method fails due to other reasons. 1656 */ 1657 JNIEXPORT jboolean JNICALL Java_sun_awt_X11InputMethodBase_isCompositionEnabledNative 1658 (JNIEnv *env, jobject this) 1659 { 1660 X11InputMethodData *pX11IMData = NULL; 1661 char * ret = NULL; 1662 XIMPreeditState state = XIMPreeditUnKnown; 1663 XVaNestedList pr_atrb; 1664 1665 AWT_LOCK(); 1666 pX11IMData = getX11InputMethodData(env, this); 1667 1668 if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) { 1669 AWT_UNLOCK(); 1670 return JNI_FALSE; 1671 } 1672 1673 pr_atrb = XVaCreateNestedList(0, XNPreeditState, &state, NULL); 1674 ret = XGetICValues(pX11IMData->current_ic, XNPreeditAttributes, pr_atrb, NULL); 1675 XFree((void *)pr_atrb); 1676 AWT_UNLOCK(); 1677 1678 if ((ret != 0) 1679 && ((strcmp(ret, XNPreeditAttributes) == 0) 1680 || (strcmp(ret, XNPreeditState) == 0))) { 1681 JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", ""); 1682 return JNI_FALSE; 1683 } 1684 1685 return (jboolean)(state == XIMPreeditEnable); 1686 } 1687 1688 JNIEXPORT void JNICALL Java_sun_awt_X11_XInputMethod_adjustStatusWindow 1689 (JNIEnv *env, jobject this, jlong window) 1690 { 1691 #if defined(__linux__) || defined(MACOSX) 1692 AWT_LOCK(); 1693 adjustStatusWindow(window); 1694 AWT_UNLOCK(); 1695 #endif 1696 } 1697 1698 #if defined(__linux__) || defined(MACOSX) 1699 static Window getParentWindow(Window w) 1700 { 1701 Window root=None, parent=None, *ignore_children=NULL; 1702 unsigned int ignore_uint=0; 1703 Status status = 0; 1704 1705 if (w == None) 1706 return None; 1707 status = XQueryTree(dpy, w, &root, &parent, &ignore_children, &ignore_uint); 1708 XFree(ignore_children); 1709 if (status == 0) 1710 return None; 1711 return parent; 1712 } 1713 #endif |