4.4BSD/usr/src/contrib/X11R5-lib/lib/X/XlcWrap.c
/*
* $XConsortium: XlcWrap.c,v 11.9 92/04/24 16:07:40 rws Exp $
*/
/*
* Copyright 1991 by the Massachusetts Institute of Technology
* Copyright 1991 by the Open Software Foundation
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the names of Open Software Foundation and M.I.T.
* not be used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. Open Software
* Foundation and M.I.T. make no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* OPEN SOFTWARE FOUNDATION AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL OPEN SOFTWARE FOUNDATIONN OR M.I.T. BE
* LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* M. Collins OSF
*/
#include "Xlibint.h"
#include "Xlcint.h"
#include <X11/Xlocale.h>
#include <X11/Xos.h>
#if __STDC__
#define Const const
#else
#define Const /**/
#endif
#ifdef X_NOT_STDC_ENV
extern char *getenv();
#endif
extern XLCd _XlcDefaultLoader(
#if NeedFunctionPrototypes
char*
#endif
);
#if NeedFunctionPrototypes
char *
XSetLocaleModifiers(
_Xconst char *modifiers
)
#else
char *
XSetLocaleModifiers(modifiers)
char *modifiers;
#endif
{
XLCd lcd = _XlcCurrentLC();
char *user_mods;
if (!lcd)
return (char *) NULL;
if (!modifiers)
return lcd->core.modifiers;
user_mods = getenv("XMODIFIERS");
modifiers = (*lcd->methods->map_modifiers) (lcd,
user_mods, (char *)modifiers);
if (modifiers)
lcd->core.modifiers = (char *)modifiers;
return (char *)modifiers;
}
Bool
XSupportsLocale()
{
return _XlcCurrentLC() != (XLCd)NULL;
}
Bool _XlcValidModSyntax(mods, valid_mods)
char *mods;
char **valid_mods;
{
int i;
char **ptr;
while (mods && (*mods == '@')) {
mods++;
if (*mods == '@')
break;
for (ptr = valid_mods; *ptr; ptr++) {
i = strlen(*ptr);
if (strncmp(mods, *ptr, i) || (mods[i] != '='))
continue;
mods = index(mods+i+1, '@');
break;
}
}
return !mods || !*mods;
}
static Const char *im_valid[] = {"im", (char *)NULL};
/*ARGSUSED*/
char *
_XlcDefaultMapModifiers (lcd, user_mods, prog_mods)
XLCd lcd;
char *user_mods;
char *prog_mods;
{
int i;
char *mods;
if (!_XlcValidModSyntax(prog_mods, (char **)im_valid))
return (char *)NULL;
if (!_XlcValidModSyntax(user_mods, (char **)im_valid))
return (char *)NULL;
i = strlen(prog_mods) + 1;
if (user_mods)
i += strlen(user_mods);
mods = Xmalloc(i);
if (mods) {
strcpy(mods, prog_mods);
if (user_mods)
strcat(mods, user_mods);
}
return mods;
}
#ifndef lint
static lock;
#endif /* lint */
static XLCd *lcd_list;
static XLCdLoadProc *loaders;
Bool
_XlcAddLoader (proc)
XLCdLoadProc proc;
{
if (!loaders) {
loaders = (XLCdLoadProc *) Xmalloc (2 * sizeof(XLCdLoadProc));
if (!loaders)
return False;
loaders[0] = proc;
loaders[1] = (XLCdLoadProc) NULL;
} else {
}
return True;
}
/*
* Get the XLCd for the current locale
*/
XLCd
_XlcCurrentLC ()
{
char *name;
XLCd lcd;
int i, j;
name = setlocale (LC_CTYPE, (char *)NULL);
LockMutex(&lock);
/*
* if first-time, build a list and load the one needed
*/
if (!lcd_list) {
lcd_list = (XLCd *) Xmalloc (sizeof(XLCd));
if (!lcd_list)
goto bad;
lcd_list[0] = (XLCd) NULL;
}
/*
* search for needed lcd, if found return it
*/
for (i = 0; lcd_list[i]; i++) {
lcd = lcd_list[i];
if (!strcmp (lcd->core.name, name))
goto found;
}
if (!loaders && !_XlcAddLoader(_XlcDefaultLoader))
goto bad;
/*
* not there, so try to get and add to list
*/
for (j = 0; loaders[j]; j++) {
lcd = (*loaders[j]) (name);
if (lcd) {
XLCd *new_list;
new_list = (XLCd *) Xrealloc ((char *)lcd_list,
(sizeof (XLCd) * (i+2)));
if (!new_list)
goto bad;
lcd_list = new_list;
lcd_list[i] = lcd;
lcd_list[i+1] = (XLCd) NULL;
goto found;
}
}
bad:
lcd = (XLCd) NULL;
found:
UnlockMutex(&lock);
return lcd;
}