Merge branch 'master' of git+ssh://git.freedesktop.org/srv/git.freedesktop.org/git/xorg/lib/libX11

This commit is contained in:
Daniel Stone 2006-06-22 16:53:45 +03:00 committed by Daniel Stone
commit efedfd68e3
24 changed files with 800 additions and 171 deletions

1
.gitignore vendored
View file

@ -16,3 +16,4 @@ MakeOut
missing
mkinstalldirs
x11.pc
*~

View file

@ -303,6 +303,17 @@ else
fi
AC_SUBST(XKBPROTO_REQUIRES)
AC_FUNC_MMAP()
composecache_default=$ac_cv_func_mmap_fixed_mapped
AC_CHECK_FUNC(nl_langinfo, , [composecache_default=no])
AC_ARG_ENABLE(composecache,
AC_HELP_STRING([--disable-composecache],
[Disable compose table cache support]),
[COMPOSECACHE=$enableval],[COMPOSECACHE=$composecache_default])
if test x"$COMPOSECACHE" = "xyes"; then
AC_DEFINE(COMPOSECACHE,1,[Include compose table cache support])
fi
if test "x$GCC" = "xyes"; then
GCC_WARNINGS="-Wall -Wpointer-arith -Wstrict-prototypes \
-Wmissing-prototypes -Wmissing-declarations \
@ -436,4 +447,5 @@ echo " XF86BigFont support: "$XF86BIGFONT
echo " XKB support: "$XKB
echo " XLOCALEDIR environment variable support: "$ENABLE_XLOCALEDIR
echo " Manual pages installed: "$LIBMAN_SUFFIX
echo " Compose table cache enabled: "$COMPOSECACHE
echo ""

View file

@ -1264,6 +1264,12 @@ extern int _XOpenFile(
int /* flags */
);
extern int _XOpenFileMode(
_Xconst char* /* path */,
int /* flags */,
mode_t /* mode */
);
extern void* _XFopenFile(
_Xconst char* /* path */,
_Xconst char* /* mode */
@ -1274,6 +1280,7 @@ extern int _XAccessFile(
);
#else
#define _XOpenFile(path,flags) open(path,flags)
#define _XOpenFileMode(path,flags,mode) open(path,flags,mode)
#define _XFopenFile(path,mode) fopen(path,mode)
#endif

View file

@ -76,7 +76,7 @@ _XimSetHeader(
return;
}
Private char
Public char
_XimGetMyEndian(void)
{
CARD16 test_card = 1;

View file

@ -49,7 +49,8 @@ _XimLocalFilter(d, w, ev, client_data)
Xic ic = (Xic)client_data;
KeySym keysym;
static char buf[256];
DefTree *p;
DefTree *b = ic->private.local.base.tree;
DTIndex t;
if(ev->xkey.keycode == 0)
return (False);
@ -74,7 +75,7 @@ _XimLocalFilter(d, w, ev, client_data)
if(ic->private.local.brl_committing) {
ic->private.local.brl_committed =
ic->private.local.brl_committing;
ic->private.local.composed = NULL;
ic->private.local.composed = 0;
ev->type = KeyPress;
ev->xkey.keycode = 0;
_XPutBackEvent(d, ev);
@ -85,22 +86,21 @@ _XimLocalFilter(d, w, ev, client_data)
}
if( (ev->type != KeyPress)
|| (((Xim)ic->core.im)->private.local.top == (DefTree *)NULL) )
|| (((Xim)ic->core.im)->private.local.top == 0 ) )
return(False);
for(p = ic->private.local.context; p; p = p->next) {
if(((ev->xkey.state & p->modifier_mask) == p->modifier) &&
(keysym == p->keysym)) {
for(t = ic->private.local.context; t; t = b[t].next) {
if(((ev->xkey.state & b[t].modifier_mask) == b[t].modifier) &&
(keysym == b[t].keysym))
break;
}
}
if(p) { /* Matched */
if(p->succession) { /* Intermediate */
ic->private.local.context = p->succession;
if(t) { /* Matched */
if(b[t].succession) { /* Intermediate */
ic->private.local.context = b[t].succession;
return(True);
} else { /* Terminate (reached to leaf) */
ic->private.local.composed = p;
ic->private.local.composed = t;
ic->private.local.brl_committed = 0;
/* return back to client KeyPressEvent keycode == 0 */
ev->xkey.keycode = 0;

View file

@ -97,7 +97,7 @@ _XimLocalReset(
XIC xic)
{
Xic ic = (Xic)xic;
ic->private.local.composed = (DefTree *)NULL;
ic->private.local.composed = 0;
ic->private.local.context = ((Xim)ic->core.im)->private.local.top;
ic->private.local.brl_pressed = 0;
ic->private.local.brl_committing = 0;
@ -152,8 +152,9 @@ _XimLocalCreateIC(
ic->methods = &Local_ic_methods;
ic->core.im = im;
ic->private.local.base = ((Xim)im)->private.local.base;
ic->private.local.context = ((Xim)im)->private.local.top;
ic->private.local.composed = (DefTree *)NULL;
ic->private.local.composed = 0;
ic->private.local.brl_pressed = 0;
ic->private.local.brl_committing = 0;
ic->private.local.brl_committed = 0;

View file

@ -50,6 +50,51 @@ THIS SOFTWARE.
#include "XlcPubI.h"
#include "Ximint.h"
#include <ctype.h>
#include <assert.h>
#ifdef COMPOSECACHE
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/mman.h>
# include <langinfo.h>
#endif
#ifdef COMPOSECACHE
/* include trailing '/' for cache directory, file prefix otherwise */
#define XIM_GLOBAL_CACHE_DIR "/var/X11R6/compose-cache/"
#define XIM_HOME_CACHE_DIR "/.compose-cache/"
#define XIM_CACHE_MAGIC ('X' | 'i'<<8 | 'm'<<16 | 'C'<<24)
#define XIM_CACHE_VERSION 3
#define XIM_HASH_PRIME_1 13
#define XIM_HASH_PRIME_2 1234096939
typedef INT32 DTStructIndex;
struct _XimCacheStruct {
INT32 id;
INT32 version;
DTStructIndex tree;
DTStructIndex mb;
DTStructIndex wc;
DTStructIndex utf8;
DTStructIndex size;
DTIndex top;
DTIndex treeused;
DTCharIndex mbused;
DTCharIndex wcused;
DTCharIndex utf8used;
char fname[1];
/* char encoding[1] */
};
Private struct _XimCacheStruct* _XimCache_mmap = NULL;
Private DefTreeBase _XimCachedDefaultTreeBase;
Private int _XimCachedDefaultTreeRefcount = 0;
#endif
Public Bool
_XimCheckIfLocalProcessing(im)
@ -78,23 +123,37 @@ _XimCheckIfLocalProcessing(im)
Private void
XimFreeDefaultTree(
DefTree *top)
DefTreeBase *b)
{
if (!top) return;
if (top->succession) XimFreeDefaultTree(top->succession);
if (top->next) XimFreeDefaultTree(top->next);
if (top->mb) Xfree(top->mb);
if (top->wc) Xfree(top->wc);
if (top->utf8) Xfree(top->utf8);
Xfree(top);
if (!b) return;
if (b->tree == NULL) return;
#ifdef COMPOSECACHE
if (b->tree == _XimCachedDefaultTreeBase.tree) {
_XimCachedDefaultTreeRefcount--;
/* No deleting, it's a cache after all. */
return;
}
#endif
Xfree (b->tree);
if (b->mb) Xfree (b->mb);
if (b->wc) Xfree (b->wc);
if (b->utf8) Xfree (b->utf8);
b->tree = NULL;
b->mb = NULL;
b->wc = NULL;
b->utf8 = NULL;
b->treeused = b->treesize = 0;
b->mbused = b->mbsize = 0;
b->wcused = b->wcsize = 0;
b->utf8used = b->utf8size = 0;
}
Public void
_XimLocalIMFree(
Xim im)
{
XimFreeDefaultTree(im->private.local.top);
im->private.local.top = NULL;
XimFreeDefaultTree(&im->private.local.base);
im->private.local.top = 0;
if(im->core.im_resources) {
Xfree(im->core.im_resources);
@ -213,28 +272,272 @@ _XimLocalSetIMValues(
return(name);
}
#ifdef COMPOSECACHE
Private Bool
_XimReadCachedDefaultTree(
int fd_cache,
const char *name,
const char *encoding,
DTStructIndex size)
{
struct _XimCacheStruct* m;
int namelen = strlen (name) + 1;
int encodinglen = strlen (encoding) + 1;
m = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd_cache, 0);
if (m == NULL || m == MAP_FAILED)
return False;
assert (m->id == XIM_CACHE_MAGIC);
assert (m->version == XIM_CACHE_VERSION);
if (size != m->size ||
size < XOffsetOf (struct _XimCacheStruct, fname) + namelen + encodinglen) {
fprintf (stderr, "Ignoring broken XimCache %s [%s]\n", name, encoding);
munmap (m, size);
return False;
}
if (strncmp (name, m->fname, namelen) != 0) {
/* m->fname may *not* be terminated - but who cares here */
fprintf (stderr, "Filename hash clash - expected %s, got %s\n",
name, m->fname);
munmap (m, size);
return False;
}
if (strncmp (encoding, m->fname + namelen, encodinglen) != 0) {
/* m->fname+namelen may *not* be terminated - but who cares here */
fprintf (stderr, "Enoding hash clash - expected %s, got %s\n",
encoding, m->fname + namelen);
munmap (m, size);
return False;
}
_XimCache_mmap = m;
_XimCachedDefaultTreeBase.tree = (DefTree *) (((char *) m) + m->tree);
_XimCachedDefaultTreeBase.mb = (((char *) m) + m->mb);
_XimCachedDefaultTreeBase.wc = (wchar_t *) (((char *) m) + m->wc);
_XimCachedDefaultTreeBase.utf8 = (((char *) m) + m->utf8);
_XimCachedDefaultTreeBase.treeused = m->treeused;
_XimCachedDefaultTreeBase.mbused = m->mbused;
_XimCachedDefaultTreeBase.wcused = m->wcused;
_XimCachedDefaultTreeBase.utf8used = m->utf8used;
/* treesize etc. is ignored because only used during parsing */
_XimCachedDefaultTreeRefcount = 0;
/* fprintf (stderr, "read cached tree at %p: %s\n", (void *) m, name); */
return True;
}
Private unsigned int strToHash (
const char *name)
{
unsigned int hash = 0;
while (*name)
hash = hash * XIM_HASH_PRIME_1 + *(unsigned const char *)name++;
return hash % XIM_HASH_PRIME_2;
}
/* Returns read-only fd of cache file, -1 if none.
* Sets *res to cache filename if safe. Sets *size to file size of cache. */
Private int _XimCachedFileName (
const char *dir, const char *name,
const char *intname, const char *encoding,
uid_t uid, int isglobal, char **res, off_t *size)
{
struct stat st_name, st;
int fd;
unsigned int len, hash, hash2;
struct _XimCacheStruct *m;
/* There are some races here with 'dir', but we are either in our own home
* or the global cache dir, and not inside some public writable dir */
/* fprintf (stderr, "XimCachedFileName for dir %s name %s intname %s encoding %s uid %d\n", dir, name, intname, encoding, uid); */
if (stat (name, &st_name) == -1 || ! S_ISREG (st_name.st_mode)
|| stat (dir, &st) == -1 || ! S_ISDIR (st.st_mode) || st.st_uid != uid
|| (st.st_mode & 0022) != 0000) {
*res = NULL;
return -1;
}
len = strlen (dir);
hash = strToHash (intname);
hash2 = strToHash (encoding);
*res = Xmalloc (len + 1 + 27 + 1); /* Max VERSION 9999 */
if (len == 0 || dir [len-1] != '/')
sprintf (*res, "%s/%c%d_%03x_%08x_%08x", dir, _XimGetMyEndian(),
XIM_CACHE_VERSION, sizeof (DefTree), hash, hash2);
else
sprintf (*res, "%s%c%d_%03x_%08x_%08x", dir, _XimGetMyEndian(),
XIM_CACHE_VERSION, sizeof (DefTree), hash, hash2);
/* fprintf (stderr, "-> %s\n", *res); */
if ( (fd = _XOpenFile (*res, O_RDONLY)) == -1)
return -1;
if (fstat (fd, &st) == -1) {
Xfree (*res);
*res = NULL;
close (fd);
return -1;
}
*size = st.st_size;
if (! S_ISREG (st.st_mode) || st.st_uid != uid
|| (st.st_mode & 0022) != 0000 || st.st_mtime <= st_name.st_mtime
|| (st.st_mtime < time (NULL) - 24*60*60 && ! isglobal)) {
close (fd);
if (unlink (*res) != 0) {
Xfree (*res);
*res = NULL; /* cache is not safe */
}
return -1;
}
m = mmap (NULL, sizeof (struct _XimCacheStruct), PROT_READ, MAP_PRIVATE,
fd, 0);
if (m == NULL || m == MAP_FAILED) {
close (fd);
Xfree (*res);
*res = NULL;
return -1;
}
if (*size < sizeof (struct _XimCacheStruct) || m->id != XIM_CACHE_MAGIC) {
munmap (m, sizeof (struct _XimCacheStruct));
close (fd);
fprintf (stderr, "Ignoring broken XimCache %s\n", *res);
Xfree (*res);
*res = NULL;
return -1;
}
if (m->version != XIM_CACHE_VERSION) {
munmap (m, sizeof (struct _XimCacheStruct));
close (fd);
if (unlink (*res) != 0) {
Xfree (*res);
*res = NULL; /* cache is not safe */
}
return -1;
}
munmap (m, sizeof (struct _XimCacheStruct));
return fd;
}
Private Bool _XimLoadCache (
int fd,
const char *name,
const char *encoding,
off_t size,
Xim im)
{
if (_XimCache_mmap ||
_XimReadCachedDefaultTree (fd, name, encoding, size)) {
_XimCachedDefaultTreeRefcount++;
memcpy (&im->private.local.base, &_XimCachedDefaultTreeBase,
sizeof (_XimCachedDefaultTreeBase));
im->private.local.top = _XimCache_mmap->top;
return True;
}
return False;
}
Private void
_XimWriteCachedDefaultTree(
const char *name,
const char *encoding,
const char *cachename,
Xim im)
{
int fd;
FILE *fp;
struct _XimCacheStruct *m;
int msize = XOffsetOf(struct _XimCacheStruct, fname) + strlen(name) + strlen(encoding) + 2;
DefTreeBase *b = &im->private.local.base;
if (! b->tree && ! (b->tree = Xmalloc (sizeof(DefTree))) )
return;
if (! b->mb && ! (b->mb = Xmalloc (1)) )
return;
if (! b->wc && ! (b->wc = Xmalloc (sizeof(wchar_t))) )
return;
if (! b->utf8 && ! (b->utf8 = Xmalloc (1)) )
return;
m = Xmalloc (msize);
m->id = XIM_CACHE_MAGIC;
m->version = XIM_CACHE_VERSION;
m->tree = msize;
m->top = im->private.local.top;
m->treeused = b->treeused;
m->mbused = b->mbused;
m->wcused = b->wcused;
m->utf8used = b->utf8used;
m->mb = msize + sizeof (DefTree) * m->treeused;
m->wc = m->mb + m->mbused;
m->utf8 = m->wc + sizeof (wchar_t) * m->wcused;
m->size = m->utf8 + m->utf8used;
strcpy (m->fname, name);
strcpy (m->fname+strlen(name)+1, encoding);
/* This STILL might be racy on NFS */
if ( (fd = _XOpenFileMode (cachename, O_WRONLY | O_CREAT | O_EXCL,
0600)) < 0)
return;
if (! (fp = fdopen (fd, "wb")) ) {
close (fd);
return;
}
fwrite (m, msize, 1, fp);
fwrite (im->private.local.base.tree, sizeof(DefTree), m->treeused, fp);
fwrite (im->private.local.base.mb, 1, m->mbused, fp);
fwrite (im->private.local.base.wc, sizeof(wchar_t), m->wcused, fp);
fwrite (im->private.local.base.utf8, 1, m->utf8used, fp);
if (fclose (fp) != 0)
unlink (cachename);
_XimCache_mmap = m;
memcpy (&_XimCachedDefaultTreeBase, &im->private.local.base,
sizeof (_XimCachedDefaultTreeBase));
/* fprintf (stderr, "wrote tree %s size %ld to %s\n", name, m->size, cachename); */
}
#endif
Private void
_XimCreateDefaultTree(
Xim im)
{
FILE *fp = NULL;
char *name, *tmpname = NULL;
char *name, *tmpname = NULL, *intname;
char *cachename = NULL;
/* Should use getpwent() instead of $HOME (cross-platform?) */
char *home = getenv("HOME");
char *cachedir = NULL;
char *tmpcachedir = NULL;
int hl = home ? strlen (home) : 0;
#ifdef COMPOSECACHE
const char *encoding = nl_langinfo (CODESET);
uid_t euid = geteuid ();
gid_t egid = getegid ();
int cachefd = -1;
off_t size;
#endif
name = getenv("XCOMPOSEFILE");
if (name == (char *) NULL) {
char *home = getenv("HOME");
if (home != (char *) NULL) {
int hl = strlen(home);
tmpname = name = Xmalloc(hl + 10 + 1);
if (name != (char *) NULL) {
int fd;
strcpy(name, home);
strcpy(name + hl, "/.XCompose");
fp = _XFopenFile (name, "r");
if (fp == (FILE *) NULL) {
Xfree(name);
name = tmpname = NULL;
}
if ( (fd = _XOpenFile (name, O_RDONLY)) < 0) {
Xfree (name);
name = tmpname = NULL;
} else
close (fd);
}
}
}
@ -242,19 +545,95 @@ _XimCreateDefaultTree(
if (name == (char *) NULL) {
tmpname = name = _XlcFileName(im->core.lcd, COMPOSE_FILE);
}
intname = name;
#ifdef COMPOSECACHE
if (getuid () == euid && getgid () == egid && euid != 0) {
char *c;
/* Usage: XCOMPOSECACHE=<cachedir>[=<filename>]
* cachedir: directory of cache files
* filename: internally used name for cache file */
cachedir = getenv("XCOMPOSECACHE");
if (cachedir && (c = strchr (cachedir, '='))) {
tmpcachedir = strdup (cachedir);
intname = tmpcachedir + (c-cachedir) + 1;
tmpcachedir[c-cachedir] = '\0';
cachedir = tmpcachedir;
}
}
if (name == (char *) NULL)
if (! cachedir) {
cachefd = _XimCachedFileName (XIM_GLOBAL_CACHE_DIR, name, intname,
encoding, 0, 1, &cachename, &size);
if (cachefd != -1) {
if (_XimLoadCache (cachefd, intname, encoding, size, im)) {
if (tmpcachedir)
Xfree (tmpcachedir);
if (tmpname)
Xfree (tmpname);
if (cachename)
Xfree (cachename);
close (cachefd);
return;
}
close (cachefd);
}
if (cachename)
Xfree (cachename);
cachename = NULL;
}
if (getuid () == euid && getgid () == egid && euid != 0 && home) {
if (! cachedir) {
tmpcachedir = cachedir = Xmalloc (hl+strlen(XIM_HOME_CACHE_DIR)+1);
strcpy (cachedir, home);
strcat (cachedir, XIM_HOME_CACHE_DIR);
}
cachefd = _XimCachedFileName (cachedir, name, intname, encoding,
euid, 0, &cachename, &size);
if (cachefd != -1) {
if (_XimLoadCache (cachefd, intname, encoding, size, im)) {
if (tmpcachedir)
Xfree (tmpcachedir);
if (tmpname)
Xfree (tmpname);
if (cachename)
Xfree (cachename);
close (cachefd);
return;
}
close (cachefd);
}
}
#endif
fp = _XFopenFile (name, "r");
if (! (fp = _XFopenFile (name, "r"))) {
if (tmpcachedir)
Xfree (tmpcachedir);
if (tmpname)
Xfree (tmpname);
if (cachename)
Xfree (cachename);
return;
if (fp == (FILE *) NULL) {
fp = _XFopenFile (name, "r");
}
if (tmpname != (char *) NULL) {
Xfree(tmpname);
}
if (fp == (FILE *) NULL)
return;
_XimParseStringFile(fp, im);
fclose(fp);
#ifdef COMPOSECACHE
if (cachename) {
assert (euid != 0);
_XimWriteCachedDefaultTree (intname, encoding, cachename, im);
}
#endif
if (tmpcachedir)
Xfree (tmpcachedir);
if (tmpname)
Xfree (tmpname);
if (cachename)
Xfree (cachename);
}
Private XIMMethodsRec Xim_im_local_methods = {
@ -327,6 +706,11 @@ _XimLocalOpenIM(
goto Open_Error;
private->ucstoutf8_conv = conv;
private->base.treeused = 1;
private->base.mbused = 1;
private->base.wcused = 1;
private->base.utf8used = 1;
_XimCreateDefaultTree(im);
im->methods = &Xim_im_local_methods;

View file

@ -56,13 +56,15 @@ _XimLocalMbLookupString(xic, ev, buffer, bytes, keysym, status)
{
Xic ic = (Xic)xic;
int ret;
DefTree *b = ic->private.local.base.tree;
char *mb = ic->private.local.base.mb;
if(ev->type != KeyPress) {
if(status) *status = XLookupNone;
return(0);
}
if(ev->keycode == 0 &&
( (ic->private.local.composed != NULL)
( (ic->private.local.composed != 0)
||(ic->private.local.brl_committed != 0))) {
if (ic->private.local.brl_committed != 0) { /* Braille Event */
unsigned char pattern = ic->private.local.brl_committed;
@ -79,13 +81,13 @@ _XimLocalMbLookupString(xic, ev, buffer, bytes, keysym, status)
if(status) *status = XLookupChars;
memcpy(buffer, mb, ret);
} else { /* Composed Event */
ret = strlen(ic->private.local.composed->mb);
ret = strlen(&mb[b[ic->private.local.composed].mb]);
if(ret > bytes) {
if(status) *status = XBufferOverflow;
return(ret);
}
memcpy(buffer, ic->private.local.composed->mb, ret);
if(keysym) *keysym = ic->private.local.composed->ks;
memcpy(buffer, &mb[b[ic->private.local.composed].mb], ret);
if(keysym) *keysym = b[ic->private.local.composed].ks;
if (ret > 0) {
if (keysym && *keysym != NoSymbol) {
if(status) *status = XLookupBoth;
@ -133,6 +135,8 @@ _XimLocalWcLookupString(xic, ev, buffer, wlen, keysym, status)
{
Xic ic = (Xic)xic;
int ret;
DefTree *b = ic->private.local.base.tree;
wchar_t *wc = ic->private.local.base.wc;
if(ev->type != KeyPress) {
if(status) *status = XLookupNone;
@ -153,14 +157,14 @@ _XimLocalWcLookupString(xic, ev, buffer, wlen, keysym, status)
} else
if(status) *status = XLookupChars;
} else { /* Composed Event */
ret = _Xwcslen(ic->private.local.composed->wc);
ret = _Xwcslen(&wc[b[ic->private.local.composed].wc]);
if(ret > wlen) {
if(status) *status = XBufferOverflow;
return (ret);
}
memcpy((char *)buffer, (char *)ic->private.local.composed->wc,
memcpy((char *)buffer, (char *)&wc[b[ic->private.local.composed].wc],
ret * sizeof(wchar_t));
if(keysym) *keysym = ic->private.local.composed->ks;
if(keysym) *keysym = b[ic->private.local.composed].ks;
if (ret > 0) {
if (keysym && *keysym != NoSymbol) {
if(status) *status = XLookupBoth;
@ -208,6 +212,8 @@ _XimLocalUtf8LookupString(xic, ev, buffer, bytes, keysym, status)
{
Xic ic = (Xic)xic;
int ret;
DefTree *b = ic->private.local.base.tree;
char *utf8 = ic->private.local.base.utf8;
if(ev->type != KeyPress) {
if(status) *status = XLookupNone;
@ -225,13 +231,13 @@ _XimLocalUtf8LookupString(xic, ev, buffer, bytes, keysym, status)
buffer[1] = 0x80 | ((BRL_UC_ROW >> 8) & 0x30) | (pattern >> 6);
buffer[2] = 0x80 | (pattern & 0x3f);
} else { /* Composed Event */
ret = strlen(ic->private.local.composed->utf8);
ret = strlen(&utf8[b[ic->private.local.composed].utf8]);
if(ret > bytes) {
if(status) *status = XBufferOverflow;
return (ret);
}
memcpy(buffer, ic->private.local.composed->utf8, ret);
if(keysym) *keysym = ic->private.local.composed->ks;
memcpy(buffer, &utf8[b[ic->private.local.composed].utf8], ret);
if(keysym) *keysym = b[ic->private.local.composed].ks;
if (ret > 0) {
if (keysym && *keysym != NoSymbol) {
if(status) *status = XLookupBoth;

View file

@ -422,11 +422,13 @@ parseline(
char* tokenbuf)
{
int token;
unsigned modifier_mask;
unsigned modifier;
unsigned tmp;
DTModifier modifier_mask;
DTModifier modifier;
DTModifier tmp;
KeySym keysym = NoSymbol;
DefTree **top = &im->private.local.top;
DTIndex *top = &im->private.local.top;
DefTreeBase *b = &im->private.local.base;
DTIndex t;
DefTree *p = NULL;
Bool exclam, tilde;
KeySym rhs_keysym = 0;
@ -438,8 +440,8 @@ parseline(
char local_utf8_buf[LOCAL_UTF8_BUFSIZE], *rhs_string_utf8;
struct DefBuffer {
unsigned modifier_mask;
unsigned modifier;
DTModifier modifier_mask;
DTModifier modifier;
KeySym keysym;
};
@ -536,20 +538,24 @@ parseline(
token = nexttoken(fp, tokenbuf, &lastch);
if (token == STRING) {
if( (rhs_string_mb = Xmalloc(strlen(tokenbuf) + 1)) == NULL )
goto error;
l = strlen(tokenbuf) + 1;
while (b->mbused + l > b->mbsize) {
b->mbsize = b->mbsize ? b->mbsize * 1.5 : 1024;
if (! (b->mb = Xrealloc (b->mb, b->mbsize)) )
goto error;
}
rhs_string_mb = &b->mb[b->mbused];
b->mbused += l;
strcpy(rhs_string_mb, tokenbuf);
token = nexttoken(fp, tokenbuf, &lastch);
if (token == KEY) {
rhs_keysym = XStringToKeysym(tokenbuf);
if (rhs_keysym == NoSymbol) {
Xfree(rhs_string_mb);
goto error;
}
token = nexttoken(fp, tokenbuf, &lastch);
}
if (token != ENDOFLINE && token != ENDOFFILE) {
Xfree(rhs_string_mb);
goto error;
}
} else if (token == KEY) {
@ -563,14 +569,13 @@ parseline(
}
l = get_mb_string(im, local_mb_buf, rhs_keysym);
if (l == 0) {
rhs_string_mb = Xmalloc(1);
} else {
rhs_string_mb = Xmalloc(l + 1);
}
if( rhs_string_mb == NULL ) {
goto error;
while (b->mbused + l + 1 > b->mbsize) {
b->mbsize = b->mbsize ? b->mbsize * 1.5 : 1024;
if (! (b->mb = Xrealloc (b->mb, b->mbsize)) )
goto error;
}
rhs_string_mb = &b->mb[b->mbused];
b->mbused += l + 1;
memcpy(rhs_string_mb, local_mb_buf, l);
rhs_string_mb[l] = '\0';
} else {
@ -581,62 +586,70 @@ parseline(
if (l == LOCAL_WC_BUFSIZE - 1) {
local_wc_buf[l] = (wchar_t)'\0';
}
if( (rhs_string_wc = (wchar_t *)Xmalloc((l + 1) * sizeof(wchar_t))) == NULL ) {
Xfree( rhs_string_mb );
return( 0 );
while (b->wcused + l + 1 > b->wcsize) {
b->wcsize = b->wcsize ? b->wcsize * 1.5 : 512;
if (! (b->wc = Xrealloc (b->wc, sizeof(wchar_t) * b->wcsize)) )
goto error;
}
rhs_string_wc = &b->wc[b->wcused];
b->wcused += l + 1;
memcpy((char *)rhs_string_wc, (char *)local_wc_buf, (l + 1) * sizeof(wchar_t) );
l = _Xmbstoutf8(local_utf8_buf, rhs_string_mb, LOCAL_UTF8_BUFSIZE - 1);
if (l == LOCAL_UTF8_BUFSIZE - 1) {
local_wc_buf[l] = '\0';
}
if( (rhs_string_utf8 = (char *)Xmalloc(l + 1)) == NULL ) {
Xfree( rhs_string_wc );
Xfree( rhs_string_mb );
return( 0 );
while (b->utf8used + l + 1 > b->utf8size) {
b->utf8size = b->utf8size ? b->utf8size * 1.5 : 1024;
if (! (b->utf8 = Xrealloc (b->utf8, b->utf8size)) )
goto error;
}
rhs_string_utf8 = &b->utf8[b->utf8used];
b->utf8used += l + 1;
memcpy(rhs_string_utf8, local_utf8_buf, l + 1);
for (i = 0; i < n; i++) {
for (p = *top; p; p = p->next) {
if (buf[i].keysym == p->keysym &&
buf[i].modifier == p->modifier &&
buf[i].modifier_mask == p->modifier_mask) {
for (t = *top; t; t = b->tree[t].next) {
if (buf[i].keysym == b->tree[t].keysym &&
buf[i].modifier == b->tree[t].modifier &&
buf[i].modifier_mask == b->tree[t].modifier_mask) {
break;
}
}
if (p) {
if (t) {
p = &b->tree[t];
top = &p->succession;
} else {
if( (p = (DefTree*)Xmalloc(sizeof(DefTree))) == NULL ) {
Xfree( rhs_string_mb );
goto error;
while (b->treeused >= b->treesize) {
DefTree *old = b->tree;
int oldsize = b->treesize;
b->treesize = b->treesize ? b->treesize * 1.5 : 256;
if (! (b->tree = Xrealloc (b->tree, sizeof(DefTree) * b->treesize)) )
goto error;
if (top >= (DTIndex *) old && top < (DTIndex *) &old[oldsize])
top = (DTIndex *) (((char *) top) + (((char *)b->tree)-(char *)old));
}
p = &b->tree[b->treeused];
p->keysym = buf[i].keysym;
p->modifier = buf[i].modifier;
p->modifier_mask = buf[i].modifier_mask;
p->succession = NULL;
p->succession = 0;
p->next = *top;
p->mb = NULL;
p->wc = NULL;
p->utf8 = NULL;
p->mb = 0;
p->wc = 0;
p->utf8 = 0;
p->ks = NoSymbol;
*top = p;
*top = b->treeused;
top = &p->succession;
b->treeused++;
}
}
if( p->mb != NULL )
Xfree( p->mb );
p->mb = rhs_string_mb;
if( p->wc != NULL )
Xfree( p->wc );
p->wc = rhs_string_wc;
if( p->utf8 != NULL )
Xfree( p->utf8 );
p->utf8 = rhs_string_utf8;
p->ks = rhs_keysym;
/* old entries no longer freed... */
p->mb = rhs_string_mb - b->mb;
p->wc = rhs_string_wc - b->wc;
p->utf8 = rhs_string_utf8 - b->utf8;
p->ks = rhs_keysym;
return(n);
error:
while (token != ENDOFLINE && token != ENDOFFILE) {

View file

@ -522,9 +522,9 @@ Private Bool ThaiComposeConvert(
* Macros to save and recall last input character in XIC
*/
#define IC_SavePreviousChar(ic,ch) \
(*((ic)->private.local.context->mb) = (char) (ch))
((ic)->private.local.base.mb[(ic)->private.local.base.tree[(ic)->private.local.context].mb] = (char) (ch))
#define IC_ClearPreviousChar(ic) \
(*((ic)->private.local.context->mb) = 0)
((ic)->private.local.base.mb[(ic)->private.local.base.tree[(ic)->private.local.context].mb] = 0)
#define IC_GetPreviousChar(ic) \
(IC_RealGetPreviousChar(ic,1))
#define IC_GetContextChar(ic) \
@ -536,6 +536,7 @@ Private unsigned char
IC_RealGetPreviousChar(Xic ic, unsigned short pos)
{
XICCallback* cb = &ic->core.string_conversion_callback;
DefTreeBase *b = &ic->private.local.base;
if (cb && cb->callback) {
XIMStringConversionCallbackStruct screc;
@ -552,7 +553,7 @@ IC_RealGetPreviousChar(Xic ic, unsigned short pos)
(cb->callback)((XIC)ic, cb->client_data, (XPointer)&screc);
if (!screc.text)
return (unsigned char) *((ic)->private.local.context->mb);
return (unsigned char) b->mb[b->tree[(ic)->private.local.context].mb];
if ((screc.text->feedback &&
*screc.text->feedback == XIMStringConversionLeftEdge) ||
screc.text->length < 1)
@ -570,7 +571,7 @@ IC_RealGetPreviousChar(Xic ic, unsigned short pos)
XFree(screc.text);
return c;
} else {
return (unsigned char) *((ic)->private.local.context->mb);
return (unsigned char) b->mb[b->tree[(ic)->private.local.context].mb];
}
}
@ -1193,13 +1194,14 @@ Private void InitIscMode(Xic ic)
Private Bool
ThaiFltAcceptInput(Xic ic, unsigned char new_char, KeySym symbol)
{
ic->private.local.composed->wc[0] = tis2ucs(new_char);
ic->private.local.composed->wc[1] = '\0';
DefTreeBase *b = &ic->private.local.base;
b->wc[b->tree[ic->private.local.composed].wc+0] = tis2ucs(new_char);
b->wc[b->tree[ic->private.local.composed].wc+1] = '\0';
if ((new_char <= 0x1f) || (new_char == 0x7f))
ic->private.local.composed->keysym = symbol;
b->tree[ic->private.local.composed].keysym = symbol;
else
ic->private.local.composed->keysym = NoSymbol;
b->tree[ic->private.local.composed].keysym = NoSymbol;
return True;
}
@ -1207,12 +1209,13 @@ ThaiFltAcceptInput(Xic ic, unsigned char new_char, KeySym symbol)
Private Bool
ThaiFltReorderInput(Xic ic, unsigned char previous_char, unsigned char new_char)
{
DefTreeBase *b = &ic->private.local.base;
if (!IC_DeletePreviousChar(ic)) return False;
ic->private.local.composed->wc[0] = tis2ucs(new_char);
ic->private.local.composed->wc[1] = tis2ucs(previous_char);
ic->private.local.composed->wc[2] = '\0';
b->wc[b->tree[ic->private.local.composed].wc+0] = tis2ucs(new_char);
b->wc[b->tree[ic->private.local.composed].wc+1] = tis2ucs(previous_char);
b->wc[b->tree[ic->private.local.composed].wc+2] = '\0';
ic->private.local.composed->keysym = NoSymbol;
b->tree[ic->private.local.composed].keysym = NoSymbol;
return True;
}
@ -1220,14 +1223,15 @@ ThaiFltReorderInput(Xic ic, unsigned char previous_char, unsigned char new_char)
Private Bool
ThaiFltReplaceInput(Xic ic, unsigned char new_char, KeySym symbol)
{
DefTreeBase *b = &ic->private.local.base;
if (!IC_DeletePreviousChar(ic)) return False;
ic->private.local.composed->wc[0] = tis2ucs(new_char);
ic->private.local.composed->wc[1] = '\0';
b->wc[b->tree[ic->private.local.composed].wc+0] = tis2ucs(new_char);
b->wc[b->tree[ic->private.local.composed].wc+1] = '\0';
if ((new_char <= 0x1f) || (new_char == 0x7f))
ic->private.local.composed->keysym = symbol;
b->tree[ic->private.local.composed].keysym = symbol;
else
ic->private.local.composed->keysym = NoSymbol;
b->tree[ic->private.local.composed].keysym = NoSymbol;
return True;
}
@ -1256,6 +1260,7 @@ XPointer client_data;
#endif
wchar_t wbuf[10];
Bool isReject;
DefTreeBase *b = &ic->private.local.base;
if ((ev->type != KeyPress)
|| (ev->xkey.keycode == 0))
@ -1358,11 +1363,11 @@ XPointer client_data;
return True;
}
_Xlcwcstombs(ic->core.im->core.lcd, ic->private.local.composed->mb,
ic->private.local.composed->wc, 10);
_Xlcwcstombs(ic->core.im->core.lcd, &b->mb[b->tree[ic->private.local.composed].mb],
&b->wc[b->tree[ic->private.local.composed].wc], 10);
_Xlcmbstoutf8(ic->core.im->core.lcd, ic->private.local.composed->utf8,
ic->private.local.composed->mb, 10);
_Xlcmbstoutf8(ic->core.im->core.lcd, &b->utf8[b->tree[ic->private.local.composed].utf8],
&b->mb[b->tree[ic->private.local.composed].mb], 10);
/* Remember the last character inputted
* (as fallback in case StringConversionCallback is not provided)

View file

@ -62,6 +62,8 @@ _XimThaiDestroyIC(
XIC xic)
{
Xic ic = (Xic)xic;
DefTreeBase *b = &ic->private.local.base;
if(((Xim)ic->core.im)->private.local.current_ic == (XIC)ic) {
_XimThaiUnSetFocus(xic);
}
@ -70,14 +72,14 @@ _XimThaiDestroyIC(
ic->private.local.ic_resources = NULL;
}
Xfree(ic->private.local.context->mb);
Xfree(ic->private.local.context->wc);
Xfree(ic->private.local.context->utf8);
Xfree(ic->private.local.context);
Xfree(ic->private.local.composed->mb);
Xfree(ic->private.local.composed->wc);
Xfree(ic->private.local.composed->utf8);
Xfree(ic->private.local.composed);
if (b->tree) Xfree (b->tree);
if (b->mb) Xfree (b->mb);
if (b->wc) Xfree (b->wc);
if (b->utf8) Xfree (b->utf8);
b->tree = NULL;
b->mb = NULL;
b->wc = NULL;
b->utf8 = NULL;
return;
}
@ -107,11 +109,12 @@ _XimThaiReset(
XIC xic)
{
Xic ic = (Xic)xic;
DefTreeBase *b = &ic->private.local.base;
ic->private.local.thai.comp_state = 0;
ic->private.local.thai.keysym = 0;
ic->private.local.composed->mb[0] = '\0';
ic->private.local.composed->wc[0] = 0;
ic->private.local.composed->utf8[0] = '\0';
b->mb[b->tree[ic->private.local.composed].mb] = '\0';
b->wc[b->tree[ic->private.local.composed].wc] = '\0';
b->utf8[b->tree[ic->private.local.composed].utf8] = '\0';
}
Private char *
@ -154,6 +157,7 @@ _XimThaiCreateIC(
XIMResourceList res;
unsigned int num;
int len;
DefTree *tree;
if((ic = (Xic)Xmalloc(sizeof(XicRec))) == (Xic)NULL) {
return ((XIC)NULL);
@ -163,30 +167,23 @@ _XimThaiCreateIC(
ic->methods = &Thai_ic_methods;
ic->core.im = im;
ic->core.filter_events = KeyPressMask;
if ((ic->private.local.context = (DefTree *)Xmalloc(sizeof(DefTree)))
== (DefTree *)NULL)
if (! (ic->private.local.base.tree = tree = (DefTree *)Xmalloc(sizeof(DefTree)*3)) )
goto Set_Error;
if ((ic->private.local.context->mb = (char *)Xmalloc(10))
== (char *)NULL)
if (! (ic->private.local.base.mb = (char *)Xmalloc(21)) )
goto Set_Error;
if ((ic->private.local.context->wc = (wchar_t *)Xmalloc(10*sizeof(wchar_t)))
== (wchar_t *)NULL)
if (! (ic->private.local.base.wc = (wchar_t*)Xmalloc(sizeof(wchar_t)*21)) )
goto Set_Error;
if ((ic->private.local.context->utf8 = (char *)Xmalloc(10))
== (char *)NULL)
goto Set_Error;
if ((ic->private.local.composed = (DefTree *)Xmalloc(sizeof(DefTree)))
== (DefTree *)NULL)
goto Set_Error;
if ((ic->private.local.composed->mb = (char *)Xmalloc(10))
== (char *)NULL)
goto Set_Error;
if ((ic->private.local.composed->wc = (wchar_t *)Xmalloc(10*sizeof(wchar_t)))
== (wchar_t *)NULL)
goto Set_Error;
if ((ic->private.local.composed->utf8 = (char *)Xmalloc(10))
== (char *)NULL)
if (! (ic->private.local.base.utf8 = (char *)Xmalloc(21)) )
goto Set_Error;
ic->private.local.context = 1;
tree[1].mb = 1;
tree[1].wc = 1;
tree[1].utf8 = 1;
ic->private.local.composed = 2;
tree[2].mb = 11;
tree[2].wc = 11;
tree[2].utf8 = 11;
ic->private.local.thai.comp_state = 0;
ic->private.local.thai.keysym = 0;

View file

@ -256,6 +256,8 @@ XFontSetExtents *
XExtentsOfFontSet(font_set)
XFontSet font_set;
{
if (!font_set)
return NULL;
return &font_set->core.font_set_extents;
}

View file

@ -477,11 +477,8 @@ XOpenDisplay (
(void) strncpy(dpy->vendor, u.vendor, vendorlen);
dpy->vendor[vendorlen] = '\0';
vendorlen = (vendorlen + 3) & ~3; /* round up */
u.vendor += vendorlen;
memmove (setup, u.vendor + vendorlen,
(int) setuplength - sz_xConnSetup - vendorlen);
u.vendor = setup;
/*
* Now iterate down setup information.....
*/

View file

@ -3388,6 +3388,26 @@ int _XOpenFile(path, flags)
return ret;
}
int _XOpenFileMode(path, flags, mode)
_Xconst char* path;
int flags;
mode_t mode;
{
char buf[MAX_PATH];
char* bufp = NULL;
int ret = -1;
UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
if (AccessFile (path, buf, MAX_PATH, &bufp))
ret = open (bufp, flags, mode);
(void) SetErrorMode (olderror);
if (bufp != buf) Xfree (bufp);
return ret;
}
void* _XFopenFile(path, mode)
_Xconst char* path;
_Xconst char* mode;

View file

@ -201,7 +201,24 @@ TekHVC_ParseString(
&pColor->spec.TekHVC.H,
&pColor->spec.TekHVC.V,
&pColor->spec.TekHVC.C) != 3) {
return(XcmsFailure);
char *s; /* Maybe failed due to locale */
int f;
if ((s = strdup(spec))) {
for (f = 0; s[f]; ++f)
if (s[f] == '.')
s[f] = ',';
else if (s[f] == ',')
s[f] = '.';
if (sscanf(s + n + 1, "%lf/%lf/%lf",
&pColor->spec.TekHVC.H,
&pColor->spec.TekHVC.V,
&pColor->spec.TekHVC.C) != 3) {
free(s);
return(XcmsFailure);
}
free(s);
} else
return(XcmsFailure);
}
pColor->format = XcmsTekHVCFormat;
pColor->pixel = 0;

View file

@ -1432,7 +1432,24 @@ XcmsLRGB_RGBi_ParseString(
&pColor->spec.RGBi.red,
&pColor->spec.RGBi.green,
&pColor->spec.RGBi.blue) != 3) {
return(XcmsFailure);
char *s; /* Maybe failed due to locale */
int f;
if (s = strdup(spec)) {
for (f = 0; s[f]; ++f)
if (s[f] == '.')
s[f] = ',';
else if (s[f] == ',')
s[f] = '.';
if (sscanf(s + n + 1, "%lf/%lf/%lf",
&pColor->spec.RGBi.red,
&pColor->spec.RGBi.green,
&pColor->spec.RGBi.blue) != 3) {
free(s);
return(XcmsFailure);
}
free(s);
} else
return(XcmsFailure);
}
/*

View file

@ -162,7 +162,24 @@ CIELab_ParseString(
&pColor->spec.CIELab.L_star,
&pColor->spec.CIELab.a_star,
&pColor->spec.CIELab.b_star) != 3) {
return(XcmsFailure);
char *s; /* Maybe failed due to locale */
int f;
if (s = strdup(spec)) {
for (f = 0; s[f]; ++f)
if (s[f] == '.')
s[f] = ',';
else if (s[f] == ',')
s[f] = '.';
if (sscanf(s + n + 1, "%lf/%lf/%lf",
&pColor->spec.CIELab.L_star,
&pColor->spec.CIELab.a_star,
&pColor->spec.CIELab.b_star) != 3) {
free(s);
return(XcmsFailure);
}
free(s);
} else
return(XcmsFailure);
}
pColor->format = XcmsCIELabFormat;
pColor->pixel = 0;

View file

@ -165,6 +165,23 @@ CIELuv_ParseString(
&pColor->spec.CIELuv.L_star,
&pColor->spec.CIELuv.u_star,
&pColor->spec.CIELuv.v_star) != 3) {
char *s; /* Maybe failed due to locale */
int f;
if (s = strdup(spec)) {
for (f = 0; s[f]; ++f)
if (s[f] == '.')
s[f] = ',';
else if (s[f] == ',')
s[f] = '.';
if (sscanf(s + n + 1, "%lf/%lf/%lf",
&pColor->spec.CIELuv.L_star,
&pColor->spec.CIELuv.u_star,
&pColor->spec.CIELuv.v_star) != 3) {
free(s);
return(XcmsFailure);
}
free(s);
} else
return(XcmsFailure);
}
pColor->format = XcmsCIELuvFormat;

View file

@ -144,7 +144,24 @@ CIEXYZ_ParseString(
&pColor->spec.CIEXYZ.X,
&pColor->spec.CIEXYZ.Y,
&pColor->spec.CIEXYZ.Z) != 3) {
return(XcmsFailure);
char *s; /* Maybe failed due to locale */
int f;
if (s = strdup(spec)) {
for (f = 0; s[f]; ++f)
if (s[f] == '.')
s[f] = ',';
else if (s[f] == ',')
s[f] = '.';
if (sscanf(s + n + 1, "%lf/%lf/%lf",
&pColor->spec.CIEXYZ.X,
&pColor->spec.CIEXYZ.Y,
&pColor->spec.CIEXYZ.Z) != 3) {
free(s);
return(XcmsFailure);
}
free(s);
} else
return(XcmsFailure);
}
pColor->format = XcmsCIEXYZFormat;
pColor->pixel = 0;

View file

@ -159,7 +159,24 @@ CIEuvY_ParseString(
&pColor->spec.CIEuvY.u_prime,
&pColor->spec.CIEuvY.v_prime,
&pColor->spec.CIEuvY.Y) != 3) {
return(XcmsFailure);
char *s; /* Maybe failed due to locale */
int f;
if (s = strdup(spec)) {
for (f = 0; s[f]; ++f)
if (s[f] == '.')
s[f] = ',';
else if (s[f] == ',')
s[f] = '.';
if (sscanf(s + n + 1, "%lf/%lf/%lf",
&pColor->spec.CIEuvY.u_prime,
&pColor->spec.CIEuvY.v_prime,
&pColor->spec.CIEuvY.Y) != 3) {
free(s);
return(XcmsFailure);
}
free(s);
} else
return(XcmsFailure);
}
pColor->format = XcmsCIEuvYFormat;
pColor->pixel = 0;

View file

@ -158,7 +158,24 @@ CIExyY_ParseString(
&pColor->spec.CIExyY.x,
&pColor->spec.CIExyY.y,
&pColor->spec.CIExyY.Y) != 3) {
return(XcmsFailure);
char *s; /* Maybe failed due to locale */
int f;
if (s = strdup(spec)) {
for (f = 0; s[f]; ++f)
if (s[f] == '.')
s[f] = ',';
else if (s[f] == ',')
s[f] = '.';
if (sscanf(s + n + 1, "%lf/%lf/%lf",
&pColor->spec.CIExyY.x,
&pColor->spec.CIExyY.y,
&pColor->spec.CIExyY.Y) != 3) {
free(s);
return(XcmsFailure);
}
free(s);
} else
return(XcmsFailure);
}
pColor->format = XcmsCIExyYFormat;
pColor->pixel = 0;

View file

@ -672,6 +672,10 @@ extern int _XimLcctstoutf8(
Status *state
);
extern char _XimGetMyEndian(
void
);
extern int _XimCheckDataSize(
XPointer buf,
int len

View file

@ -40,21 +40,36 @@ THIS SOFTWARE.
#define COMPOSE_FILE "Compose"
/*
* Data Structure for Local Processing
* Data Structures for Local Processing
*/
typedef INT32 DTIndex;
typedef INT32 DTCharIndex;
typedef BITS32 DTModifier;
typedef struct _DefTree {
struct _DefTree *next; /* another Key definition */
struct _DefTree *succession; /* successive Key Sequence */
DTIndex next;
DTIndex succession; /* successive Key Sequence */
/* Key definitions */
unsigned modifier_mask;
unsigned modifier;
DTModifier modifier_mask;
DTModifier modifier;
KeySym keysym; /* leaf only */
char *mb;
wchar_t *wc; /* make from mb */
char *utf8; /* make from mb */
DTCharIndex mb;
DTCharIndex wc; /* make from mb */
DTCharIndex utf8; /* make from mb */
KeySym ks;
} DefTree;
typedef struct _DefTreeBase {
DefTree *tree;
char *mb;
wchar_t *wc;
char *utf8;
DTIndex treeused, treesize;
DTCharIndex mbused, mbsize;
DTCharIndex wcused, wcsize;
DTCharIndex utf8used, utf8size;
} DefTreeBase;
typedef struct _XimLocalPrivateRec {
/* The first fields are identical with XimCommonPrivateRec. */
XlcConv ctom_conv;
@ -67,7 +82,8 @@ typedef struct _XimLocalPrivateRec {
XlcConv ucstoutf8_conv;
XIC current_ic;
DefTree *top;
DefTreeBase base;
DTIndex top;
} XimLocalPrivateRec;
typedef struct _XicThaiPart {
@ -78,8 +94,9 @@ typedef struct _XicThaiPart {
typedef struct _XicLocalPrivateRec {
long value_mask;
DefTree *context;
DefTree *composed;
DefTreeBase base;
DTIndex context;
DTIndex composed;
XicThaiPart thai;
XIMResourceList ic_resources;

View file

@ -269,7 +269,11 @@ xlocaledir(
if (seteuid(0) != 0) {
priv = 0;
} else {
seteuid(oldeuid);
if (seteuid(oldeuid) == -1) {
/* XXX ouch, coudn't get back to original uid
what can we do ??? */
_exit(127);
}
priv = 1;
}
#endif
@ -647,6 +651,15 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name)
char *target_name = (char*)0;
char *target_dir = (char*)0;
char *nlc_name = NULL;
static char* last_dir_name = 0;
static size_t last_dir_len = 0;
static char* last_lc_name = 0;
if (last_lc_name != 0 && strcmp (last_lc_name, lc_name) == 0
&& dir_len >= last_dir_len) {
strcpy (dir_name, last_dir_name);
return dir_name;
}
xlocaledir (dir, PATH_MAX);
n = _XlcParsePath(dir, args, 256);
@ -714,6 +727,17 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name)
}
if (target_name != lc_name)
Xfree(target_name);
if (last_dir_name != 0)
Xfree (last_dir_name);
if (last_lc_name != 0)
Xfree (last_lc_name);
last_dir_len = strlen (dir_name) + 1;
last_dir_name = Xmalloc (last_dir_len);
strcpy (last_dir_name, dir_name);
last_lc_name = Xmalloc (strlen (lc_name) + 1);
strcpy (last_lc_name, lc_name);
return dir_name;
}
@ -730,6 +754,15 @@ _XlcLocaleLibDirName(dir_name, dir_len, lc_name)
char *target_name = (char*)0;
char *target_dir = (char*)0;
char *nlc_name = NULL;
static char* last_dir_name = 0;
static size_t last_dir_len = 0;
static char* last_lc_name = 0;
if (last_lc_name != 0 && strcmp (last_lc_name, lc_name) == 0
&& dir_len >= last_dir_len) {
strcpy (dir_name, last_dir_name);
return dir_name;
}
xlocalelibdir (dir, PATH_MAX);
n = _XlcParsePath(dir, args, 256);
@ -797,5 +830,16 @@ _XlcLocaleLibDirName(dir_name, dir_len, lc_name)
}
if (target_name != lc_name)
Xfree(target_name);
if (last_dir_name != 0)
Xfree (last_dir_name);
if (last_lc_name != 0)
Xfree (last_lc_name);
last_dir_len = strlen (dir_name) + 1;
last_dir_name = Xmalloc (last_dir_len);
strcpy (last_dir_name, dir_name);
last_lc_name = Xmalloc (strlen (lc_name) + 1);
strcpy (last_lc_name, lc_name);
return dir_name;
}