11ab64890Smrg/* 21ab64890SmrgCopyright 1985, 1986, 1987, 1991, 1998 The Open Group 31ab64890Smrg 41ab64890SmrgPermission is hereby granted, free of charge, to any person obtaining a 51ab64890Smrgcopy of this software and associated documentation files (the 61ab64890Smrg"Software"), to deal in the Software without restriction, including 71ab64890Smrgwithout limitation the rights to use, copy, modify, merge, publish, 81ab64890Smrgdistribute, sublicense, and/or sell copies of the Software, and to 91ab64890Smrgpermit persons to whom the Software is furnished to do so, subject to 101ab64890Smrgthe following conditions: The above copyright notice and this 111ab64890Smrgpermission notice shall be included in all copies or substantial 121ab64890Smrgportions of the Software. 131ab64890Smrg 141ab64890Smrg 15b4ee4795SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b4ee4795SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b4ee4795SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18b4ee4795SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19b4ee4795SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20b4ee4795SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE 21b4ee4795SmrgEVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES. 221ab64890Smrg 231ab64890Smrg 24b4ee4795SmrgExcept as contained in this notice, the name of The Open Group shall not be 25b4ee4795Smrgused in advertising or otherwise to promote the sale, use or other dealings 26b4ee4795Smrgin this Software without prior written authorization from The Open Group. 271ab64890Smrg 281ab64890Smrg 291ab64890SmrgX Window System is a trademark of The Open Group 301ab64890Smrg 311ab64890SmrgOSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF 321ab64890Smrglogo, LBX, X Window System, and Xinerama are trademarks of the Open 331ab64890SmrgGroup. All other trademarks and registered trademarks mentioned herein 341ab64890Smrgare the property of their respective owners. No right, title or 351ab64890Smrginterest in or to any trademark, service mark, logo or trade name of 361ab64890SmrgSun Microsystems, Inc. or its licensors is granted. 371ab64890Smrg 381ab64890Smrg*/ 39b4ee4795Smrg/* 405efbdfc3Smrg * Copyright (c) 2000, Oracle and/or its affiliates. 41b4ee4795Smrg * 42b4ee4795Smrg * Permission is hereby granted, free of charge, to any person obtaining a 43b4ee4795Smrg * copy of this software and associated documentation files (the "Software"), 44b4ee4795Smrg * to deal in the Software without restriction, including without limitation 45b4ee4795Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 46b4ee4795Smrg * and/or sell copies of the Software, and to permit persons to whom the 47b4ee4795Smrg * Software is furnished to do so, subject to the following conditions: 48b4ee4795Smrg * 49b4ee4795Smrg * The above copyright notice and this permission notice (including the next 50b4ee4795Smrg * paragraph) shall be included in all copies or substantial portions of the 51b4ee4795Smrg * Software. 52b4ee4795Smrg * 53b4ee4795Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 54b4ee4795Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 55b4ee4795Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 56b4ee4795Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 57b4ee4795Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 58b4ee4795Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 59b4ee4795Smrg * DEALINGS IN THE SOFTWARE. 60b4ee4795Smrg */ 61b4ee4795Smrg 621ab64890Smrg 631ab64890Smrg#ifdef HAVE_CONFIG_H 641ab64890Smrg#include <config.h> 651ab64890Smrg#endif 661ab64890Smrg#include <stdio.h> 671ab64890Smrg#include "Xlibint.h" 681ab64890Smrg#include "Xlcint.h" 691ab64890Smrg#include "XlcGeneric.h" 70258a0ebeSmrg#include "reallocarray.h" 711ab64890Smrg 721ab64890Smrg#ifndef MAXINT 731ab64890Smrg#define MAXINT (~((unsigned int)1 << (8 * sizeof(int)) - 1)) 741ab64890Smrg#endif /* !MAXINT */ 751ab64890Smrg 761ab64890Smrgtypedef struct _StaticXIM *StaticXIM; 771ab64890Smrg 781ab64890Smrgtypedef struct _XIMStaticXIMRec { 791ab64890Smrg /* for CT => MB,WC converter */ 801ab64890Smrg XlcConv ctom_conv; 811ab64890Smrg XlcConv ctow_conv; 821ab64890Smrg} XIMStaticXIMRec; 831ab64890Smrg 841ab64890Smrgtypedef enum { 851ab64890Smrg CREATE_IC = 1, 861ab64890Smrg SET_ICVAL = 2, 871ab64890Smrg GET_ICVAL = 3 881ab64890Smrg} XICOp_t; 891ab64890Smrg 901ab64890Smrgtypedef struct _StaticXIM { 911ab64890Smrg XIMMethods methods; 921ab64890Smrg XIMCoreRec core; 931ab64890Smrg XIMStaticXIMRec *private; 941ab64890Smrg} StaticXIMRec; 951ab64890Smrg 961ab64890Smrgstatic Status _CloseIM( 971ab64890Smrg XIM 981ab64890Smrg); 991ab64890Smrg 1001ab64890Smrgstatic char *_SetIMValues( 1011ab64890Smrg XIM, XIMArg * 1021ab64890Smrg); 1031ab64890Smrg 1041ab64890Smrgstatic char *_GetIMValues( 1051ab64890Smrg XIM, XIMArg* 1061ab64890Smrg); 1071ab64890Smrg 1081ab64890Smrgstatic XIC _CreateIC( 1091ab64890Smrg XIM, XIMArg* 1101ab64890Smrg); 1111ab64890Smrg 1121ab64890Smrgstatic _Xconst XIMMethodsRec local_im_methods = { 1131ab64890Smrg _CloseIM, /* close */ 1141ab64890Smrg _SetIMValues, /* set_values */ 1151ab64890Smrg _GetIMValues, /* get_values */ 1161ab64890Smrg _CreateIC, /* create_ic */ 1171ab64890Smrg NULL, /* ctstombs */ 1181ab64890Smrg NULL /* ctstowcs */ 1191ab64890Smrg}; 1201ab64890Smrg 1211ab64890Smrgstatic void _DestroyIC( 1221ab64890Smrg XIC 1231ab64890Smrg); 1241ab64890Smrgstatic void _SetFocus( 1251ab64890Smrg XIC 1261ab64890Smrg); 1271ab64890Smrgstatic void _UnsetFocus( 1281ab64890Smrg XIC 1291ab64890Smrg); 1301ab64890Smrgstatic char* _SetICValues( 1311ab64890Smrg XIC, XIMArg * 1321ab64890Smrg); 1331ab64890Smrgstatic char* _GetICValues( 1341ab64890Smrg XIC, XIMArg * 1351ab64890Smrg); 1361ab64890Smrgstatic char *_MbReset( 1371ab64890Smrg XIC 1381ab64890Smrg); 1391ab64890Smrgstatic wchar_t *_WcReset( 1401ab64890Smrg XIC 1411ab64890Smrg); 1421ab64890Smrgstatic int _MbLookupString( 1431ab64890Smrg XIC, XKeyEvent *, char *, int, KeySym *, Status * 1441ab64890Smrg); 1451ab64890Smrgstatic int _WcLookupString( 1461ab64890Smrg XIC, XKeyEvent *, wchar_t *, int, KeySym *, Status * 1471ab64890Smrg); 1481ab64890Smrg 1491ab64890Smrgstatic _Xconst XICMethodsRec local_ic_methods = { 1501ab64890Smrg _DestroyIC, /* destroy */ 1511ab64890Smrg _SetFocus, /* set_focus */ 1521ab64890Smrg _UnsetFocus, /* unset_focus */ 1531ab64890Smrg _SetICValues, /* set_values */ 1541ab64890Smrg _GetICValues, /* get_values */ 1551ab64890Smrg _MbReset, /* mb_reset */ 1561ab64890Smrg _WcReset, /* wc_reset */ 1571ab64890Smrg NULL, /* utf8_reset */ /* ??? */ 1581ab64890Smrg _MbLookupString, /* mb_lookup_string */ 1591ab64890Smrg _WcLookupString, /* wc_lookup_string */ 1601ab64890Smrg NULL /* utf8_lookup_string */ /* ??? */ 1611ab64890Smrg}; 1621ab64890Smrg 1631ab64890SmrgXIM 1641ab64890Smrg_XDefaultOpenIM( 1651ab64890Smrg XLCd lcd, 1661ab64890Smrg Display *dpy, 1671ab64890Smrg XrmDatabase rdb, 1681ab64890Smrg char *res_name, 1691ab64890Smrg char *res_class) 1701ab64890Smrg{ 1711ab64890Smrg StaticXIM im; 1721ab64890Smrg int i; 1731ab64890Smrg char *mod; 1741ab64890Smrg char buf[BUFSIZ]; 1751ab64890Smrg 1762d67cb4fSmrg if ((im = Xcalloc(1, sizeof(StaticXIMRec))) == NULL) 1772d67cb4fSmrg return NULL; 17861b2299dSmrg 1792d67cb4fSmrg if ((im->private = Xcalloc(1, sizeof(XIMStaticXIMRec))) == NULL) 1802d67cb4fSmrg goto Error; 1811ab64890Smrg 1822d67cb4fSmrg if ((im->private->ctom_conv = _XlcOpenConverter(lcd, XlcNCompoundText, 1832d67cb4fSmrg lcd, XlcNMultiByte)) 1842d67cb4fSmrg == NULL) 1852d67cb4fSmrg goto Error; 1862d67cb4fSmrg 1872d67cb4fSmrg if ((im->private->ctow_conv = _XlcOpenConverter(lcd, XlcNCompoundText, 1882d67cb4fSmrg lcd, XlcNWideChar)) 1892d67cb4fSmrg == NULL) 1902d67cb4fSmrg goto Error; 1911ab64890Smrg 1921ab64890Smrg buf[0] = '\0'; 1931ab64890Smrg i = 0; 1941ab64890Smrg if ((lcd->core->modifiers) && (*lcd->core->modifiers)) { 1951ab64890Smrg#define MODIFIER "@im=" 1961ab64890Smrg mod = strstr(lcd->core->modifiers, MODIFIER); 1971ab64890Smrg if (mod) { 1981ab64890Smrg mod += strlen(MODIFIER); 1991ab64890Smrg while (*mod && *mod != '@' && i < BUFSIZ - 1) { 2001ab64890Smrg buf[i++] = *mod++; 2011ab64890Smrg } 2021ab64890Smrg buf[i] = '\0'; 2031ab64890Smrg } 2041ab64890Smrg } 2051ab64890Smrg#undef MODIFIER 2062d67cb4fSmrg if ((im->core.im_name = strdup(buf)) == NULL) 2072d67cb4fSmrg goto Error; 2081ab64890Smrg 2091ab64890Smrg im->methods = (XIMMethods)&local_im_methods; 2101ab64890Smrg im->core.lcd = lcd; 2111ab64890Smrg im->core.ic_chain = (XIC)NULL; 2121ab64890Smrg im->core.display = dpy; 2131ab64890Smrg im->core.rdb = rdb; 2141ab64890Smrg im->core.res_name = NULL; 2151ab64890Smrg im->core.res_class = NULL; 2161ab64890Smrg 2171ab64890Smrg if ((res_name != NULL) && (*res_name != '\0')){ 2186cc2b21fSmrg im->core.res_name = strdup(res_name); 2191ab64890Smrg } 2201ab64890Smrg if ((res_class != NULL) && (*res_class != '\0')){ 2216cc2b21fSmrg im->core.res_class = strdup(res_class); 2221ab64890Smrg } 2231ab64890Smrg 2241ab64890Smrg return (XIM)im; 2252d67cb4fSmrg 2262d67cb4fSmrg Error: 2272d67cb4fSmrg _CloseIM((XIM)im); 2281ab64890Smrg Xfree(im); 2291ab64890Smrg return(NULL); 2301ab64890Smrg} 2311ab64890Smrg 2321ab64890Smrgstatic Status 2331ab64890Smrg_CloseIM(XIM xim) 2341ab64890Smrg{ 2351ab64890Smrg StaticXIM im = (StaticXIM)xim; 2362d67cb4fSmrg 2372d67cb4fSmrg if (im->private->ctom_conv != NULL) 2382d67cb4fSmrg _XlcCloseConverter(im->private->ctom_conv); 2392d67cb4fSmrg if (im->private->ctow_conv != NULL) 2402d67cb4fSmrg _XlcCloseConverter(im->private->ctow_conv); 2411ab64890Smrg XFree(im->private); 2421ab64890Smrg XFree(im->core.im_name); 2432d67cb4fSmrg XFree(im->core.res_name); 2442d67cb4fSmrg XFree(im->core.res_class); 2452d67cb4fSmrg return 1; 2461ab64890Smrg} 2471ab64890Smrg 2481ab64890Smrgstatic char * 2491ab64890Smrg_SetIMValues( 2501ab64890Smrg XIM xim, 2511ab64890Smrg XIMArg *arg) 2521ab64890Smrg{ 2531ab64890Smrg return(arg->name); /* evil */ 2541ab64890Smrg} 2551ab64890Smrg 2561ab64890Smrgstatic char * 2571ab64890Smrg_GetIMValues( 2581ab64890Smrg XIM xim, 2591ab64890Smrg XIMArg *values) 2601ab64890Smrg{ 2611ab64890Smrg XIMArg *p; 2621ab64890Smrg XIMStyles *styles; 2631ab64890Smrg 2641ab64890Smrg for (p = values; p->name != NULL; p++) { 2651ab64890Smrg if (strcmp(p->name, XNQueryInputStyle) == 0) { 266818534a1Smrg styles = Xmalloc(sizeof(XIMStyles)); 2671ab64890Smrg *(XIMStyles **)p->value = styles; 2681ab64890Smrg styles->count_styles = 1; 2691ab64890Smrg styles->supported_styles = 270258a0ebeSmrg Xmallocarray(styles->count_styles, sizeof(XIMStyle)); 2711ab64890Smrg styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone); 2721ab64890Smrg } else { 2731ab64890Smrg break; 2741ab64890Smrg } 2751ab64890Smrg } 2761ab64890Smrg return (p->name); 2771ab64890Smrg} 2781ab64890Smrg 2791ab64890Smrgstatic char* 2801ab64890Smrg_SetICValueData(XIC ic, XIMArg *values, XICOp_t mode) 2811ab64890Smrg{ 2821ab64890Smrg XIMArg *p; 2831ab64890Smrg char *return_name = NULL; 2841ab64890Smrg 2851ab64890Smrg for (p = values; p != NULL && p->name != NULL; p++) { 2861ab64890Smrg if(strcmp(p->name, XNInputStyle) == 0) { 2871ab64890Smrg if (mode == CREATE_IC) 2881ab64890Smrg ic->core.input_style = (XIMStyle)p->value; 2891ab64890Smrg } else if (strcmp(p->name, XNClientWindow) == 0) { 2901ab64890Smrg ic->core.client_window = (Window)p->value ; 2911ab64890Smrg } else if (strcmp(p->name, XNFocusWindow) == 0) { 2921ab64890Smrg ic->core.focus_window = (Window)p->value ; 2931ab64890Smrg } else if (strcmp(p->name, XNPreeditAttributes) == 0 2941ab64890Smrg || strcmp(p->name, XNStatusAttributes) == 0) { 2951ab64890Smrg return_name = _SetICValueData(ic, (XIMArg*)p->value, mode); 2961ab64890Smrg if (return_name) break; 2971ab64890Smrg } else { 2981ab64890Smrg return_name = p->name; 2991ab64890Smrg break; 3001ab64890Smrg } 3011ab64890Smrg } 3021ab64890Smrg return(return_name); 3031ab64890Smrg} 3041ab64890Smrg 3051ab64890Smrgstatic char* 3061ab64890Smrg_GetICValueData(XIC ic, XIMArg *values, XICOp_t mode) 3071ab64890Smrg{ 3081ab64890Smrg XIMArg *p; 3091ab64890Smrg char *return_name = NULL; 3101ab64890Smrg 3111ab64890Smrg for (p = values; p->name != NULL; p++) { 3121ab64890Smrg if(strcmp(p->name, XNInputStyle) == 0) { 3131ab64890Smrg *((XIMStyle *)(p->value)) = ic->core.input_style; 3141ab64890Smrg } else if (strcmp(p->name, XNClientWindow) == 0) { 3151ab64890Smrg *((Window *)(p->value)) = ic->core.client_window; 3161ab64890Smrg } else if (strcmp(p->name, XNFocusWindow) == 0) { 3171ab64890Smrg *((Window *)(p->value)) = ic->core.focus_window; 3181ab64890Smrg } else if (strcmp(p->name, XNFilterEvents) == 0) { 3191ab64890Smrg *((unsigned long *)(p->value))= ic->core.filter_events; 3201ab64890Smrg } else if (strcmp(p->name, XNPreeditAttributes) == 0 3211ab64890Smrg || strcmp(p->name, XNStatusAttributes) == 0) { 3221ab64890Smrg return_name = _GetICValueData(ic, (XIMArg*)p->value, mode); 3231ab64890Smrg if (return_name) break; 3241ab64890Smrg } else { 3251ab64890Smrg return_name = p->name; 3261ab64890Smrg break; 3271ab64890Smrg } 3281ab64890Smrg } 3291ab64890Smrg return(return_name); 3301ab64890Smrg} 3311ab64890Smrg 3321ab64890Smrgstatic XIC 3331ab64890Smrg_CreateIC(XIM im, XIMArg *arg) 3341ab64890Smrg{ 3351ab64890Smrg XIC ic; 3361ab64890Smrg 3372d67cb4fSmrg if ((ic = Xcalloc(1, sizeof(XICRec))) == (XIC)NULL) { 3381ab64890Smrg return ((XIC)NULL); 3391ab64890Smrg } 3401ab64890Smrg 3411ab64890Smrg ic->methods = (XICMethods)&local_ic_methods; 3421ab64890Smrg ic->core.im = im; 3431ab64890Smrg ic->core.filter_events = KeyPressMask; 3441ab64890Smrg 3451ab64890Smrg if (_SetICValueData(ic, arg, CREATE_IC) != NULL) 3461ab64890Smrg goto err_return; 3471ab64890Smrg if (!(ic->core.input_style)) 3481ab64890Smrg goto err_return; 3491ab64890Smrg 3501ab64890Smrg return (XIC)ic; 3511ab64890Smrgerr_return: 3521ab64890Smrg XFree(ic); 3531ab64890Smrg return ((XIC)NULL); 3541ab64890Smrg} 3551ab64890Smrg 3561ab64890Smrgstatic void 3571ab64890Smrg_DestroyIC(XIC ic) 3581ab64890Smrg{ 3591ab64890Smrg/*BugId4255571. This Xfree() should be removed because XDestroyIC() still need ic after invoking _DestroyIC() and there is a XFree(ic) at the end of XDestroyIC() already. 3601ab64890Smrg if(ic) 3611ab64890Smrg XFree(ic); */ 3621ab64890Smrg} 3631ab64890Smrg 3641ab64890Smrgstatic void 3651ab64890Smrg_SetFocus(XIC ic) 3661ab64890Smrg{ 3671ab64890Smrg} 3681ab64890Smrg 3691ab64890Smrgstatic void 3701ab64890Smrg_UnsetFocus(XIC ic) 3711ab64890Smrg{ 3721ab64890Smrg} 3731ab64890Smrg 3741ab64890Smrgstatic char* 3751ab64890Smrg_SetICValues(XIC ic, XIMArg *args) 3761ab64890Smrg{ 3771ab64890Smrg char *ret = NULL; 3781ab64890Smrg if (!ic) { 3791ab64890Smrg return (args->name); 3801ab64890Smrg } 3811ab64890Smrg ret = _SetICValueData(ic, args, SET_ICVAL); 3821ab64890Smrg return(ret); 3831ab64890Smrg} 3841ab64890Smrg 3851ab64890Smrgstatic char* 3861ab64890Smrg_GetICValues(XIC ic, XIMArg *args) 3871ab64890Smrg{ 3881ab64890Smrg char *ret = NULL; 3891ab64890Smrg if (!ic) { 3901ab64890Smrg return (args->name); 3911ab64890Smrg } 3921ab64890Smrg ret = _GetICValueData(ic, args, GET_ICVAL); 3931ab64890Smrg return(ret); 3941ab64890Smrg} 3951ab64890Smrg 3961ab64890Smrgstatic char * 3971ab64890Smrg_MbReset(XIC xic) 3981ab64890Smrg{ 3991ab64890Smrg return(NULL); 4001ab64890Smrg} 4011ab64890Smrg 4021ab64890Smrgstatic wchar_t * 4031ab64890Smrg_WcReset(XIC xic) 4041ab64890Smrg{ 4051ab64890Smrg return(NULL); 4061ab64890Smrg} 4071ab64890Smrg 4081ab64890Smrgstatic int 4091ab64890Smrg_MbLookupString( 4101ab64890Smrg XIC xic, 4111ab64890Smrg XKeyEvent *ev, 4121ab64890Smrg char * buffer, 4131ab64890Smrg int bytes, 4141ab64890Smrg KeySym *keysym, 4151ab64890Smrg Status *status) 4161ab64890Smrg{ 4171ab64890Smrg XComposeStatus NotSupportedYet ; 4181ab64890Smrg int length; 41961b2299dSmrg 4201ab64890Smrg length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet); 4211ab64890Smrg 4221ab64890Smrg if (keysym && *keysym == NoSymbol){ 4231ab64890Smrg *status = XLookupNone; 4241ab64890Smrg } else if (length > 0) { 4251ab64890Smrg *status = XLookupBoth; 4261ab64890Smrg } else { 4271ab64890Smrg *status = XLookupKeySym; 4281ab64890Smrg } 4291ab64890Smrg return(length); 4301ab64890Smrg} 4311ab64890Smrg 4321ab64890Smrgstatic int 4331ab64890Smrg_WcLookupString( 4341ab64890Smrg XIC xic, 4351ab64890Smrg XKeyEvent *ev, 4361ab64890Smrg wchar_t * buffer, 4371ab64890Smrg int wlen, 4381ab64890Smrg KeySym *keysym, 4391ab64890Smrg Status *status) 4401ab64890Smrg{ 4411ab64890Smrg XComposeStatus NotSupportedYet ; 4421ab64890Smrg int length; 4431ab64890Smrg /* In single-byte, mb_len = wc_len */ 444818534a1Smrg char *mb_buf = Xmalloc(wlen); 4451ab64890Smrg 4461ab64890Smrg length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet); 4471ab64890Smrg 4481ab64890Smrg if (keysym && *keysym == NoSymbol){ 4491ab64890Smrg *status = XLookupNone; 4501ab64890Smrg } else if (length > 0) { 4511ab64890Smrg *status = XLookupBoth; 4521ab64890Smrg } else { 4531ab64890Smrg *status = XLookupKeySym; 4541ab64890Smrg } 4559c019ec5Smaya mbstowcs(buffer, mb_buf, (size_t) length); 4561ab64890Smrg XFree(mb_buf); 4571ab64890Smrg return(length); 4581ab64890Smrg} 459