XDefaultIMIF.c revision e9fcaa8a
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/*
40e9fcaa8aSmrg * Copyright 2000 Oracle and/or its affiliates. All rights reserved.
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"
701ab64890Smrg
711ab64890Smrg#ifndef MAXINT
721ab64890Smrg#define MAXINT          (~((unsigned int)1 << (8 * sizeof(int)) - 1))
731ab64890Smrg#endif /* !MAXINT */
741ab64890Smrg
751ab64890Smrgtypedef struct _StaticXIM *StaticXIM;
761ab64890Smrg
771ab64890Smrgtypedef struct _XIMStaticXIMRec {
781ab64890Smrg    /* for CT => MB,WC converter */
791ab64890Smrg    XlcConv		 ctom_conv;
801ab64890Smrg    XlcConv		 ctow_conv;
811ab64890Smrg} XIMStaticXIMRec;
821ab64890Smrg
831ab64890Smrgtypedef enum {
841ab64890Smrg    CREATE_IC = 1,
851ab64890Smrg    SET_ICVAL = 2,
861ab64890Smrg    GET_ICVAL = 3
871ab64890Smrg} XICOp_t;
881ab64890Smrg
891ab64890Smrgtypedef struct _StaticXIM {
901ab64890Smrg    XIMMethods		methods;
911ab64890Smrg    XIMCoreRec		core;
921ab64890Smrg    XIMStaticXIMRec	*private;
931ab64890Smrg} StaticXIMRec;
941ab64890Smrg
951ab64890Smrgstatic Status _CloseIM(
961ab64890Smrg	XIM
971ab64890Smrg);
981ab64890Smrg
991ab64890Smrgstatic char *_SetIMValues(
1001ab64890Smrg	XIM, XIMArg *
1011ab64890Smrg);
1021ab64890Smrg
1031ab64890Smrgstatic char *_GetIMValues(
1041ab64890Smrg	XIM, XIMArg*
1051ab64890Smrg);
1061ab64890Smrg
1071ab64890Smrgstatic XIC _CreateIC(
1081ab64890Smrg	XIM, XIMArg*
1091ab64890Smrg);
1101ab64890Smrg
1111ab64890Smrgstatic _Xconst XIMMethodsRec local_im_methods = {
1121ab64890Smrg    _CloseIM,		/* close */
1131ab64890Smrg    _SetIMValues,	/* set_values */
1141ab64890Smrg    _GetIMValues, 	/* get_values */
1151ab64890Smrg    _CreateIC,		/* create_ic */
1161ab64890Smrg    NULL,		/* ctstombs */
1171ab64890Smrg    NULL		/* ctstowcs */
1181ab64890Smrg};
1191ab64890Smrg
1201ab64890Smrgstatic void _DestroyIC(
1211ab64890Smrg		       XIC
1221ab64890Smrg);
1231ab64890Smrgstatic void _SetFocus(
1241ab64890Smrg		      XIC
1251ab64890Smrg);
1261ab64890Smrgstatic void _UnsetFocus(
1271ab64890Smrg			XIC
1281ab64890Smrg);
1291ab64890Smrgstatic char* _SetICValues(
1301ab64890Smrg			 XIC, XIMArg *
1311ab64890Smrg);
1321ab64890Smrgstatic char* _GetICValues(
1331ab64890Smrg			 XIC, XIMArg *
1341ab64890Smrg);
1351ab64890Smrgstatic char *_MbReset(
1361ab64890Smrg		      XIC
1371ab64890Smrg);
1381ab64890Smrgstatic wchar_t *_WcReset(
1391ab64890Smrg			 XIC
1401ab64890Smrg);
1411ab64890Smrgstatic int _MbLookupString(
1421ab64890Smrg	XIC, XKeyEvent *, char *, int, KeySym *, Status *
1431ab64890Smrg);
1441ab64890Smrgstatic int _WcLookupString(
1451ab64890Smrg	XIC, XKeyEvent *, wchar_t *, int, KeySym *, Status *
1461ab64890Smrg);
1471ab64890Smrg
1481ab64890Smrgstatic _Xconst XICMethodsRec local_ic_methods = {
1491ab64890Smrg    _DestroyIC, 	/* destroy */
1501ab64890Smrg    _SetFocus,		/* set_focus */
1511ab64890Smrg    _UnsetFocus,	/* unset_focus */
1521ab64890Smrg    _SetICValues,	/* set_values */
1531ab64890Smrg    _GetICValues,	/* get_values */
1541ab64890Smrg    _MbReset,		/* mb_reset */
1551ab64890Smrg    _WcReset,		/* wc_reset */
1561ab64890Smrg    NULL,		/* utf8_reset */		/* ??? */
1571ab64890Smrg    _MbLookupString,	/* mb_lookup_string */
1581ab64890Smrg    _WcLookupString,	/* wc_lookup_string */
1591ab64890Smrg    NULL		/* utf8_lookup_string */	/* ??? */
1601ab64890Smrg};
1611ab64890Smrg
1621ab64890SmrgXIM
1631ab64890Smrg_XDefaultOpenIM(
1641ab64890Smrg    XLCd                lcd,
1651ab64890Smrg    Display             *dpy,
1661ab64890Smrg    XrmDatabase         rdb,
1671ab64890Smrg    char                *res_name,
1681ab64890Smrg    char                *res_class)
1691ab64890Smrg{
1701ab64890Smrg    StaticXIM im;
1711ab64890Smrg    XIMStaticXIMRec *local_impart;
1721ab64890Smrg    XlcConv ctom_conv, ctow_conv;
1731ab64890Smrg    int i;
1741ab64890Smrg    char *mod;
1751ab64890Smrg    char buf[BUFSIZ];
1761ab64890Smrg
1771ab64890Smrg    if (!(ctom_conv = _XlcOpenConverter(lcd,
1781ab64890Smrg			XlcNCompoundText, lcd, XlcNMultiByte))) {
1791ab64890Smrg	return((XIM)NULL);
1801ab64890Smrg    }
18161b2299dSmrg
1821ab64890Smrg    if (!(ctow_conv = _XlcOpenConverter(lcd,
1831ab64890Smrg			XlcNCompoundText, lcd, XlcNWideChar))) {
1841ab64890Smrg	return((XIM)NULL);
1851ab64890Smrg    }
1861ab64890Smrg
1871ab64890Smrg    if ((im = (StaticXIM)Xmalloc(sizeof(StaticXIMRec))) == (StaticXIM)NULL) {
1881ab64890Smrg	return((XIM)NULL);
1891ab64890Smrg    }
1901ab64890Smrg    if ((local_impart = (XIMStaticXIMRec*)Xmalloc(sizeof(XIMStaticXIMRec)))
1911ab64890Smrg	== (XIMStaticXIMRec *)NULL) {
1921ab64890Smrg	Xfree(im);
1931ab64890Smrg	return((XIM)NULL);
1941ab64890Smrg    }
1951ab64890Smrg    memset(im, 0, sizeof(StaticXIMRec));
1961ab64890Smrg    memset(local_impart, 0, sizeof(XIMStaticXIMRec));
1971ab64890Smrg
1981ab64890Smrg    buf[0] = '\0';
1991ab64890Smrg    i = 0;
2001ab64890Smrg    if ((lcd->core->modifiers) && (*lcd->core->modifiers)) {
2011ab64890Smrg#define	MODIFIER "@im="
2021ab64890Smrg	mod = strstr(lcd->core->modifiers, MODIFIER);
2031ab64890Smrg	if (mod) {
2041ab64890Smrg	    mod += strlen(MODIFIER);
2051ab64890Smrg	    while (*mod && *mod != '@' && i < BUFSIZ - 1) {
2061ab64890Smrg		buf[i++] = *mod++;
2071ab64890Smrg	    }
2081ab64890Smrg	    buf[i] = '\0';
2091ab64890Smrg	}
2101ab64890Smrg    }
2111ab64890Smrg#undef MODIFIER
2121ab64890Smrg    if ((im->core.im_name = Xmalloc(i+1)) == NULL)
2131ab64890Smrg	goto Error2;
2141ab64890Smrg    strcpy(im->core.im_name, buf);
2151ab64890Smrg
2161ab64890Smrg    im->private = local_impart;
2171ab64890Smrg    im->methods        = (XIMMethods)&local_im_methods;
2181ab64890Smrg    im->core.lcd       = lcd;
2191ab64890Smrg    im->core.ic_chain  = (XIC)NULL;
2201ab64890Smrg    im->core.display   = dpy;
2211ab64890Smrg    im->core.rdb       = rdb;
2221ab64890Smrg    im->core.res_name  = NULL;
2231ab64890Smrg    im->core.res_class = NULL;
2241ab64890Smrg
2251ab64890Smrg    local_impart->ctom_conv = ctom_conv;
2261ab64890Smrg    local_impart->ctow_conv = ctow_conv;
2271ab64890Smrg
2281ab64890Smrg    if ((res_name != NULL) && (*res_name != '\0')){
2291ab64890Smrg	im->core.res_name  = (char *)Xmalloc(strlen(res_name)+1);
2301ab64890Smrg	strcpy(im->core.res_name,res_name);
2311ab64890Smrg    }
2321ab64890Smrg    if ((res_class != NULL) && (*res_class != '\0')){
2331ab64890Smrg	im->core.res_class = (char *)Xmalloc(strlen(res_class)+1);
2341ab64890Smrg	strcpy(im->core.res_class,res_class);
2351ab64890Smrg    }
2361ab64890Smrg
2371ab64890Smrg    return (XIM)im;
2381ab64890SmrgError2 :
2391ab64890Smrg    Xfree(im->private);
2401ab64890Smrg    Xfree(im->core.im_name);
2411ab64890Smrg    Xfree(im);
2421ab64890Smrg    _XlcCloseConverter(ctom_conv);
2431ab64890Smrg    _XlcCloseConverter(ctow_conv);
2441ab64890Smrg    return(NULL);
2451ab64890Smrg}
2461ab64890Smrg
2471ab64890Smrgstatic Status
2481ab64890Smrg_CloseIM(XIM xim)
2491ab64890Smrg{
2501ab64890Smrg    StaticXIM im = (StaticXIM)xim;
2511ab64890Smrg    _XlcCloseConverter(im->private->ctom_conv);
2521ab64890Smrg    _XlcCloseConverter(im->private->ctow_conv);
2531ab64890Smrg    XFree(im->private);
2541ab64890Smrg    XFree(im->core.im_name);
2551ab64890Smrg    if (im->core.res_name) XFree(im->core.res_name);
2561ab64890Smrg    if (im->core.res_class) XFree(im->core.res_class);
2571ab64890Smrg    return 1; /*bugID 4163122*/
2581ab64890Smrg}
2591ab64890Smrg
2601ab64890Smrgstatic char *
2611ab64890Smrg_SetIMValues(
2621ab64890Smrg    XIM xim,
2631ab64890Smrg    XIMArg *arg)
2641ab64890Smrg{
2651ab64890Smrg    return(arg->name);		/* evil */
2661ab64890Smrg}
2671ab64890Smrg
2681ab64890Smrgstatic char *
2691ab64890Smrg_GetIMValues(
2701ab64890Smrg    XIM xim,
2711ab64890Smrg    XIMArg *values)
2721ab64890Smrg{
2731ab64890Smrg    XIMArg *p;
2741ab64890Smrg    XIMStyles *styles;
2751ab64890Smrg
2761ab64890Smrg    for (p = values; p->name != NULL; p++) {
2771ab64890Smrg	if (strcmp(p->name, XNQueryInputStyle) == 0) {
2781ab64890Smrg	    styles = (XIMStyles *)Xmalloc(sizeof(XIMStyles));
2791ab64890Smrg	    *(XIMStyles **)p->value = styles;
2801ab64890Smrg	    styles->count_styles = 1;
2811ab64890Smrg	    styles->supported_styles =
2821ab64890Smrg		(XIMStyle*)Xmalloc(styles->count_styles * sizeof(XIMStyle));
2831ab64890Smrg	    styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone);
2841ab64890Smrg	} else {
2851ab64890Smrg	    break;
2861ab64890Smrg	}
2871ab64890Smrg    }
2881ab64890Smrg    return (p->name);
2891ab64890Smrg}
2901ab64890Smrg
2911ab64890Smrgstatic char*
2921ab64890Smrg_SetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
2931ab64890Smrg{
2941ab64890Smrg    XIMArg *p;
2951ab64890Smrg    char *return_name = NULL;
2961ab64890Smrg
2971ab64890Smrg    for (p = values; p != NULL && p->name != NULL; p++) {
2981ab64890Smrg	if(strcmp(p->name, XNInputStyle) == 0) {
2991ab64890Smrg	    if (mode == CREATE_IC)
3001ab64890Smrg		ic->core.input_style = (XIMStyle)p->value;
3011ab64890Smrg	} else if (strcmp(p->name, XNClientWindow) == 0) {
3021ab64890Smrg	    ic->core.client_window = (Window)p->value ;
3031ab64890Smrg	} else if (strcmp(p->name, XNFocusWindow) == 0) {
3041ab64890Smrg	    ic->core.focus_window = (Window)p->value ;
3051ab64890Smrg	} else if (strcmp(p->name, XNPreeditAttributes) == 0
3061ab64890Smrg		   || strcmp(p->name, XNStatusAttributes) == 0) {
3071ab64890Smrg            return_name = _SetICValueData(ic, (XIMArg*)p->value, mode);
3081ab64890Smrg            if (return_name) break;
3091ab64890Smrg        } else {
3101ab64890Smrg            return_name = p->name;
3111ab64890Smrg            break;
3121ab64890Smrg        }
3131ab64890Smrg    }
3141ab64890Smrg    return(return_name);
3151ab64890Smrg}
3161ab64890Smrg
3171ab64890Smrgstatic char*
3181ab64890Smrg_GetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
3191ab64890Smrg{
3201ab64890Smrg    XIMArg *p;
3211ab64890Smrg    char *return_name = NULL;
3221ab64890Smrg
3231ab64890Smrg    for (p = values; p->name != NULL; p++) {
3241ab64890Smrg	if(strcmp(p->name, XNInputStyle) == 0) {
3251ab64890Smrg	    *((XIMStyle *)(p->value)) = ic->core.input_style;
3261ab64890Smrg	} else if (strcmp(p->name, XNClientWindow) == 0) {
3271ab64890Smrg	    *((Window *)(p->value)) = ic->core.client_window;
3281ab64890Smrg	} else if (strcmp(p->name, XNFocusWindow) == 0) {
3291ab64890Smrg	    *((Window *)(p->value)) = ic->core.focus_window;
3301ab64890Smrg	} else if (strcmp(p->name, XNFilterEvents) == 0) {
3311ab64890Smrg	    *((unsigned long *)(p->value))= ic->core.filter_events;
3321ab64890Smrg	} else if (strcmp(p->name, XNPreeditAttributes) == 0
3331ab64890Smrg		   || strcmp(p->name, XNStatusAttributes) == 0) {
3341ab64890Smrg	    return_name = _GetICValueData(ic, (XIMArg*)p->value, mode);
3351ab64890Smrg	    if (return_name) break;
3361ab64890Smrg	} else {
3371ab64890Smrg	    return_name = p->name;
3381ab64890Smrg	    break;
3391ab64890Smrg	}
3401ab64890Smrg    }
3411ab64890Smrg    return(return_name);
3421ab64890Smrg}
3431ab64890Smrg
3441ab64890Smrgstatic XIC
3451ab64890Smrg_CreateIC(XIM im, XIMArg *arg)
3461ab64890Smrg{
3471ab64890Smrg    XIC ic;
3481ab64890Smrg
3491ab64890Smrg    if ((ic = (XIC)Xmalloc(sizeof(XICRec))) == (XIC)NULL) {
3501ab64890Smrg	return ((XIC)NULL);
3511ab64890Smrg    }
3521ab64890Smrg    memset(ic, 0, sizeof(XICRec));
3531ab64890Smrg
3541ab64890Smrg    ic->methods = (XICMethods)&local_ic_methods;
3551ab64890Smrg    ic->core.im = im;
3561ab64890Smrg    ic->core.filter_events = KeyPressMask;
3571ab64890Smrg
3581ab64890Smrg    if (_SetICValueData(ic, arg, CREATE_IC) != NULL)
3591ab64890Smrg	goto err_return;
3601ab64890Smrg    if (!(ic->core.input_style))
3611ab64890Smrg	goto err_return;
3621ab64890Smrg
3631ab64890Smrg    return (XIC)ic;
3641ab64890Smrgerr_return:
3651ab64890Smrg    XFree(ic);
3661ab64890Smrg    return ((XIC)NULL);
3671ab64890Smrg}
3681ab64890Smrg
3691ab64890Smrgstatic void
3701ab64890Smrg_DestroyIC(XIC ic)
3711ab64890Smrg{
3721ab64890Smrg/*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.
3731ab64890Smrg   if(ic)
3741ab64890Smrg   	XFree(ic); */
3751ab64890Smrg}
3761ab64890Smrg
3771ab64890Smrgstatic void
3781ab64890Smrg_SetFocus(XIC ic)
3791ab64890Smrg{
3801ab64890Smrg}
3811ab64890Smrg
3821ab64890Smrgstatic void
3831ab64890Smrg_UnsetFocus(XIC ic)
3841ab64890Smrg{
3851ab64890Smrg}
3861ab64890Smrg
3871ab64890Smrgstatic char*
3881ab64890Smrg_SetICValues(XIC ic, XIMArg *args)
3891ab64890Smrg{
3901ab64890Smrg    char *ret = NULL;
3911ab64890Smrg    if (!ic) {
3921ab64890Smrg        return (args->name);
3931ab64890Smrg    }
3941ab64890Smrg    ret = _SetICValueData(ic, args, SET_ICVAL);
3951ab64890Smrg    return(ret);
3961ab64890Smrg}
3971ab64890Smrg
3981ab64890Smrgstatic char*
3991ab64890Smrg_GetICValues(XIC ic, XIMArg *args)
4001ab64890Smrg{
4011ab64890Smrg    char *ret = NULL;
4021ab64890Smrg    if (!ic) {
4031ab64890Smrg        return (args->name);
4041ab64890Smrg    }
4051ab64890Smrg    ret = _GetICValueData(ic, args, GET_ICVAL);
4061ab64890Smrg    return(ret);
4071ab64890Smrg}
4081ab64890Smrg
4091ab64890Smrgstatic char *
4101ab64890Smrg_MbReset(XIC xic)
4111ab64890Smrg{
4121ab64890Smrg    return(NULL);
4131ab64890Smrg}
4141ab64890Smrg
4151ab64890Smrgstatic wchar_t *
4161ab64890Smrg_WcReset(XIC xic)
4171ab64890Smrg{
4181ab64890Smrg    return(NULL);
4191ab64890Smrg}
4201ab64890Smrg
4211ab64890Smrgstatic int
4221ab64890Smrg_MbLookupString(
4231ab64890Smrg    XIC xic,
4241ab64890Smrg    XKeyEvent *ev,
4251ab64890Smrg    char * buffer,
4261ab64890Smrg    int bytes,
4271ab64890Smrg    KeySym *keysym,
4281ab64890Smrg    Status *status)
4291ab64890Smrg{
4301ab64890Smrg    XComposeStatus NotSupportedYet ;
4311ab64890Smrg    int length;
43261b2299dSmrg
4331ab64890Smrg    length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet);
4341ab64890Smrg
4351ab64890Smrg    if (keysym && *keysym == NoSymbol){
4361ab64890Smrg	*status = XLookupNone;
4371ab64890Smrg    } else if (length > 0) {
4381ab64890Smrg	*status = XLookupBoth;
4391ab64890Smrg    } else {
4401ab64890Smrg	*status = XLookupKeySym;
4411ab64890Smrg    }
4421ab64890Smrg    return(length);
4431ab64890Smrg}
4441ab64890Smrg
4451ab64890Smrgstatic int
4461ab64890Smrg_WcLookupString(
4471ab64890Smrg    XIC xic,
4481ab64890Smrg    XKeyEvent *ev,
4491ab64890Smrg    wchar_t * buffer,
4501ab64890Smrg    int wlen,
4511ab64890Smrg    KeySym *keysym,
4521ab64890Smrg    Status *status)
4531ab64890Smrg{
4541ab64890Smrg    XComposeStatus NotSupportedYet ;
4551ab64890Smrg    int length;
4561ab64890Smrg    /* In single-byte, mb_len = wc_len */
4571ab64890Smrg    char *mb_buf = (char *)Xmalloc(wlen);
4581ab64890Smrg
4591ab64890Smrg    length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet);
4601ab64890Smrg
4611ab64890Smrg    if (keysym && *keysym == NoSymbol){
4621ab64890Smrg	*status = XLookupNone;
4631ab64890Smrg    } else if (length > 0) {
4641ab64890Smrg	*status = XLookupBoth;
4651ab64890Smrg    } else {
4661ab64890Smrg	*status = XLookupKeySym;
4671ab64890Smrg    }
4681ab64890Smrg    mbstowcs(buffer, mb_buf, length);
4691ab64890Smrg    XFree(mb_buf);
4701ab64890Smrg    return(length);
4711ab64890Smrg}
472