Commit 9354351f authored by Matthias Hopf's avatar Matthias Hopf

Bug #3104: Compose table cache for faster X11 application starts. Part 1:...

Bug #3104: Compose table cache for faster X11 application starts. Part 1: Pointerless compose data structure, using indices instead of pointers, needed for mmap()ing data structure.
parent b18713ec
...@@ -1264,6 +1264,12 @@ extern int _XOpenFile( ...@@ -1264,6 +1264,12 @@ extern int _XOpenFile(
int /* flags */ int /* flags */
); );
extern int _XOpenFileMode(
_Xconst char* /* path */,
int /* flags */,
mode_t /* mode */
);
extern void* _XFopenFile( extern void* _XFopenFile(
_Xconst char* /* path */, _Xconst char* /* path */,
_Xconst char* /* mode */ _Xconst char* /* mode */
...@@ -1274,6 +1280,7 @@ extern int _XAccessFile( ...@@ -1274,6 +1280,7 @@ extern int _XAccessFile(
); );
#else #else
#define _XOpenFile(path,flags) open(path,flags) #define _XOpenFile(path,flags) open(path,flags)
#define _XOpenFileMode(path,flags,mode) open(path,flags,mode)
#define _XFopenFile(path,mode) fopen(path,mode) #define _XFopenFile(path,mode) fopen(path,mode)
#endif #endif
......
...@@ -49,7 +49,8 @@ _XimLocalFilter(d, w, ev, client_data) ...@@ -49,7 +49,8 @@ _XimLocalFilter(d, w, ev, client_data)
Xic ic = (Xic)client_data; Xic ic = (Xic)client_data;
KeySym keysym; KeySym keysym;
static char buf[256]; static char buf[256];
DefTree *p; DefTree *b = ic->private.local.base.tree;
DTIndex t;
if(ev->xkey.keycode == 0) if(ev->xkey.keycode == 0)
return (False); return (False);
...@@ -74,7 +75,7 @@ _XimLocalFilter(d, w, ev, client_data) ...@@ -74,7 +75,7 @@ _XimLocalFilter(d, w, ev, client_data)
if(ic->private.local.brl_committing) { if(ic->private.local.brl_committing) {
ic->private.local.brl_committed = ic->private.local.brl_committed =
ic->private.local.brl_committing; ic->private.local.brl_committing;
ic->private.local.composed = NULL; ic->private.local.composed = 0;
ev->type = KeyPress; ev->type = KeyPress;
ev->xkey.keycode = 0; ev->xkey.keycode = 0;
_XPutBackEvent(d, ev); _XPutBackEvent(d, ev);
...@@ -85,22 +86,21 @@ _XimLocalFilter(d, w, ev, client_data) ...@@ -85,22 +86,21 @@ _XimLocalFilter(d, w, ev, client_data)
} }
if( (ev->type != KeyPress) if( (ev->type != KeyPress)
|| (((Xim)ic->core.im)->private.local.top == (DefTree *)NULL) ) || (((Xim)ic->core.im)->private.local.top == 0 ) )
return(False); return(False);
for(p = ic->private.local.context; p; p = p->next) { for(t = ic->private.local.context; t; t = b[t].next) {
if(((ev->xkey.state & p->modifier_mask) == p->modifier) && if(((ev->xkey.state & b[t].modifier_mask) == b[t].modifier) &&
(keysym == p->keysym)) { (keysym == b[t].keysym))
break; break;
}
} }
if(p) { /* Matched */ if(t) { /* Matched */
if(p->succession) { /* Intermediate */ if(b[t].succession) { /* Intermediate */
ic->private.local.context = p->succession; ic->private.local.context = b[t].succession;
return(True); return(True);
} else { /* Terminate (reached to leaf) */ } else { /* Terminate (reached to leaf) */
ic->private.local.composed = p; ic->private.local.composed = t;
ic->private.local.brl_committed = 0; ic->private.local.brl_committed = 0;
/* return back to client KeyPressEvent keycode == 0 */ /* return back to client KeyPressEvent keycode == 0 */
ev->xkey.keycode = 0; ev->xkey.keycode = 0;
......
...@@ -97,7 +97,7 @@ _XimLocalReset( ...@@ -97,7 +97,7 @@ _XimLocalReset(
XIC xic) XIC xic)
{ {
Xic ic = (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.context = ((Xim)ic->core.im)->private.local.top;
ic->private.local.brl_pressed = 0; ic->private.local.brl_pressed = 0;
ic->private.local.brl_committing = 0; ic->private.local.brl_committing = 0;
...@@ -152,8 +152,9 @@ _XimLocalCreateIC( ...@@ -152,8 +152,9 @@ _XimLocalCreateIC(
ic->methods = &Local_ic_methods; ic->methods = &Local_ic_methods;
ic->core.im = im; 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.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_pressed = 0;
ic->private.local.brl_committing = 0; ic->private.local.brl_committing = 0;
ic->private.local.brl_committed = 0; ic->private.local.brl_committed = 0;
......
...@@ -78,23 +78,29 @@ _XimCheckIfLocalProcessing(im) ...@@ -78,23 +78,29 @@ _XimCheckIfLocalProcessing(im)
Private void Private void
XimFreeDefaultTree( XimFreeDefaultTree(
DefTree *top) DefTreeBase *b)
{ {
if (!top) return; if (!b) return;
if (top->succession) XimFreeDefaultTree(top->succession); if (b->tree) Xfree (b->tree);
if (top->next) XimFreeDefaultTree(top->next); if (b->mb) Xfree (b->mb);
if (top->mb) Xfree(top->mb); if (b->wc) Xfree (b->wc);
if (top->wc) Xfree(top->wc); if (b->utf8) Xfree (b->utf8);
if (top->utf8) Xfree(top->utf8); b->tree = NULL;
Xfree(top); 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 Public void
_XimLocalIMFree( _XimLocalIMFree(
Xim im) Xim im)
{ {
XimFreeDefaultTree(im->private.local.top); XimFreeDefaultTree(&im->private.local.base);
im->private.local.top = NULL; im->private.local.top = 0;
if(im->core.im_resources) { if(im->core.im_resources) {
Xfree(im->core.im_resources); Xfree(im->core.im_resources);
...@@ -327,6 +333,11 @@ _XimLocalOpenIM( ...@@ -327,6 +333,11 @@ _XimLocalOpenIM(
goto Open_Error; goto Open_Error;
private->ucstoutf8_conv = conv; private->ucstoutf8_conv = conv;
private->base.treeused = 1;
private->base.mbused = 1;
private->base.wcused = 1;
private->base.utf8used = 1;
_XimCreateDefaultTree(im); _XimCreateDefaultTree(im);
im->methods = &Xim_im_local_methods; im->methods = &Xim_im_local_methods;
......
...@@ -56,13 +56,15 @@ _XimLocalMbLookupString(xic, ev, buffer, bytes, keysym, status) ...@@ -56,13 +56,15 @@ _XimLocalMbLookupString(xic, ev, buffer, bytes, keysym, status)
{ {
Xic ic = (Xic)xic; Xic ic = (Xic)xic;
int ret; int ret;
DefTree *b = ic->private.local.base.tree;
char *mb = ic->private.local.base.mb;
if(ev->type != KeyPress) { if(ev->type != KeyPress) {
if(status) *status = XLookupNone; if(status) *status = XLookupNone;
return(0); return(0);
} }
if(ev->keycode == 0 && if(ev->keycode == 0 &&
( (ic->private.local.composed != NULL) ( (ic->private.local.composed != 0)
||(ic->private.local.brl_committed != 0))) { ||(ic->private.local.brl_committed != 0))) {
if (ic->private.local.brl_committed != 0) { /* Braille Event */ if (ic->private.local.brl_committed != 0) { /* Braille Event */
unsigned char pattern = ic->private.local.brl_committed; unsigned char pattern = ic->private.local.brl_committed;
...@@ -79,13 +81,13 @@ _XimLocalMbLookupString(xic, ev, buffer, bytes, keysym, status) ...@@ -79,13 +81,13 @@ _XimLocalMbLookupString(xic, ev, buffer, bytes, keysym, status)
if(status) *status = XLookupChars; if(status) *status = XLookupChars;
memcpy(buffer, mb, ret); memcpy(buffer, mb, ret);
} else { /* Composed Event */ } else { /* Composed Event */
ret = strlen(ic->private.local.composed->mb); ret = strlen(&mb[b[ic->private.local.composed].mb]);
if(ret > bytes) { if(ret > bytes) {
if(status) *status = XBufferOverflow; if(status) *status = XBufferOverflow;
return(ret); return(ret);
} }
memcpy(buffer, ic->private.local.composed->mb, ret); memcpy(buffer, &mb[b[ic->private.local.composed].mb], ret);
if(keysym) *keysym = ic->private.local.composed->ks; if(keysym) *keysym = b[ic->private.local.composed].ks;
if (ret > 0) { if (ret > 0) {
if (keysym && *keysym != NoSymbol) { if (keysym && *keysym != NoSymbol) {
if(status) *status = XLookupBoth; if(status) *status = XLookupBoth;
...@@ -133,6 +135,8 @@ _XimLocalWcLookupString(xic, ev, buffer, wlen, keysym, status) ...@@ -133,6 +135,8 @@ _XimLocalWcLookupString(xic, ev, buffer, wlen, keysym, status)
{ {
Xic ic = (Xic)xic; Xic ic = (Xic)xic;
int ret; int ret;
DefTree *b = ic->private.local.base.tree;
wchar_t *wc = ic->private.local.base.wc;
if(ev->type != KeyPress) { if(ev->type != KeyPress) {
if(status) *status = XLookupNone; if(status) *status = XLookupNone;
...@@ -153,14 +157,14 @@ _XimLocalWcLookupString(xic, ev, buffer, wlen, keysym, status) ...@@ -153,14 +157,14 @@ _XimLocalWcLookupString(xic, ev, buffer, wlen, keysym, status)
} else } else
if(status) *status = XLookupChars; if(status) *status = XLookupChars;
} else { /* Composed Event */ } else { /* Composed Event */
ret = _Xwcslen(ic->private.local.composed->wc); ret = _Xwcslen(&wc[b[ic->private.local.composed].wc]);
if(ret > wlen) { if(ret > wlen) {
if(status) *status = XBufferOverflow; if(status) *status = XBufferOverflow;
return (ret); 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)); 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 (ret > 0) {
if (keysym && *keysym != NoSymbol) { if (keysym && *keysym != NoSymbol) {
if(status) *status = XLookupBoth; if(status) *status = XLookupBoth;
...@@ -208,6 +212,8 @@ _XimLocalUtf8LookupString(xic, ev, buffer, bytes, keysym, status) ...@@ -208,6 +212,8 @@ _XimLocalUtf8LookupString(xic, ev, buffer, bytes, keysym, status)
{ {
Xic ic = (Xic)xic; Xic ic = (Xic)xic;
int ret; int ret;
DefTree *b = ic->private.local.base.tree;
char *utf8 = ic->private.local.base.utf8;
if(ev->type != KeyPress) { if(ev->type != KeyPress) {
if(status) *status = XLookupNone; if(status) *status = XLookupNone;
...@@ -225,13 +231,13 @@ _XimLocalUtf8LookupString(xic, ev, buffer, bytes, keysym, status) ...@@ -225,13 +231,13 @@ _XimLocalUtf8LookupString(xic, ev, buffer, bytes, keysym, status)
buffer[1] = 0x80 | ((BRL_UC_ROW >> 8) & 0x30) | (pattern >> 6); buffer[1] = 0x80 | ((BRL_UC_ROW >> 8) & 0x30) | (pattern >> 6);
buffer[2] = 0x80 | (pattern & 0x3f); buffer[2] = 0x80 | (pattern & 0x3f);
} else { /* Composed Event */ } else { /* Composed Event */
ret = strlen(ic->private.local.composed->utf8); ret = strlen(&utf8[b[ic->private.local.composed].utf8]);
if(ret > bytes) { if(ret > bytes) {
if(status) *status = XBufferOverflow; if(status) *status = XBufferOverflow;
return (ret); return (ret);
} }
memcpy(buffer, ic->private.local.composed->utf8, ret); memcpy(buffer, &utf8[b[ic->private.local.composed].utf8], ret);
if(keysym) *keysym = ic->private.local.composed->ks; if(keysym) *keysym = b[ic->private.local.composed].ks;
if (ret > 0) { if (ret > 0) {
if (keysym && *keysym != NoSymbol) { if (keysym && *keysym != NoSymbol) {
if(status) *status = XLookupBoth; if(status) *status = XLookupBoth;
......
...@@ -422,11 +422,13 @@ parseline( ...@@ -422,11 +422,13 @@ parseline(
char* tokenbuf) char* tokenbuf)
{ {
int token; int token;
unsigned modifier_mask; DTModifier modifier_mask;
unsigned modifier; DTModifier modifier;
unsigned tmp; DTModifier tmp;
KeySym keysym = NoSymbol; 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; DefTree *p = NULL;
Bool exclam, tilde; Bool exclam, tilde;
KeySym rhs_keysym = 0; KeySym rhs_keysym = 0;
...@@ -438,8 +440,8 @@ parseline( ...@@ -438,8 +440,8 @@ parseline(
char local_utf8_buf[LOCAL_UTF8_BUFSIZE], *rhs_string_utf8; char local_utf8_buf[LOCAL_UTF8_BUFSIZE], *rhs_string_utf8;
struct DefBuffer { struct DefBuffer {
unsigned modifier_mask; DTModifier modifier_mask;
unsigned modifier; DTModifier modifier;
KeySym keysym; KeySym keysym;
}; };
...@@ -536,20 +538,24 @@ parseline( ...@@ -536,20 +538,24 @@ parseline(
token = nexttoken(fp, tokenbuf, &lastch); token = nexttoken(fp, tokenbuf, &lastch);
if (token == STRING) { if (token == STRING) {
if( (rhs_string_mb = Xmalloc(strlen(tokenbuf) + 1)) == NULL ) l = strlen(tokenbuf) + 1;
goto error; 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); strcpy(rhs_string_mb, tokenbuf);
token = nexttoken(fp, tokenbuf, &lastch); token = nexttoken(fp, tokenbuf, &lastch);
if (token == KEY) { if (token == KEY) {
rhs_keysym = XStringToKeysym(tokenbuf); rhs_keysym = XStringToKeysym(tokenbuf);
if (rhs_keysym == NoSymbol) { if (rhs_keysym == NoSymbol) {
Xfree(rhs_string_mb);
goto error; goto error;
} }
token = nexttoken(fp, tokenbuf, &lastch); token = nexttoken(fp, tokenbuf, &lastch);
} }
if (token != ENDOFLINE && token != ENDOFFILE) { if (token != ENDOFLINE && token != ENDOFFILE) {
Xfree(rhs_string_mb);
goto error; goto error;
} }
} else if (token == KEY) { } else if (token == KEY) {
...@@ -563,14 +569,13 @@ parseline( ...@@ -563,14 +569,13 @@ parseline(
} }
l = get_mb_string(im, local_mb_buf, rhs_keysym); l = get_mb_string(im, local_mb_buf, rhs_keysym);
if (l == 0) { while (b->mbused + l + 1 > b->mbsize) {
rhs_string_mb = Xmalloc(1); b->mbsize = b->mbsize ? b->mbsize * 1.5 : 1024;
} else { if (! (b->mb = Xrealloc (b->mb, b->mbsize)) )
rhs_string_mb = Xmalloc(l + 1); goto error;
}
if( rhs_string_mb == NULL ) {
goto error;
} }
rhs_string_mb = &b->mb[b->mbused];
b->mbused += l + 1;
memcpy(rhs_string_mb, local_mb_buf, l); memcpy(rhs_string_mb, local_mb_buf, l);
rhs_string_mb[l] = '\0'; rhs_string_mb[l] = '\0';
} else { } else {
...@@ -581,62 +586,70 @@ parseline( ...@@ -581,62 +586,70 @@ parseline(
if (l == LOCAL_WC_BUFSIZE - 1) { if (l == LOCAL_WC_BUFSIZE - 1) {
local_wc_buf[l] = (wchar_t)'\0'; local_wc_buf[l] = (wchar_t)'\0';
} }
if( (rhs_string_wc = (wchar_t *)Xmalloc((l + 1) * sizeof(wchar_t))) == NULL ) { while (b->wcused + l + 1 > b->wcsize) {
Xfree( rhs_string_mb ); b->wcsize = b->wcsize ? b->wcsize * 1.5 : 512;
return( 0 ); 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) ); 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); l = _Xmbstoutf8(local_utf8_buf, rhs_string_mb, LOCAL_UTF8_BUFSIZE - 1);
if (l == LOCAL_UTF8_BUFSIZE - 1) { if (l == LOCAL_UTF8_BUFSIZE - 1) {
local_wc_buf[l] = '\0'; local_wc_buf[l] = '\0';
} }
if( (rhs_string_utf8 = (char *)Xmalloc(l + 1)) == NULL ) { while (b->utf8used + l + 1 > b->utf8size) {
Xfree( rhs_string_wc ); b->utf8size = b->utf8size ? b->utf8size * 1.5 : 1024;
Xfree( rhs_string_mb ); if (! (b->utf8 = Xrealloc (b->utf8, b->utf8size)) )
return( 0 ); goto error;
} }
rhs_string_utf8 = &b->utf8[b->utf8used];
b->utf8used += l + 1;
memcpy(rhs_string_utf8, local_utf8_buf, l + 1); memcpy(rhs_string_utf8, local_utf8_buf, l + 1);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
for (p = *top; p; p = p->next) { for (t = *top; t; t = b->tree[t].next) {
if (buf[i].keysym == p->keysym && if (buf[i].keysym == b->tree[t].keysym &&
buf[i].modifier == p->modifier && buf[i].modifier == b->tree[t].modifier &&
buf[i].modifier_mask == p->modifier_mask) { buf[i].modifier_mask == b->tree[t].modifier_mask) {
break; break;
} }
} }
if (p) { if (t) {
p = &b->tree[t];
top = &p->succession; top = &p->succession;
} else { } else {
if( (p = (DefTree*)Xmalloc(sizeof(DefTree))) == NULL ) { while (b->treeused >= b->treesize) {
Xfree( rhs_string_mb ); DefTree *old = b->tree;
goto error; 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->keysym = buf[i].keysym;
p->modifier = buf[i].modifier; p->modifier = buf[i].modifier;
p->modifier_mask = buf[i].modifier_mask; p->modifier_mask = buf[i].modifier_mask;
p->succession = NULL; p->succession = 0;
p->next = *top; p->next = *top;
p->mb = NULL; p->mb = 0;
p->wc = NULL; p->wc = 0;
p->utf8 = NULL; p->utf8 = 0;
p->ks = NoSymbol; p->ks = NoSymbol;
*top = p; *top = b->treeused;
top = &p->succession; top = &p->succession;
b->treeused++;
} }
} }
if( p->mb != NULL ) /* old entries no longer freed... */
Xfree( p->mb ); p->mb = rhs_string_mb - b->mb;
p->mb = rhs_string_mb; p->wc = rhs_string_wc - b->wc;
if( p->wc != NULL ) p->utf8 = rhs_string_utf8 - b->utf8;
Xfree( p->wc ); p->ks = rhs_keysym;
p->wc = rhs_string_wc;
if( p->utf8 != NULL )
Xfree( p->utf8 );
p->utf8 = rhs_string_utf8;
p->ks = rhs_keysym;
return(n); return(n);
error: error:
while (token != ENDOFLINE && token != ENDOFFILE) { while (token != ENDOFLINE && token != ENDOFFILE) {
......
...@@ -522,9 +522,9 @@ Private Bool ThaiComposeConvert( ...@@ -522,9 +522,9 @@ Private Bool ThaiComposeConvert(
* Macros to save and recall last input character in XIC * Macros to save and recall last input character in XIC
*/ */
#define IC_SavePreviousChar(ic,ch) \ #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) \ #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) \ #define IC_GetPreviousChar(ic) \
(IC_RealGetPreviousChar(ic,1)) (IC_RealGetPreviousChar(ic,1))
#define IC_GetContextChar(ic) \ #define IC_GetContextChar(ic) \
...@@ -536,6 +536,7 @@ Private unsigned char ...@@ -536,6 +536,7 @@ Private unsigned char
IC_RealGetPreviousChar(Xic ic, unsigned short pos) IC_RealGetPreviousChar(Xic ic, unsigned short pos)
{ {
XICCallback* cb = &ic->core.string_conversion_callback; XICCallback* cb = &ic->core.string_conversion_callback;
DefTreeBase *b = &ic->private.local.base;
if (cb && cb->callback) { if (cb && cb->callback) {
XIMStringConversionCallbackStruct screc; XIMStringConversionCallbackStruct screc;
...@@ -552,7 +553,7 @@ IC_RealGetPreviousChar(Xic ic, unsigned short pos) ...@@ -552,7 +553,7 @@ IC_RealGetPreviousChar(Xic ic, unsigned short pos)
(cb->callback)((XIC)ic, cb->client_data, (XPointer)&screc); (cb->callback)((XIC)ic, cb->client_data, (XPointer)&screc);
if (!screc.text) 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 && if ((screc.text->feedback &&
*screc.text->feedback == XIMStringConversionLeftEdge) || *screc.text->feedback == XIMStringConversionLeftEdge) ||
screc.text->length < 1) screc.text->length < 1)
...@@ -570,7 +571,7 @@ IC_RealGetPreviousChar(Xic ic, unsigned short pos) ...@@ -570,7 +571,7 @@ IC_RealGetPreviousChar(Xic ic, unsigned short pos)
XFree(screc.text); XFree(screc.text);
return c; return c;
} else { } 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) ...@@ -1193,13 +1194,14 @@ Private void InitIscMode(Xic ic)
Private Bool Private Bool
ThaiFltAcceptInput(Xic ic, unsigned char new_char, KeySym symbol) ThaiFltAcceptInput(Xic ic, unsigned char new_char, KeySym symbol)
{ {
ic->private.local.composed->wc[0] = tis2ucs(new_char); DefTreeBase *b = &ic->private.local.base;
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)) if ((new_char <= 0x1f) || (new_char == 0x7f))
ic->private.local.composed->keysym = symbol; b->tree[ic->private.local.composed].keysym = symbol;
else else
ic->private.local.composed->keysym = NoSymbol; b->tree[ic->private.local.composed].keysym = NoSymbol;
return True; return True;
} }
...@@ -1207,12 +1209,13 @@ ThaiFltAcceptInput(Xic ic, unsigned char new_char, KeySym symbol) ...@@ -1207,12 +1209,13 @@ ThaiFltAcceptInput(Xic ic, unsigned char new_char, KeySym symbol)
Private Bool Private Bool
ThaiFltReorderInput(Xic ic, unsigned char previous_char, unsigned char new_char) ThaiFltReorderInput(Xic ic, unsigned char previous_char, unsigned char new_char)
{ {
DefTreeBase *b = &ic->private.local.base;
if (!IC_DeletePreviousChar(ic)) return False; if (!IC_DeletePreviousChar(ic)) return False;
ic->private.local.composed->wc[0] = tis2ucs(new_char); b->wc[b->tree[ic->private.local.composed].wc+0] = tis2ucs(new_char);
ic->private.local.composed->wc[1] = tis2ucs(previous_char); b->wc[b->tree[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+2] = '\0';
ic->private.local.composed->keysym = NoSymbol; b->tree[ic->private.local.composed].keysym = NoSymbol;
return True; return True;
} }
...@@ -1220,14 +1223,15 @@ ThaiFltReorderInput(Xic ic, unsigned char previous_char, unsigned char new_char) ...@@ -1220,14 +1223,15 @@ ThaiFltReorderInput(Xic ic, unsigned char previous_char, unsigned char new_char)
Private Bool Private Bool
ThaiFltReplaceInput(Xic ic, unsigned char new_char, KeySym symbol) ThaiFltReplaceInput(Xic ic, unsigned char new_char, KeySym symbol)
{ {
DefTreeBase *b = &ic->private.local.base;
if (!IC_DeletePreviousChar(ic)) return False; if (!IC_DeletePreviousChar(ic)) return False;
ic->private.local.composed->wc[0] = tis2ucs(new_char); b->wc[b->tree[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+1] = '\0';
if ((new_char <= 0x1f) || (new_char == 0x7f)) if ((new_char <= 0x1f) || (new_char == 0x7f))
ic->private.local.composed->keysym = symbol; b->tree[ic->private.local.composed].keysym = symbol;
else else
ic->private.local.composed->keysym = NoSymbol; b->tree[ic->private.local.composed].keysym = NoSymbol;
return True; return True;
} }
...@@ -1256,6 +1260,7 @@ XPointer client_data; ...@@ -1256,6 +1260,7 @@ XPointer client_data;
#endif #endif
wchar_t wbuf[10]; wchar_t wbuf[10];
Bool isReject; Bool isReject;
DefTreeBase *b = &ic->private.local.base;
if ((ev->type