mirror of
https://gitlab.freedesktop.org/xorg/lib/libx11.git
synced 2026-05-05 21:38:02 +02:00
Merge branch 'master' of git+ssh://git.freedesktop.org/srv/git.freedesktop.org/git/xorg/lib/libX11
This commit is contained in:
commit
efedfd68e3
24 changed files with 800 additions and 171 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -16,3 +16,4 @@ MakeOut
|
|||
missing
|
||||
mkinstalldirs
|
||||
x11.pc
|
||||
*~
|
||||
|
|
|
|||
12
configure.ac
12
configure.ac
|
|
@ -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 ""
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ _XimSetHeader(
|
|||
return;
|
||||
}
|
||||
|
||||
Private char
|
||||
Public char
|
||||
_XimGetMyEndian(void)
|
||||
{
|
||||
CARD16 test_card = 1;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -256,6 +256,8 @@ XFontSetExtents *
|
|||
XExtentsOfFontSet(font_set)
|
||||
XFontSet font_set;
|
||||
{
|
||||
if (!font_set)
|
||||
return NULL;
|
||||
return &font_set->core.font_set_extents;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.....
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -672,6 +672,10 @@ extern int _XimLcctstoutf8(
|
|||
Status *state
|
||||
);
|
||||
|
||||
extern char _XimGetMyEndian(
|
||||
void
|
||||
);
|
||||
|
||||
extern int _XimCheckDataSize(
|
||||
XPointer buf,
|
||||
int len
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue