aboutsummaryrefslogtreecommitdiff
path: root/libX11/modules/im
diff options
context:
space:
mode:
Diffstat (limited to 'libX11/modules/im')
-rw-r--r--libX11/modules/im/Makefile.am2
-rw-r--r--libX11/modules/im/ximcp/imDispch.c208
-rw-r--r--libX11/modules/im/ximcp/imImSw.c110
-rw-r--r--libX11/modules/im/ximcp/imLcPrs.c1370
-rw-r--r--libX11/modules/im/ximcp/imLcSIc.c108
-rw-r--r--libX11/modules/im/ximcp/imThaiFlt.c2842
-rw-r--r--libX11/modules/im/ximcp/imThaiIm.c470
7 files changed, 2555 insertions, 2555 deletions
diff --git a/libX11/modules/im/Makefile.am b/libX11/modules/im/Makefile.am
index 0974cf615..330a6dd6d 100644
--- a/libX11/modules/im/Makefile.am
+++ b/libX11/modules/im/Makefile.am
@@ -1 +1 @@
-SUBDIRS=ximcp
+SUBDIRS=ximcp
diff --git a/libX11/modules/im/ximcp/imDispch.c b/libX11/modules/im/ximcp/imDispch.c
index f9b4bdb77..3d67909ee 100644
--- a/libX11/modules/im/ximcp/imDispch.c
+++ b/libX11/modules/im/ximcp/imDispch.c
@@ -1,104 +1,104 @@
-/******************************************************************
-
- Copyright 1993, 1994 by FUJITSU LIMITED
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and
-that both that copyright notice and this permission notice appear
-in supporting documentation, and that the name of FUJITSU LIMITED
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-FUJITSU LIMITED makes no representations about the suitability of
-this software for any purpose.
-It is provided "as is" without express or implied warranty.
-
-FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
-USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
- Author: Takashi Fujiwara FUJITSU LIMITED
- fujiwara@a80.tech.yk.fujitsu.co.jp
-
-******************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <X11/Xlib.h>
-#include "Xlibint.h"
-#include "Xutil.h"
-#include "Xlcint.h"
-#include "Ximint.h"
-
-
-Public Bool
-_XimRegProtoIntrCallback(
- Xim im,
- CARD16 major_code,
- CARD16 minor_code,
- Bool (*proc)(
- Xim, INT16, XPointer, XPointer
- ),
-
- XPointer call_data)
-{
- XimProtoIntrRec *rec;
-
- if (!(rec = (XimProtoIntrRec *)Xmalloc(sizeof(XimProtoIntrRec))))
- return False;
- rec->func = proc;
- rec->major_code = major_code;
- rec->minor_code = minor_code;
- rec->call_data = call_data;
- rec->next = im->private.proto.intrproto;
- im->private.proto.intrproto = rec;
- return True;
-}
-
-Public void
-_XimFreeProtoIntrCallback(Xim im)
-{
- register XimProtoIntrRec *rec, *next;
-
- for (rec = im->private.proto.intrproto; rec;) {
- next = rec->next;
- Xfree(rec);
- rec = next;
- }
- im->private.proto.intrproto = NULL;
- return;
-}
-
-Private Bool
-_XimTransportIntr(
- Xim im,
- INT16 len,
- XPointer data,
- XPointer call_data)
-{
- Xim call_im = (Xim)call_data;
- XimProtoIntrRec *rec = call_im->private.proto.intrproto;
- CARD8 major_opcode = *((CARD8 *)data);
- CARD8 minor_opcode = *((CARD8 *)data + 1);
-
- for (; rec; rec = rec->next) {
- if ((major_opcode == (CARD8)rec->major_code)
- && (minor_opcode == (CARD8)rec->minor_code))
- if ((*rec->func)(call_im, len, data, rec->call_data))
- return True;
- }
- return False;
-}
-
-Public Bool
-_XimDispatchInit(Xim im)
-{
- if (_XimRegisterDispatcher(im, _XimTransportIntr, (XPointer)im))
- return True;
- return False;
-}
+/******************************************************************
+
+ Copyright 1993, 1994 by FUJITSU LIMITED
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and
+that both that copyright notice and this permission notice appear
+in supporting documentation, and that the name of FUJITSU LIMITED
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+FUJITSU LIMITED makes no representations about the suitability of
+this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+ Author: Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/Xlib.h>
+#include "Xlibint.h"
+#include "Xutil.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+
+
+Public Bool
+_XimRegProtoIntrCallback(
+ Xim im,
+ CARD16 major_code,
+ CARD16 minor_code,
+ Bool (*proc)(
+ Xim, INT16, XPointer, XPointer
+ ),
+
+ XPointer call_data)
+{
+ XimProtoIntrRec *rec;
+
+ if (!(rec = (XimProtoIntrRec *)Xmalloc(sizeof(XimProtoIntrRec))))
+ return False;
+ rec->func = proc;
+ rec->major_code = major_code;
+ rec->minor_code = minor_code;
+ rec->call_data = call_data;
+ rec->next = im->private.proto.intrproto;
+ im->private.proto.intrproto = rec;
+ return True;
+}
+
+Public void
+_XimFreeProtoIntrCallback(Xim im)
+{
+ register XimProtoIntrRec *rec, *next;
+
+ for (rec = im->private.proto.intrproto; rec;) {
+ next = rec->next;
+ Xfree(rec);
+ rec = next;
+ }
+ im->private.proto.intrproto = NULL;
+ return;
+}
+
+Private Bool
+_XimTransportIntr(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer call_data)
+{
+ Xim call_im = (Xim)call_data;
+ XimProtoIntrRec *rec = call_im->private.proto.intrproto;
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+
+ for (; rec; rec = rec->next) {
+ if ((major_opcode == (CARD8)rec->major_code)
+ && (minor_opcode == (CARD8)rec->minor_code))
+ if ((*rec->func)(call_im, len, data, rec->call_data))
+ return True;
+ }
+ return False;
+}
+
+Public Bool
+_XimDispatchInit(Xim im)
+{
+ if (_XimRegisterDispatcher(im, _XimTransportIntr, (XPointer)im))
+ return True;
+ return False;
+}
diff --git a/libX11/modules/im/ximcp/imImSw.c b/libX11/modules/im/ximcp/imImSw.c
index acad4b8af..dfa6d6699 100644
--- a/libX11/modules/im/ximcp/imImSw.c
+++ b/libX11/modules/im/ximcp/imImSw.c
@@ -1,55 +1,55 @@
-/******************************************************************
-
- Copyright 1992, 1993 by FUJITSU LIMITED
- Copyright 1993 by Digital Equipment Corporation
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of FUJITSU LIMITED and
-Digital Equipment Corporation not be used in advertising or publicity
-pertaining to distribution of the software without specific, written
-prior permission. FUJITSU LIMITED and Digital Equipment Corporation
-makes no representations about the suitability of this software for
-any purpose. It is provided "as is" without express or implied
-warranty.
-
-FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL
-WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR
-ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-THIS SOFTWARE.
-
- Author: Takashi Fujiwara FUJITSU LIMITED
- fujiwara@a80.tech.yk.fujitsu.co.jp
- Modifier: Franky Ling Digital Equipment Corporation
- frankyling@hgrd01.enet.dec.com
-
-******************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "Xlibint.h"
-#include "Xlcint.h"
-#include "Ximint.h"
-#include "XimImSw.h"
-
-Private Bool
-_XimCheckIfDefault(
- Xim im)
-{
- return(True);
-}
-
-XimImsportSW _XimImSportRec[] = {
- { _XimCheckIfLocalProcessing, _XimLocalOpenIM, _XimLocalIMFree },
- { _XimCheckIfThaiProcessing, _XimThaiOpenIM, _XimThaiIMFree },
- { _XimCheckIfDefault, _XimProtoOpenIM, _XimProtoIMFree },
- { NULL, NULL, NULL },
-};
+/******************************************************************
+
+ Copyright 1992, 1993 by FUJITSU LIMITED
+ Copyright 1993 by Digital Equipment Corporation
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of FUJITSU LIMITED and
+Digital Equipment Corporation not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission. FUJITSU LIMITED and Digital Equipment Corporation
+makes no representations about the suitability of this software for
+any purpose. It is provided "as is" without express or implied
+warranty.
+
+FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL
+WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR
+ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+ Author: Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+ Modifier: Franky Ling Digital Equipment Corporation
+ frankyling@hgrd01.enet.dec.com
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+#include "XimImSw.h"
+
+Private Bool
+_XimCheckIfDefault(
+ Xim im)
+{
+ return(True);
+}
+
+XimImsportSW _XimImSportRec[] = {
+ { _XimCheckIfLocalProcessing, _XimLocalOpenIM, _XimLocalIMFree },
+ { _XimCheckIfThaiProcessing, _XimThaiOpenIM, _XimThaiIMFree },
+ { _XimCheckIfDefault, _XimProtoOpenIM, _XimProtoIMFree },
+ { NULL, NULL, NULL },
+};
diff --git a/libX11/modules/im/ximcp/imLcPrs.c b/libX11/modules/im/ximcp/imLcPrs.c
index f5d6f8cd1..4e54385b5 100644
--- a/libX11/modules/im/ximcp/imLcPrs.c
+++ b/libX11/modules/im/ximcp/imLcPrs.c
@@ -1,685 +1,685 @@
-/******************************************************************
-
- Copyright 1992 by Oki Technosystems Laboratory, Inc.
- Copyright 1992 by Fuji Xerox Co., Ltd.
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and
-that both that copyright notice and this permission notice appear
-in supporting documentation, and that the name of Oki Technosystems
-Laboratory and Fuji Xerox not be used in advertising or publicity
-pertaining to distribution of the software without specific, written
-prior permission.
-Oki Technosystems Laboratory and Fuji Xerox make no representations
-about the suitability of this software for any purpose. It is provided
-"as is" without express or implied warranty.
-
-OKI TECHNOSYSTEMS LABORATORY AND FUJI XEROX DISCLAIM ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OKI TECHNOSYSTEMS
-LABORATORY AND FUJI XEROX BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
-OR PERFORMANCE OF THIS SOFTWARE.
-
- Author: Yasuhiro Kawai Oki Technosystems Laboratory
- Author: Kazunori Nishihara Fuji Xerox
-
-******************************************************************/
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <X11/Xlib.h>
-#include <X11/Xmd.h>
-#include <X11/Xos.h>
-#include "Xlibint.h"
-#include "Xlcint.h"
-#include "Ximint.h"
-#include <sys/stat.h>
-#include <stdio.h>
-
-#define XLC_BUFSIZE 256
-
-extern int _Xmbstowcs(
- wchar_t *wstr,
- char *str,
- int len
-);
-
-extern int _Xmbstoutf8(
- char *ustr,
- const char *str,
- int len
-);
-
-/*
- * Parsing File Format:
- *
- * FILE ::= { [PRODUCTION] [COMMENT] "\n"}
- * PRODUCTION ::= LHS ":" RHS [ COMMENT ]
- * COMMENT ::= "#" {<any character except null or newline>}
- * LHS ::= EVENT { EVENT }
- * EVENT ::= [MODIFIER_LIST] "<" keysym ">"
- * MODIFIER_LIST ::= ("!" {MODIFIER} ) | "None"
- * MODIFIER ::= ["~"] modifier_name
- * RHS ::= ( STRING | keysym | STRING keysym )
- * STRING ::= '"' { CHAR } '"'
- * CHAR ::= GRAPHIC_CHAR | ESCAPED_CHAR
- * GRAPHIC_CHAR ::= locale (codeset) dependent code
- * ESCAPED_CHAR ::= ('\\' | '\"' | OCTAL | HEX )
- * OCTAL ::= '\' OCTAL_CHAR [OCTAL_CHAR [OCTAL_CHAR]]
- * OCTAL_CHAR ::= (0|1|2|3|4|5|6|7)
- * HEX ::= '\' (x|X) HEX_CHAR [HEX_CHAR]]
- * HEX_CHAR ::= (0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|a|b|c|d|e|f)
- *
- */
-
-static int
-nextch(
- FILE *fp,
- int *lastch)
-{
- int c;
-
- if (*lastch != 0) {
- c = *lastch;
- *lastch = 0;
- } else {
- c = getc(fp);
- if (c == '\\') {
- c = getc(fp);
- if (c == '\n') {
- c = getc(fp);
- } else {
- ungetc(c, fp);
- c = '\\';
- }
- }
- }
- return(c);
-}
-
-static void
-putbackch(
- int c,
- int *lastch)
-{
- *lastch = c;
-}
-
-#define ENDOFFILE 0
-#define ENDOFLINE 1
-#define COLON 2
-#define LESS 3
-#define GREATER 4
-#define EXCLAM 5
-#define TILDE 6
-#define STRING 7
-#define KEY 8
-#define ERROR 9
-
-#ifndef isalnum
-#define isalnum(c) \
- (('0' <= (c) && (c) <= '9') || \
- ('A' <= (c) && (c) <= 'Z') || \
- ('a' <= (c) && (c) <= 'z'))
-#endif
-
-static int
-nexttoken(
- FILE *fp,
- char *tokenbuf,
- int *lastch)
-{
- int c;
- int token;
- char *p;
- int i, j;
-
- while ((c = nextch(fp, lastch)) == ' ' || c == '\t') {
- }
- switch (c) {
- case EOF:
- token = ENDOFFILE;
- break;
- case '\n':
- token = ENDOFLINE;
- break;
- case '<':
- token = LESS;
- break;
- case '>':
- token = GREATER;
- break;
- case ':':
- token = COLON;
- break;
- case '!':
- token = EXCLAM;
- break;
- case '~':
- token = TILDE;
- break;
- case '"':
- p = tokenbuf;
- while ((c = nextch(fp, lastch)) != '"') {
- if (c == '\n' || c == EOF) {
- putbackch(c, lastch);
- token = ERROR;
- goto string_error;
- } else if (c == '\\') {
- c = nextch(fp, lastch);
- switch (c) {
- case '\\':
- case '"':
- *p++ = c;
- break;
- case 'n':
- *p++ = '\n';
- break;
- case 'r':
- *p++ = '\r';
- break;
- case 't':
- *p++ = '\t';
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- i = c - '0';
- c = nextch(fp, lastch);
- for (j = 0; j < 2 && c >= '0' && c <= '7'; j++) {
- i <<= 3;
- i += c - '0';
- c = nextch(fp, lastch);
- }
- putbackch(c, lastch);
- *p++ = (char)i;
- break;
- case 'X':
- case 'x':
- i = 0;
- for (j = 0; j < 2; j++) {
- c = nextch(fp, lastch);
- i <<= 4;
- if (c >= '0' && c <= '9') {
- i += c - '0';
- } else if (c >= 'A' && c <= 'F') {
- i += c - 'A' + 10;
- } else if (c >= 'a' && c <= 'f') {
- i += c - 'a' + 10;
- } else {
- putbackch(c, lastch);
- i >>= 4;
- break;
- }
- }
- if (j == 0) {
- token = ERROR;
- goto string_error;
- }
- *p++ = (char)i;
- break;
- case EOF:
- putbackch(c, lastch);
- token = ERROR;
- goto string_error;
- default:
- *p++ = c;
- break;
- }
- } else {
- *p++ = c;
- }
- }
- *p = '\0';
- token = STRING;
- break;
- case '#':
- while ((c = nextch(fp, lastch)) != '\n' && c != EOF) {
- }
- if (c == '\n') {
- token = ENDOFLINE;
- } else {
- token = ENDOFFILE;
- }
- break;
- default:
- if (isalnum(c) || c == '_' || c == '-') {
- p = tokenbuf;
- *p++ = c;
- c = nextch(fp, lastch);
- while (isalnum(c) || c == '_' || c == '-') {
- *p++ = c;
- c = nextch(fp, lastch);
- }
- *p = '\0';
- putbackch(c, lastch);
- token = KEY;
- } else {
- token = ERROR;
- }
- break;
- }
-string_error:
- return(token);
-}
-
-static long
-modmask(
- char *name)
-{
- struct _modtbl {
- const char name[6];
- long mask;
- };
-
- static const struct _modtbl tbl[] = {
- { "Ctrl", ControlMask },
- { "Lock", LockMask },
- { "Caps", LockMask },
- { "Shift", ShiftMask },
- { "Alt", Mod1Mask },
- { "Meta", Mod1Mask }};
-
- int i, num_entries = sizeof (tbl) / sizeof (tbl[0]);
-
- for (i = 0; i < num_entries; i++)
- if (!strcmp (name, tbl[i].name))
- return tbl[i].mask;
-
- return 0;
-}
-
-static char*
-TransFileName(Xim im, char *name)
-{
- char *home = NULL, *lcCompose = NULL;
- char dir[XLC_BUFSIZE];
- char *i = name, *ret, *j;
- int l = 0;
-
- while (*i) {
- if (*i == '%') {
- i++;
- switch (*i) {
- case '%':
- l++;
- break;
- case 'H':
- home = getenv("HOME");
- if (home)
- l += strlen(home);
- break;
- case 'L':
- if (lcCompose == NULL)
- lcCompose = _XlcFileName(im->core.lcd, COMPOSE_FILE);
- if (lcCompose)
- l += strlen(lcCompose);
- break;
- case 'S':
- xlocaledir(dir, XLC_BUFSIZE);
- l += strlen(dir);
- break;
- }
- } else {
- l++;
- }
- i++;
- }
-
- j = ret = Xmalloc(l+1);
- if (ret == NULL)
- return ret;
- i = name;
- while (*i) {
- if (*i == '%') {
- i++;
- switch (*i) {
- case '%':
- *j++ = '%';
- break;
- case 'H':
- if (home) {
- strcpy(j, home);
- j += strlen(home);
- }
- break;
- case 'L':
- if (lcCompose) {
- strcpy(j, lcCompose);
- j += strlen(lcCompose);
- }
- break;
- case 'S':
- strcpy(j, dir);
- j += strlen(dir);
- break;
- }
- i++;
- } else {
- *j++ = *i++;
- }
- }
- *j = '\0';
- Xfree(lcCompose);
- return ret;
-}
-
-#ifndef MB_LEN_MAX
-#define MB_LEN_MAX 6
-#endif
-
-static int
-get_mb_string (Xim im, char *buf, KeySym ks)
-{
- XPointer from, to;
- int from_len, to_len, len;
- XPointer args[1];
- XlcCharSet charset;
- char local_buf[MB_LEN_MAX];
- unsigned int ucs;
- ucs = KeySymToUcs4(ks);
-
- from = (XPointer) &ucs;
- to = (XPointer) local_buf;
- from_len = 1;
- to_len = MB_LEN_MAX;
- args[0] = (XPointer) &charset;
- if (_XlcConvert(im->private.local.ucstoc_conv,
- &from, &from_len, &to, &to_len, args, 1 ) != 0) {
- return 0;
- }
-
- from = (XPointer) local_buf;
- to = (XPointer) buf;
- from_len = MB_LEN_MAX - to_len;
- to_len = MB_LEN_MAX + 1;
- args[0] = (XPointer) charset;
- if (_XlcConvert(im->private.local.cstomb_conv,
- &from, &from_len, &to, &to_len, args, 1 ) != 0) {
- return 0;
- }
- len = MB_LEN_MAX + 1 - to_len;
- buf[len] = '\0';
- return len;
-}
-
-#define AllMask (ShiftMask | LockMask | ControlMask | Mod1Mask)
-#define LOCAL_WC_BUFSIZE 128
-#define LOCAL_UTF8_BUFSIZE 256
-#define SEQUENCE_MAX 10
-
-static int
-parseline(
- FILE *fp,
- Xim im,
- char* tokenbuf)
-{
- int token;
- DTModifier modifier_mask;
- DTModifier modifier;
- DTModifier tmp;
- KeySym keysym = NoSymbol;
- DTIndex *top = &im->private.local.top;
- DefTreeBase *b = &im->private.local.base;
- DTIndex t;
- DefTree *p = NULL;
- Bool exclam, tilde;
- KeySym rhs_keysym = 0;
- char *rhs_string_mb;
- int l;
- int lastch = 0;
- char local_mb_buf[MB_LEN_MAX+1];
- wchar_t local_wc_buf[LOCAL_WC_BUFSIZE], *rhs_string_wc;
- char local_utf8_buf[LOCAL_UTF8_BUFSIZE], *rhs_string_utf8;
-
- struct DefBuffer {
- DTModifier modifier_mask;
- DTModifier modifier;
- KeySym keysym;
- };
-
- struct DefBuffer buf[SEQUENCE_MAX];
- int i, n;
-
- do {
- token = nexttoken(fp, tokenbuf, &lastch);
- } while (token == ENDOFLINE);
-
- if (token == ENDOFFILE) {
- return(-1);
- }
-
- n = 0;
- do {
- if ((token == KEY) && (strcmp("include", tokenbuf) == 0)) {
- char *filename;
- FILE *infp;
- token = nexttoken(fp, tokenbuf, &lastch);
- if (token != KEY && token != STRING)
- goto error;
- if ((filename = TransFileName(im, tokenbuf)) == NULL)
- goto error;
- infp = _XFopenFile(filename, "r");
- Xfree(filename);
- if (infp == NULL)
- goto error;
- _XimParseStringFile(infp, im);
- fclose(infp);
- return (0);
- } else if ((token == KEY) && (strcmp("None", tokenbuf) == 0)) {
- modifier = 0;
- modifier_mask = AllMask;
- token = nexttoken(fp, tokenbuf, &lastch);
- } else {
- modifier_mask = modifier = 0;
- exclam = False;
- if (token == EXCLAM) {
- exclam = True;
- token = nexttoken(fp, tokenbuf, &lastch);
- }
- while (token == TILDE || token == KEY) {
- tilde = False;
- if (token == TILDE) {
- tilde = True;
- token = nexttoken(fp, tokenbuf, &lastch);
- if (token != KEY)
- goto error;
- }
- tmp = modmask(tokenbuf);
- if (!tmp) {
- goto error;
- }
- modifier_mask |= tmp;
- if (tilde) {
- modifier &= ~tmp;
- } else {
- modifier |= tmp;
- }
- token = nexttoken(fp, tokenbuf, &lastch);
- }
- if (exclam) {
- modifier_mask = AllMask;
- }
- }
-
- if (token != LESS) {
- goto error;
- }
-
- token = nexttoken(fp, tokenbuf, &lastch);
- if (token != KEY) {
- goto error;
- }
-
- token = nexttoken(fp, tokenbuf, &lastch);
- if (token != GREATER) {
- goto error;
- }
-
- keysym = XStringToKeysym(tokenbuf);
- if (keysym == NoSymbol) {
- goto error;
- }
-
- buf[n].keysym = keysym;
- buf[n].modifier = modifier;
- buf[n].modifier_mask = modifier_mask;
- n++;
- if( n >= SEQUENCE_MAX )
- goto error;
- token = nexttoken(fp, tokenbuf, &lastch);
- } while (token != COLON);
-
- token = nexttoken(fp, tokenbuf, &lastch);
- if (token == STRING) {
- 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) {
- goto error;
- }
- token = nexttoken(fp, tokenbuf, &lastch);
- }
- if (token != ENDOFLINE && token != ENDOFFILE) {
- goto error;
- }
- } else if (token == KEY) {
- rhs_keysym = XStringToKeysym(tokenbuf);
- if (rhs_keysym == NoSymbol) {
- goto error;
- }
- token = nexttoken(fp, tokenbuf, &lastch);
- if (token != ENDOFLINE && token != ENDOFFILE) {
- goto error;
- }
-
- l = get_mb_string(im, local_mb_buf, rhs_keysym);
- 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 {
- goto error;
- }
-
- l = _Xmbstowcs(local_wc_buf, rhs_string_mb, LOCAL_WC_BUFSIZE - 1);
- if (l == LOCAL_WC_BUFSIZE - 1) {
- local_wc_buf[l] = (wchar_t)'\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_utf8_buf[l] = '\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 (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 (t) {
- p = &b->tree[t];
- top = &p->succession;
- } else {
- 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 = 0;
- p->next = *top;
- p->mb = 0;
- p->wc = 0;
- p->utf8 = 0;
- p->ks = NoSymbol;
- *top = b->treeused;
- top = &p->succession;
- b->treeused++;
- }
- }
-
- /* 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) {
- token = nexttoken(fp, tokenbuf, &lastch);
- }
- return(0);
-}
-
-void
-_XimParseStringFile(
- FILE *fp,
- Xim im)
-{
- char tb[8192];
- char* tbp;
- struct stat st;
-
- if (fstat (fileno (fp), &st) != -1) {
- unsigned long size = (unsigned long) st.st_size;
- if (size <= sizeof tb) tbp = tb;
- else tbp = malloc (size);
-
- if (tbp != NULL) {
- while (parseline(fp, im, tbp) >= 0) {}
- if (tbp != tb) free (tbp);
- }
- }
-}
+/******************************************************************
+
+ Copyright 1992 by Oki Technosystems Laboratory, Inc.
+ Copyright 1992 by Fuji Xerox Co., Ltd.
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and
+that both that copyright notice and this permission notice appear
+in supporting documentation, and that the name of Oki Technosystems
+Laboratory and Fuji Xerox not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+Oki Technosystems Laboratory and Fuji Xerox make no representations
+about the suitability of this software for any purpose. It is provided
+"as is" without express or implied warranty.
+
+OKI TECHNOSYSTEMS LABORATORY AND FUJI XEROX DISCLAIM ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OKI TECHNOSYSTEMS
+LABORATORY AND FUJI XEROX BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
+OR PERFORMANCE OF THIS SOFTWARE.
+
+ Author: Yasuhiro Kawai Oki Technosystems Laboratory
+ Author: Kazunori Nishihara Fuji Xerox
+
+******************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/Xlib.h>
+#include <X11/Xmd.h>
+#include <X11/Xos.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+#include <sys/stat.h>
+#include <stdio.h>
+
+#define XLC_BUFSIZE 256
+
+extern int _Xmbstowcs(
+ wchar_t *wstr,
+ char *str,
+ int len
+);
+
+extern int _Xmbstoutf8(
+ char *ustr,
+ const char *str,
+ int len
+);
+
+/*
+ * Parsing File Format:
+ *
+ * FILE ::= { [PRODUCTION] [COMMENT] "\n"}
+ * PRODUCTION ::= LHS ":" RHS [ COMMENT ]
+ * COMMENT ::= "#" {<any character except null or newline>}
+ * LHS ::= EVENT { EVENT }
+ * EVENT ::= [MODIFIER_LIST] "<" keysym ">"
+ * MODIFIER_LIST ::= ("!" {MODIFIER} ) | "None"
+ * MODIFIER ::= ["~"] modifier_name
+ * RHS ::= ( STRING | keysym | STRING keysym )
+ * STRING ::= '"' { CHAR } '"'
+ * CHAR ::= GRAPHIC_CHAR | ESCAPED_CHAR
+ * GRAPHIC_CHAR ::= locale (codeset) dependent code
+ * ESCAPED_CHAR ::= ('\\' | '\"' | OCTAL | HEX )
+ * OCTAL ::= '\' OCTAL_CHAR [OCTAL_CHAR [OCTAL_CHAR]]
+ * OCTAL_CHAR ::= (0|1|2|3|4|5|6|7)
+ * HEX ::= '\' (x|X) HEX_CHAR [HEX_CHAR]]
+ * HEX_CHAR ::= (0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|a|b|c|d|e|f)
+ *
+ */
+
+static int
+nextch(
+ FILE *fp,
+ int *lastch)
+{
+ int c;
+
+ if (*lastch != 0) {
+ c = *lastch;
+ *lastch = 0;
+ } else {
+ c = getc(fp);
+ if (c == '\\') {
+ c = getc(fp);
+ if (c == '\n') {
+ c = getc(fp);
+ } else {
+ ungetc(c, fp);
+ c = '\\';
+ }
+ }
+ }
+ return(c);
+}
+
+static void
+putbackch(
+ int c,
+ int *lastch)
+{
+ *lastch = c;
+}
+
+#define ENDOFFILE 0
+#define ENDOFLINE 1
+#define COLON 2
+#define LESS 3
+#define GREATER 4
+#define EXCLAM 5
+#define TILDE 6
+#define STRING 7
+#define KEY 8
+#define ERROR 9
+
+#ifndef isalnum
+#define isalnum(c) \
+ (('0' <= (c) && (c) <= '9') || \
+ ('A' <= (c) && (c) <= 'Z') || \
+ ('a' <= (c) && (c) <= 'z'))
+#endif
+
+static int
+nexttoken(
+ FILE *fp,
+ char *tokenbuf,
+ int *lastch)
+{
+ int c;
+ int token;
+ char *p;
+ int i, j;
+
+ while ((c = nextch(fp, lastch)) == ' ' || c == '\t') {
+ }
+ switch (c) {
+ case EOF:
+ token = ENDOFFILE;
+ break;
+ case '\n':
+ token = ENDOFLINE;
+ break;
+ case '<':
+ token = LESS;
+ break;
+ case '>':
+ token = GREATER;
+ break;
+ case ':':
+ token = COLON;
+ break;
+ case '!':
+ token = EXCLAM;
+ break;
+ case '~':
+ token = TILDE;
+ break;
+ case '"':
+ p = tokenbuf;
+ while ((c = nextch(fp, lastch)) != '"') {
+ if (c == '\n' || c == EOF) {
+ putbackch(c, lastch);
+ token = ERROR;
+ goto string_error;
+ } else if (c == '\\') {
+ c = nextch(fp, lastch);
+ switch (c) {
+ case '\\':
+ case '"':
+ *p++ = c;
+ break;
+ case 'n':
+ *p++ = '\n';
+ break;
+ case 'r':
+ *p++ = '\r';
+ break;
+ case 't':
+ *p++ = '\t';
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ i = c - '0';
+ c = nextch(fp, lastch);
+ for (j = 0; j < 2 && c >= '0' && c <= '7'; j++) {
+ i <<= 3;
+ i += c - '0';
+ c = nextch(fp, lastch);
+ }
+ putbackch(c, lastch);
+ *p++ = (char)i;
+ break;
+ case 'X':
+ case 'x':
+ i = 0;
+ for (j = 0; j < 2; j++) {
+ c = nextch(fp, lastch);
+ i <<= 4;
+ if (c >= '0' && c <= '9') {
+ i += c - '0';
+ } else if (c >= 'A' && c <= 'F') {
+ i += c - 'A' + 10;
+ } else if (c >= 'a' && c <= 'f') {
+ i += c - 'a' + 10;
+ } else {
+ putbackch(c, lastch);
+ i >>= 4;
+ break;
+ }
+ }
+ if (j == 0) {
+ token = ERROR;
+ goto string_error;
+ }
+ *p++ = (char)i;
+ break;
+ case EOF:
+ putbackch(c, lastch);
+ token = ERROR;
+ goto string_error;
+ default:
+ *p++ = c;
+ break;
+ }
+ } else {
+ *p++ = c;
+ }
+ }
+ *p = '\0';
+ token = STRING;
+ break;
+ case '#':
+ while ((c = nextch(fp, lastch)) != '\n' && c != EOF) {
+ }
+ if (c == '\n') {
+ token = ENDOFLINE;
+ } else {
+ token = ENDOFFILE;
+ }
+ break;
+ default:
+ if (isalnum(c) || c == '_' || c == '-') {
+ p = tokenbuf;
+ *p++ = c;
+ c = nextch(fp, lastch);
+ while (isalnum(c) || c == '_' || c == '-') {
+ *p++ = c;
+ c = nextch(fp, lastch);
+ }
+ *p = '\0';
+ putbackch(c, lastch);
+ token = KEY;
+ } else {
+ token = ERROR;
+ }
+ break;
+ }
+string_error:
+ return(token);
+}
+
+static long
+modmask(
+ char *name)
+{
+ struct _modtbl {
+ const char name[6];
+ long mask;
+ };
+
+ static const struct _modtbl tbl[] = {
+ { "Ctrl", ControlMask },
+ { "Lock", LockMask },
+ { "Caps", LockMask },
+ { "Shift", ShiftMask },
+ { "Alt", Mod1Mask },
+ { "Meta", Mod1Mask }};
+
+ int i, num_entries = sizeof (tbl) / sizeof (tbl[0]);
+
+ for (i = 0; i < num_entries; i++)
+ if (!strcmp (name, tbl[i].name))
+ return tbl[i].mask;
+
+ return 0;
+}
+
+static char*
+TransFileName(Xim im, char *name)
+{
+ char *home = NULL, *lcCompose = NULL;
+ char dir[XLC_BUFSIZE];
+ char *i = name, *ret, *j;
+ int l = 0;
+
+ while (*i) {
+ if (*i == '%') {
+ i++;
+ switch (*i) {
+ case '%':
+ l++;
+ break;
+ case 'H':
+ home = getenv("HOME");
+ if (home)
+ l += strlen(home);
+ break;
+ case 'L':
+ if (lcCompose == NULL)
+ lcCompose = _XlcFileName(im->core.lcd, COMPOSE_FILE);
+ if (lcCompose)
+ l += strlen(lcCompose);
+ break;
+ case 'S':
+ xlocaledir(dir, XLC_BUFSIZE);
+ l += strlen(dir);
+ break;
+ }
+ } else {
+ l++;
+ }
+ i++;
+ }
+
+ j = ret = Xmalloc(l+1);
+ if (ret == NULL)
+ return ret;
+ i = name;
+ while (*i) {
+ if (*i == '%') {
+ i++;
+ switch (*i) {
+ case '%':
+ *j++ = '%';
+ break;
+ case 'H':
+ if (home) {
+ strcpy(j, home);
+ j += strlen(home);
+ }
+ break;
+ case 'L':
+ if (lcCompose) {
+ strcpy(j, lcCompose);
+ j += strlen(lcCompose);
+ }
+ break;
+ case 'S':
+ strcpy(j, dir);
+ j += strlen(dir);
+ break;
+ }
+ i++;
+ } else {
+ *j++ = *i++;
+ }
+ }
+ *j = '\0';
+ Xfree(lcCompose);
+ return ret;
+}
+
+#ifndef MB_LEN_MAX
+#define MB_LEN_MAX 6
+#endif
+
+static int
+get_mb_string (Xim im, char *buf, KeySym ks)
+{
+ XPointer from, to;
+ int from_len, to_len, len;
+ XPointer args[1];
+ XlcCharSet charset;
+ char local_buf[MB_LEN_MAX];
+ unsigned int ucs;
+ ucs = KeySymToUcs4(ks);
+
+ from = (XPointer) &ucs;
+ to = (XPointer) local_buf;
+ from_len = 1;
+ to_len = MB_LEN_MAX;
+ args[0] = (XPointer) &charset;
+ if (_XlcConvert(im->private.local.ucstoc_conv,
+ &from, &from_len, &to, &to_len, args, 1 ) != 0) {
+ return 0;
+ }
+
+ from = (XPointer) local_buf;
+ to = (XPointer) buf;
+ from_len = MB_LEN_MAX - to_len;
+ to_len = MB_LEN_MAX + 1;
+ args[0] = (XPointer) charset;
+ if (_XlcConvert(im->private.local.cstomb_conv,
+ &from, &from_len, &to, &to_len, args, 1 ) != 0) {
+ return 0;
+ }
+ len = MB_LEN_MAX + 1 - to_len;
+ buf[len] = '\0';
+ return len;
+}
+
+#define AllMask (ShiftMask | LockMask | ControlMask | Mod1Mask)
+#define LOCAL_WC_BUFSIZE 128
+#define LOCAL_UTF8_BUFSIZE 256
+#define SEQUENCE_MAX 10
+
+static int
+parseline(
+ FILE *fp,
+ Xim im,
+ char* tokenbuf)
+{
+ int token;
+ DTModifier modifier_mask;
+ DTModifier modifier;
+ DTModifier tmp;
+ KeySym keysym = NoSymbol;
+ DTIndex *top = &im->private.local.top;
+ DefTreeBase *b = &im->private.local.base;
+ DTIndex t;
+ DefTree *p = NULL;
+ Bool exclam, tilde;
+ KeySym rhs_keysym = 0;
+ char *rhs_string_mb;
+ int l;
+ int lastch = 0;
+ char local_mb_buf[MB_LEN_MAX+1];
+ wchar_t local_wc_buf[LOCAL_WC_BUFSIZE], *rhs_string_wc;
+ char local_utf8_buf[LOCAL_UTF8_BUFSIZE], *rhs_string_utf8;
+
+ struct DefBuffer {
+ DTModifier modifier_mask;
+ DTModifier modifier;
+ KeySym keysym;
+ };
+
+ struct DefBuffer buf[SEQUENCE_MAX];
+ int i, n;
+
+ do {
+ token = nexttoken(fp, tokenbuf, &lastch);
+ } while (token == ENDOFLINE);
+
+ if (token == ENDOFFILE) {
+ return(-1);
+ }
+
+ n = 0;
+ do {
+ if ((token == KEY) && (strcmp("include", tokenbuf) == 0)) {
+ char *filename;
+ FILE *infp;
+ token = nexttoken(fp, tokenbuf, &lastch);
+ if (token != KEY && token != STRING)
+ goto error;
+ if ((filename = TransFileName(im, tokenbuf)) == NULL)
+ goto error;
+ infp = _XFopenFile(filename, "r");
+ Xfree(filename);
+ if (infp == NULL)
+ goto error;
+ _XimParseStringFile(infp, im);
+ fclose(infp);
+ return (0);
+ } else if ((token == KEY) && (strcmp("None", tokenbuf) == 0)) {
+ modifier = 0;
+ modifier_mask = AllMask;
+ token = nexttoken(fp, tokenbuf, &lastch);
+ } else {
+ modifier_mask = modifier = 0;
+ exclam = False;
+ if (token == EXCLAM) {
+ exclam = True;
+ token = nexttoken(fp, tokenbuf, &lastch);
+ }
+ while (token == TILDE || token == KEY) {
+ tilde = False;
+ if (token == TILDE) {
+ tilde = True;
+ token = nexttoken(fp, tokenbuf, &lastch);
+ if (token != KEY)
+ goto error;
+ }
+ tmp = modmask(tokenbuf);
+ if (!tmp) {
+ goto error;
+ }
+ modifier_mask |= tmp;
+ if (tilde) {
+ modifier &= ~tmp;
+ } else {
+ modifier |= tmp;
+ }
+ token = nexttoken(fp, tokenbuf, &lastch);
+ }
+ if (exclam) {
+ modifier_mask = AllMask;
+ }
+ }
+
+ if (token != LESS) {
+ goto error;
+ }
+
+ token = nexttoken(fp, tokenbuf, &lastch);
+ if (token != KEY) {
+ goto error;
+ }
+
+ token = nexttoken(fp, tokenbuf, &lastch);
+ if (token != GREATER) {
+ goto error;
+ }
+
+ keysym = XStringToKeysym(tokenbuf);
+ if (keysym == NoSymbol) {
+ goto error;
+ }
+
+ buf[n].keysym = keysym;
+ buf[n].modifier = modifier;
+ buf[n].modifier_mask = modifier_mask;
+ n++;
+ if( n >= SEQUENCE_MAX )
+ goto error;
+ token = nexttoken(fp, tokenbuf, &lastch);
+ } while (token != COLON);
+
+ token = nexttoken(fp, tokenbuf, &lastch);
+ if (token == STRING) {
+ 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) {
+ goto error;
+ }
+ token = nexttoken(fp, tokenbuf, &lastch);
+ }
+ if (token != ENDOFLINE && token != ENDOFFILE) {
+ goto error;
+ }
+ } else if (token == KEY) {
+ rhs_keysym = XStringToKeysym(tokenbuf);
+ if (rhs_keysym == NoSymbol) {
+ goto error;
+ }
+ token = nexttoken(fp, tokenbuf, &lastch);
+ if (token != ENDOFLINE && token != ENDOFFILE) {
+ goto error;
+ }
+
+ l = get_mb_string(im, local_mb_buf, rhs_keysym);
+ 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 {
+ goto error;
+ }
+
+ l = _Xmbstowcs(local_wc_buf, rhs_string_mb, LOCAL_WC_BUFSIZE - 1);
+ if (l == LOCAL_WC_BUFSIZE - 1) {
+ local_wc_buf[l] = (wchar_t)'\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_utf8_buf[l] = '\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 (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 (t) {
+ p = &b->tree[t];
+ top = &p->succession;
+ } else {
+ 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 = 0;
+ p->next = *top;
+ p->mb = 0;
+ p->wc = 0;
+ p->utf8 = 0;
+ p->ks = NoSymbol;
+ *top = b->treeused;
+ top = &p->succession;
+ b->treeused++;
+ }
+ }
+
+ /* 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) {
+ token = nexttoken(fp, tokenbuf, &lastch);
+ }
+ return(0);
+}
+
+void
+_XimParseStringFile(
+ FILE *fp,
+ Xim im)
+{
+ char tb[8192];
+ char* tbp;
+ struct stat st;
+
+ if (fstat (fileno (fp), &st) != -1) {
+ unsigned long size = (unsigned long) st.st_size;
+ if (size <= sizeof tb) tbp = tb;
+ else tbp = malloc (size);
+
+ if (tbp != NULL) {
+ while (parseline(fp, im, tbp) >= 0) {}
+ if (tbp != tb) free (tbp);
+ }
+ }
+}
diff --git a/libX11/modules/im/ximcp/imLcSIc.c b/libX11/modules/im/ximcp/imLcSIc.c
index 095919309..3fce5fdc7 100644
--- a/libX11/modules/im/ximcp/imLcSIc.c
+++ b/libX11/modules/im/ximcp/imLcSIc.c
@@ -1,54 +1,54 @@
-/******************************************************************
-
- Copyright 1990, 1991, 1992, 1993, 1994 by FUJITSU LIMITED
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and
-that both that copyright notice and this permission notice appear
-in supporting documentation, and that the name of FUJITSU LIMITED
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-FUJITSU LIMITED makes no representations about the suitability of
-this software for any purpose.
-It is provided "as is" without express or implied warranty.
-
-FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
-USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
- Author: Takashi Fujiwara FUJITSU LIMITED
- fujiwara@a80.tech.yk.fujitsu.co.jp
-
-******************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/Xmd.h>
-#include <X11/Xutil.h>
-#include "Xlibint.h"
-#include "Xlcint.h"
-#include "Ximint.h"
-
-Public char *
-_XimLocalSetICValues(XIC xic, XIMArg *values)
-{
- XimDefICValues ic_values;
- Xic ic = (Xic)xic;
- char *name;
-
- _XimGetCurrentICValues(ic, &ic_values);
- name = _XimSetICValueData(ic, (XPointer)&ic_values,
- ic->private.local.ic_resources,
- ic->private.local.ic_num_resources,
- values, XIM_SETICVALUES, True);
- _XimSetCurrentICValues(ic, &ic_values);
- return(name);
-}
+/******************************************************************
+
+ Copyright 1990, 1991, 1992, 1993, 1994 by FUJITSU LIMITED
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and
+that both that copyright notice and this permission notice appear
+in supporting documentation, and that the name of FUJITSU LIMITED
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+FUJITSU LIMITED makes no representations about the suitability of
+this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+ Author: Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xmd.h>
+#include <X11/Xutil.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+
+Public char *
+_XimLocalSetICValues(XIC xic, XIMArg *values)
+{
+ XimDefICValues ic_values;
+ Xic ic = (Xic)xic;
+ char *name;
+
+ _XimGetCurrentICValues(ic, &ic_values);
+ name = _XimSetICValueData(ic, (XPointer)&ic_values,
+ ic->private.local.ic_resources,
+ ic->private.local.ic_num_resources,
+ values, XIM_SETICVALUES, True);
+ _XimSetCurrentICValues(ic, &ic_values);
+ return(name);
+}
diff --git a/libX11/modules/im/ximcp/imThaiFlt.c b/libX11/modules/im/ximcp/imThaiFlt.c
index d22b13038..12e3de265 100644
--- a/libX11/modules/im/ximcp/imThaiFlt.c
+++ b/libX11/modules/im/ximcp/imThaiFlt.c
@@ -1,1421 +1,1421 @@
-/***********************************************************
-
-Copyright 1993, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1993 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-/*
-**++
-** FACILITY:
-**
-** Xlib
-**
-** ABSTRACT:
-**
-** Thai specific functions.
-** Handles character classifications, composibility checking,
-** Input sequence check and other Thai specific requirements
-** according to WTT specification and DEC extensions.
-**
-** MODIFICATION HISTORY:
-**
-**/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/Xmd.h>
-#include <X11/keysym.h>
-#include <X11/Xutil.h>
-#include "Xlibint.h"
-#include "Xlcint.h"
-#include "Ximint.h"
-#include "XimThai.h"
-#include "XlcPubI.h"
-
-
-#define SPACE 32
-
-/* character classification table */
-#define TACTIS_CHARS 256
-Private
-char const tactis_chtype[TACTIS_CHARS] = {
- CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 0 - 7 */
- CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 8 - 15 */
- CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 16 - 23 */
- CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 24 - 31 */
- NON, NON, NON, NON, NON, NON, NON, NON, /* 32 - 39 */
- NON, NON, NON, NON, NON, NON, NON, NON, /* 40 - 47 */
- NON, NON, NON, NON, NON, NON, NON, NON, /* 48 - 55 */
- NON, NON, NON, NON, NON, NON, NON, NON, /* 56 - 63 */
- NON, NON, NON, NON, NON, NON, NON, NON, /* 64 - 71 */
- NON, NON, NON, NON, NON, NON, NON, NON, /* 72 - 79 */
- NON, NON, NON, NON, NON, NON, NON, NON, /* 80 - 87 */
- NON, NON, NON, NON, NON, NON, NON, NON, /* 88 - 95 */
- NON, NON, NON, NON, NON, NON, NON, NON, /* 96 - 103 */
- NON, NON, NON, NON, NON, NON, NON, NON, /* 104 - 111 */
- NON, NON, NON, NON, NON, NON, NON, NON, /* 112 - 119 */
- NON, NON, NON, NON, NON, NON, NON, CTRL, /* 120 - 127 */
- CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 128 - 135 */
- CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 136 - 143 */
- CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 144 - 151 */
- CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 152 - 159 */
- NON, CONS, CONS, CONS, CONS, CONS, CONS, CONS, /* 160 - 167 */
- CONS, CONS, CONS, CONS, CONS, CONS, CONS, CONS, /* 168 - 175 */
- CONS, CONS, CONS, CONS, CONS, CONS, CONS, CONS, /* 176 - 183 */
- CONS, CONS, CONS, CONS, CONS, CONS, CONS, CONS, /* 184 - 191 */
- CONS, CONS, CONS, CONS, FV3, CONS, FV3, CONS, /* 192 - 199 */
- CONS, CONS, CONS, CONS, CONS, CONS, CONS, NON, /* 200 - 207 */
- FV1, AV2, FV1, FV1, AV1, AV3, AV2, AV3, /* 208 - 215 */
- BV1, BV2, BD, NON, NON, NON, NON, NON, /* 216 - 223 */
- LV, LV, LV, LV, LV, FV2, NON, AD2, /* 224 - 231 */
- TONE, TONE, TONE, TONE, AD1, AD1, AD3, NON, /* 232 - 239 */
- NON, NON, NON, NON, NON, NON, NON, NON, /* 240 - 247 */
- NON, NON, NON, NON, NON, NON, NON, CTRL /* 248 - 255 */
-};
-
-/* Composibility checking tables */
-#define NC 0 /* NOT COMPOSIBLE - following char displays in next cell */
-#define CP 1 /* COMPOSIBLE - following char is displayed in the same cell
- as leading char, also implies ACCEPT */
-#define XC 3 /* Non-display */
-#define AC 4 /* ACCEPT - display the following char in the next cell */
-#define RJ 5 /* REJECT - discard that following char, ignore it */
-
-#define CH_CLASSES 17 /* 17 classes of chars */
-
-Private
-char const write_rules_lookup[CH_CLASSES][CH_CLASSES] = {
- /* Table 0: writing/outputing rules */
- /* row: leading char, column: following char */
-/* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
- {XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*CTRL*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*NON*/
- ,{XC, NC, NC, NC, NC, NC, NC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*LV*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*FV1*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*FV2*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*FV3*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, CP, NC, NC, NC, NC, NC}/*BV1*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, NC, NC, NC, NC, NC, NC}/*BV2*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*BD*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*TONE*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*AD1*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*AD2*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*AD3*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, CP, NC, NC, NC, NC, NC}/*AV1*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, NC, NC, NC, NC, NC, NC}/*AV2*/
- ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, NC, CP, NC, NC, NC, NC}/*AV3*/
-};
-
-Private
-char const wtt_isc1_lookup[CH_CLASSES][CH_CLASSES] = {
- /* Table 1: WTT default input sequence check rules */
- /* row: leading char, column: following char */
-/* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
- {XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*CTRL*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*NON*/
- ,{XC, AC, AC, AC, AC, AC, AC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*LV*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV1*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV2*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV3*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*BV1*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*BV2*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*BD*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*TONE*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD1*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD2*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD3*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*AV1*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*AV2*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, CP, RJ, RJ, RJ, RJ}/*AV3*/
-};
-
-Private
-char const wtt_isc2_lookup[CH_CLASSES][CH_CLASSES] = {
- /* Table 2: WTT strict input sequence check rules */
- /* row: leading char, column: following char */
-/* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
- {XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*CTRL*/
- ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*NON*/
- ,{XC, AC, AC, AC, AC, RJ, AC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
- ,{XC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*LV*/
- ,{XC, AC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV1*/
- ,{XC, AC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV2*/
- ,{XC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV3*/
- ,{XC, AC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*BV1*/
- ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*BV2*/
- ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*BD*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*TONE*/
- ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD1*/
- ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD2*/
- ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD3*/
- ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*AV1*/
- ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*AV2*/
- ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, RJ, CP, RJ, RJ, RJ, RJ}/*AV3*/
-};
-
-Private
-char const thaicat_isc_lookup[CH_CLASSES][CH_CLASSES] = {
- /* Table 3: Thaicat input sequence check rules */
- /* row: leading char, column: following char */
-/* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
- {XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*CTRL*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*NON*/
- ,{XC, AC, AC, AC, AC, AC, AC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*LV*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV1*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV2*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ} /*FV3*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*BV1*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*BV2*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*BD*/
- ,{XC, AC, AC, AC, AC, AC, AC, CP, CP, RJ, RJ, RJ, RJ, RJ, CP, CP, CP}/*TONE*/
- ,{XC, AC, AC, AC, AC, AC, AC, CP, RJ, RJ, RJ, RJ, RJ, RJ, CP, RJ, RJ}/*AD1*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, CP}/*AD2*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD3*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*AV1*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*AV2*/
- ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, CP, RJ, RJ, RJ, RJ}/*AV3*/
-};
-
-
-/* returns classification of a char */
-Private int
-THAI_chtype (unsigned char ch)
-{
- return tactis_chtype[ch];
-}
-
-#ifdef UNUSED
-/* returns the display level */
-Private int
-THAI_chlevel (unsigned char ch)
-{
- int chlevel;
-
- switch (tactis_chtype[ch])
- {
- case CTRL:
- chlevel = NON;
- break;
- case BV1:
- case BV2:
- case BD:
- chlevel = BELOW;
- break;
- case TONE:
- case AD1:
- case AD2:
- chlevel = TOP;
- break;
- case AV1:
- case AV2:
- case AV3:
- case AD3:
- chlevel = ABOVE;
- break;
- case NON:
- case CONS:
- case LV:
- case FV1:
- case FV2:
- case FV3:
- default: /* if tactis_chtype is invalid */
- chlevel = BASE;
- break;
- }
- return chlevel;
-}
-
-
-/* return True if char is non-spacing */
-Private Bool
-THAI_isdead (unsigned char ch)
-{
- return ((tactis_chtype[ch] == CTRL) || (tactis_chtype[ch] == BV1) ||
- (tactis_chtype[ch] == BV2) || (tactis_chtype[ch] == BD) ||
- (tactis_chtype[ch] == TONE) || (tactis_chtype[ch] == AD1) ||
- (tactis_chtype[ch] == AD2) || (tactis_chtype[ch] == AD3) ||
- (tactis_chtype[ch] == AV1) || (tactis_chtype[ch] == AV2) ||
- (tactis_chtype[ch] == AV3));
-}
-
-
-/* return True if char is consonant */
-Private Bool
-THAI_iscons (unsigned char ch)
-{
- return (tactis_chtype[ch] == CONS);
-}
-
-
-/* return True if char is vowel */
-Private Bool
-THAI_isvowel (unsigned char ch)
-{
- return ((tactis_chtype[ch] == LV) || (tactis_chtype[ch] == FV1) ||
- (tactis_chtype[ch] == FV2) || (tactis_chtype[ch] == FV3) ||
- (tactis_chtype[ch] == BV1) || (tactis_chtype[ch] == BV2) ||
- (tactis_chtype[ch] == AV1) || (tactis_chtype[ch] == AV2) ||
- (tactis_chtype[ch] == AV3));
-}
-
-
-/* return True if char is tonemark */
-Private Bool
-THAI_istone (unsigned char ch)
-{
- return (tactis_chtype[ch] == TONE);
-}
-#endif
-
-Private Bool
-THAI_iscomposible (
- unsigned char follow_ch,
- unsigned char lead_ch)
-{/* "Can follow_ch be put in the same display cell as lead_ch?" */
-
- return (write_rules_lookup[THAI_chtype(lead_ch)][THAI_chtype(follow_ch)]
- == CP);
-}
-
-Private Bool
-THAI_isaccepted (
- unsigned char follow_ch,
- unsigned char lead_ch,
- unsigned char mode)
-{
- Bool iskeyvalid; /* means "Can follow_ch be keyed in after lead_ch?" */
-
- switch (mode)
- {
- case WTT_ISC1:
- iskeyvalid =
- (wtt_isc1_lookup[THAI_chtype(lead_ch)][THAI_chtype(follow_ch)] != RJ);
- break;
- case WTT_ISC2:
- iskeyvalid =
- (wtt_isc2_lookup[THAI_chtype(lead_ch)][THAI_chtype(follow_ch)] != RJ);
- break;
- case THAICAT_ISC:
- iskeyvalid =
- (thaicat_isc_lookup[THAI_chtype(lead_ch)][THAI_chtype(follow_ch)] != RJ);
- break;
- default:
- iskeyvalid = True;
- break;
- }
-
- return iskeyvalid;
-}
-
-#ifdef UNUSED
-Private void
-THAI_apply_write_rules(
- unsigned char *instr,
- unsigned char *outstr,
- unsigned char insert_ch,
- int *num_insert_ch)
-{
-/*
-Input parameters:
- instr - input string
- insert_ch specify what char to be added when invalid composition is found
-Output parameters:
- outstr - output string after input string has been applied the rules
- num_insert_ch - number of insert_ch added to outstr.
-*/
- unsigned char *lead_ch = NULL, *follow_ch = NULL, *out_ch = NULL;
-
- *num_insert_ch = 0;
- lead_ch = follow_ch = instr;
- out_ch = outstr;
- if ((*lead_ch == '\0') || !(THAI_find_chtype(instr,DEAD)))
- { /* Empty string or can't find any non-spacing char*/
- strcpy((char *)outstr, (char *)instr);
- } else { /* String of length >= 1, keep looking */
- follow_ch++;
- if (THAI_isdead(*lead_ch)) { /* is first char non-spacing? */
- *out_ch++ = SPACE;
- (*num_insert_ch)++;
- }
- *out_ch++ = *lead_ch;
- while (*follow_ch != '\0') /* more char in string to check */
- {
- if (THAI_isdead(*follow_ch) &&
- !THAI_iscomposible(*follow_ch,*lead_ch))
- {
- *out_ch++ = SPACE;
- (*num_insert_ch)++;
- }
- *out_ch++ = *follow_ch;
- lead_ch = follow_ch;
- follow_ch++;
- }
- *out_ch = '\0';
- }
-}
-
-Private int
-THAI_find_chtype (
- unsigned char *instr,
- int chtype)
-{
-/*
-Input parameters:
- instr - input string
- chtype - type of character to look for
-Output parameters:
- function returns first position of character with matched chtype
- function returns -1 if it does not find.
-*/
- int i = 0, position = -1;
-
- switch (chtype)
- {
- case DEAD:
- for (i = 0; *instr != '\0' && THAI_isdead(*instr); i++, instr++)
- ;
- if (*instr != '\0') position = i;
- break;
- default:
- break;
- }
- return position;
-}
-
-
-Private int
-THAI_apply_scm(
- unsigned char *instr,
- unsigned char *outstr,
- unsigned char spec_ch,
- int num_sp,
- unsigned char insert_ch)
-{
- unsigned char *scan, *outch;
- int i, dead_count, found_count;
- Bool isconsecutive;
-
- scan = instr;
- outch = outstr;
- dead_count = found_count = 0;
- isconsecutive = False;
- while (*scan != '\0') {
- if (THAI_isdead(*scan))
- dead_count++; /* count number of non-spacing char */
- if (*scan == spec_ch)
- if (!isconsecutive)
- found_count++; /* count number consecutive spec char found */
- *outch++ = *scan++;
- if (found_count == num_sp) {
- for (i = 0; i < dead_count; i++)
- *outch++ = insert_ch;
- dead_count = found_count = 0;
- }
- }
- /* what to return? */
- return 0; /* probably not right but better than returning garbage */
-}
-
-
-/* The following functions are copied from XKeyBind.c */
-
-Private void ComputeMaskFromKeytrans();
-Private int IsCancelComposeKey(KeySym *symbol, XKeyEvent *event);
-Private void SetLed(Display *dpy, int num, int state);
-Private CARD8 FindKeyCode();
-
-
-/* The following functions are specific to this module */
-
-Private int XThaiTranslateKey();
-Private int XThaiTranslateKeySym();
-
-
-Private KeySym HexIMNormalKey(
- XicThaiPart *thai_part,
- KeySym symbol,
- XKeyEvent *event);
-Private KeySym HexIMFirstComposeKey(
- XicThaiPart *thai_part,
- KeySym symbol,
- XKeyEvent *event);
-Private KeySym HexIMSecondComposeKey(
- XicThaiPart *thai_part,
- KeySym symbol
- XKeyEvent *event);
-Private KeySym HexIMComposeSequence(KeySym ks1, KeySym ks2);
-Private void InitIscMode(Xic ic);
-Private Bool ThaiComposeConvert(
- Display *dpy,
- KeySym insym,
- KeySym *outsym, KeySym *lower, KeySym *upper);
-#endif
-
-/*
- * Definitions
- */
-
-#define BellVolume 0
-
-#define ucs2tis(wc) \
- (unsigned char) ( \
- (0<=(wc)&&(wc)<=0x7F) ? \
- (wc) : \
- ((0x0E01<=(wc)&&(wc)<=0x0E5F) ? ((wc)-0x0E00+0xA0) : 0))
-/* "c" is an unsigned char */
-#define tis2ucs(c) \
- ( \
- ((c)<=0x7F) ? \
- (wchar_t)(c) : \
- ((0x0A1<=(c)) ? ((wchar_t)(c)-0xA0+0x0E00) : 0))
-
-/*
- * Macros to save and recall last input character in XIC
- */
-#define IC_SavePreviousChar(ic,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.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) \
- (IC_RealGetPreviousChar(ic,2))
-#define IC_DeletePreviousChar(ic) \
- (IC_RealDeletePreviousChar(ic))
-
-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;
- unsigned char c;
-
- /* Use a safe value of position = 0 and stretch the range to desired
- * place, as XIM protocol is unclear here whether it could be negative
- */
- screc.position = 0;
- screc.direction = XIMBackwardChar;
- screc.operation = XIMStringConversionRetrieval;
- screc.factor = pos;
- screc.text = 0;
-
- (cb->callback)((XIC)ic, cb->client_data, (XPointer)&screc);
- if (!screc.text)
- return (unsigned char) b->mb[b->tree[(ic)->private.local.context].mb];
- if ((screc.text->feedback &&
- *screc.text->feedback == XIMStringConversionLeftEdge) ||
- screc.text->length < 1)
- {
- c = 0;
- } else {
- Xim im;
- XlcConv conv;
- int from_left;
- int to_left;
- char *from_buf;
- char *to_buf;
-
- im = (Xim) XIMOfIC((XIC)ic);
- if (screc.text->encoding_is_wchar) {
- conv = _XlcOpenConverter(im->core.lcd, XlcNWideChar,
- im->core.lcd, XlcNCharSet);
- from_buf = (char *) screc.text->string.wcs;
- from_left = screc.text->length * sizeof(wchar_t);
- } else {
- conv = _XlcOpenConverter(im->core.lcd, XlcNMultiByte,
- im->core.lcd, XlcNCharSet);
- from_buf = screc.text->string.mbs;
- from_left = screc.text->length;
- }
- to_buf = (char *)&c;
- to_left = 1;
-
- _XlcResetConverter(conv);
- if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
- (XPointer *)&to_buf, &to_left, NULL, 0) < 0)
- {
- c = (unsigned char) b->mb[b->tree[(ic)->private.local.context].mb];
- }
- _XlcCloseConverter(conv);
-
- XFree(screc.text->string.mbs);
- }
- XFree(screc.text);
- return c;
- } else {
- return (unsigned char) b->mb[b->tree[(ic)->private.local.context].mb];
- }
-}
-
-Private unsigned char
-IC_RealDeletePreviousChar(Xic ic)
-{
- XICCallback* cb = &ic->core.string_conversion_callback;
-
- if (cb && cb->callback) {
- XIMStringConversionCallbackStruct screc;
- unsigned char c;
-
- screc.position = 0;
- screc.direction = XIMBackwardChar;
- screc.operation = XIMStringConversionSubstitution;
- screc.factor = 1;
- screc.text = 0;
-
- (cb->callback)((XIC)ic, cb->client_data, (XPointer)&screc);
- if (!screc.text) { return 0; }
- if ((screc.text->feedback &&
- *screc.text->feedback == XIMStringConversionLeftEdge) ||
- screc.text->length < 1)
- {
- c = 0;
- } else {
- if (screc.text->encoding_is_wchar) {
- c = ucs2tis(screc.text->string.wcs[0]);
- XFree(screc.text->string.wcs);
- } else {
- c = screc.text->string.mbs[0];
- XFree(screc.text->string.mbs);
- }
- }
- XFree(screc.text);
- return c;
- } else {
- return 0;
- }
-}
-/*
- * Input sequence check mode in XIC
- */
-#define IC_IscMode(ic) ((ic)->private.local.thai.input_mode)
-
-/*
- * Max. size of string handled by the two String Lookup functions.
- */
-#define STR_LKUP_BUF_SIZE 256
-
-/*
- * Size of buffer to contain previous locale name.
- */
-#define SAV_LOCALE_NAME_SIZE 256
-
-/*
- * Size of buffer to contain the IM modifier.
- */
-#define MAXTHAIIMMODLEN 20
-
-#define AllMods (ShiftMask|LockMask|ControlMask| \
- Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
-
-
-#define IsISOControlKey(ks) ((ks) >= XK_2 && (ks) <= XK_8)
-
-#define IsValidControlKey(ks) (((((ks)>=XK_A && (ks)<=XK_asciitilde) || \
- (ks)==XK_space || (ks)==XK_Delete) && \
- ((ks)!=0)))
-
-#define COMPOSE_LED 2
-
-#ifdef UNUSED
-typedef KeySym (*StateProc)(
- XicThaiPart *thai_part,
- KeySym symbol,
- XKeyEvent *event);
-
-
-/*
- * macros to classify XKeyEvent state field
- */
-
-#define IsShift(state) (((state) & ShiftMask) != 0)
-#define IsLock(state) (((state) & LockMask) != 0)
-#define IsControl(state) (((state) & ControlMask) != 0)
-#define IsMod1(state) (((state) & Mod1Mask) != 0)
-#define IsMod2(state) (((state) & Mod2Mask) != 0)
-#define IsMod3(state) (((state) & Mod3Mask) != 0)
-#define IsMod4(state) (((state) & Mod4Mask) != 0)
-#define IsMod5(state) (((state) & Mod5Mask) != 0)
-
-/*
- * key starts Thai compose sequence (Hex input method) if :
- */
-
-#define IsComposeKey(ks, event) \
- (( ks==XK_Alt_L && \
- IsControl((event)->state) && \
- !IsShift((event)->state)) \
- ? True : False)
-
-
-/*
- * State handler to implement the Thai hex input method.
- */
-
-Private int const nstate_handlers = 3;
-Private StateProc state_handler[] = {
- HexIMNormalKey,
- HexIMFirstComposeKey,
- HexIMSecondComposeKey
-};
-
-
-/*
- * Table for 'Thai Compose' character input.
- * The current implementation uses latin-1 keysyms.
- */
-struct _XMapThaiKey {
- KeySym from;
- KeySym to;
-};
-
-Private struct _XMapThaiKey const ThaiComposeTable[] = {
- { /* 0xa4 */ XK_currency, /* 0xa5 */ XK_yen },
- { /* 0xa2 */ XK_cent, /* 0xa3 */ XK_sterling },
- { /* 0xe6 */ XK_ae, /* 0xef */ XK_idiaeresis },
- { /* 0xd3 */ XK_Oacute, /* 0xee */ XK_icircumflex },
- { /* 0xb9 */ XK_onesuperior, /* 0xfa */ XK_uacute },
- { /* 0xd2 */ XK_Ograve, /* 0xe5 */ XK_aring },
- { /* 0xbc */ XK_onequarter, /* 0xfb */ XK_ucircumflex },
- { XK_VoidSymbol, XK_VoidSymbol }
-};
-
-struct _XKeytrans {
- struct _XKeytrans *next;/* next on list */
- char *string; /* string to return when the time comes */
- int len; /* length of string (since NULL is legit)*/
- KeySym key; /* keysym rebound */
- unsigned int state; /* modifier state */
- KeySym *modifiers; /* modifier keysyms you want */
- int mlen; /* length of modifier list */
-};
-
-
-/* Convert keysym to 'Thai Compose' keysym */
-/* The current implementation use latin-1 keysyms */
-Private Bool
-ThaiComposeConvert(
- Display *dpy,
- KeySym insym,
- KeySym *outsym, KeySym *lower, KeySym *upper)
-{
- struct _XMapThaiKey const *table_entry = ThaiComposeTable;
-
- while (table_entry->from != XK_VoidSymbol) {
- if (table_entry->from == insym) {
- *outsym = table_entry->to;
- *lower = *outsym;
- *upper = *outsym;
- return True;
- }
- table_entry++;
- }
- return False;
-}
-
-Private int
-XThaiTranslateKey(
- register Display *dpy,
- KeyCode keycode,
- register unsigned int modifiers,
- unsigned int *modifiers_return,
- KeySym *keysym_return,
- KeySym *lsym_return,
- KeySym *usym_return)
-{
- int per;
- register KeySym *syms;
- KeySym sym = 0, lsym = 0, usym = 0;
-
- if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
- return 0;
- *modifiers_return = (ShiftMask|LockMask) | dpy->mode_switch;
- if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
- {
- *keysym_return = NoSymbol;
- return 1;
- }
- per = dpy->keysyms_per_keycode;
- syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
- while ((per > 2) && (syms[per - 1] == NoSymbol))
- per--;
- if ((per > 2) && (modifiers & dpy->mode_switch)) {
- syms += 2;
- per -= 2;
- }
- if (!(modifiers & ShiftMask) &&
- (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) {
- if ((per == 1) || (syms[1] == NoSymbol))
- XConvertCase(syms[0], keysym_return, &usym);
- else {
- XConvertCase(syms[0], &lsym, &usym);
- *keysym_return = syms[0];
- }
- } else if (!(modifiers & LockMask) ||
- (dpy->lock_meaning != XK_Caps_Lock)) {
- if ((per == 1) || ((usym = syms[1]) == NoSymbol))
- XConvertCase(syms[0], &lsym, &usym);
- *keysym_return = usym;
- } else {
- if ((per == 1) || ((sym = syms[1]) == NoSymbol))
- sym = syms[0];
- XConvertCase(sym, &lsym, &usym);
- if (!(modifiers & ShiftMask) && (sym != syms[0]) &&
- ((sym != usym) || (lsym == usym)))
- XConvertCase(syms[0], &lsym, &usym);
- *keysym_return = usym;
- }
- /*
- * ThaiCat keyboard support :
- * When the Shift and Thai keys are hold for some keys a 'Thai Compose'
- * character code is generated which is different from column 3 and
- * 4 of the keymap.
- * Since we don't know whether ThaiCat keyboard or WTT keyboard is
- * in use, the same mapping is done for all Thai input.
- * We just arbitary choose to use column 3 keysyms as the indices of
- * this mapping.
- * When the control key is also hold, this mapping has no effect.
- */
- if ((modifiers & Mod1Mask) &&
- (modifiers & ShiftMask) &&
- !(modifiers & ControlMask)) {
- if (ThaiComposeConvert(dpy, syms[0], &sym, &lsym, &usym))
- *keysym_return = sym;
- }
-
- if (*keysym_return == XK_VoidSymbol)
- *keysym_return = NoSymbol;
- *lsym_return = lsym;
- *usym_return = usym;
- return 1;
-}
-
-/*
- * XThaiTranslateKeySym
- *
- * Translate KeySym to TACTIS code output.
- * The current implementation uses ISO latin-1 keysym.
- * Should be changed to TACTIS keysyms when they are defined by the
- * standard.
- */
-Private int
-XThaiTranslateKeySym(
- Display *dpy,
- register KeySym symbol,
- register KeySym lsym,
- register KeySym usym,
- unsigned int modifiers,
- unsigned char *buffer,
- int nbytes)
-{
- KeySym ckey = 0;
- register struct _XKeytrans *p;
- int length;
- unsigned long hiBytes;
- register unsigned char c;
-
- /*
- * initialize length = 1 ;
- */
- length = 1;
-
- if (!symbol)
- return 0;
- /* see if symbol rebound, if so, return that string. */
- for (p = dpy->key_bindings; p; p = p->next) {
- if (((modifiers & AllMods) == p->state) && (symbol == p->key)) {
- length = p->len;
- if (length > nbytes) length = nbytes;
- memcpy (buffer, p->string, length);
- return length;
- }
- }
- /* try to convert to TACTIS, handling control */
- hiBytes = symbol >> 8;
- if (!(nbytes &&
- ((hiBytes == 0) ||
- ((hiBytes == 0xFF) &&
- (((symbol >= XK_BackSpace) && (symbol <= XK_Clear)) ||
- (symbol == XK_Return) ||
- (symbol == XK_Escape) ||
- (symbol == XK_KP_Space) ||
- (symbol == XK_KP_Tab) ||
- (symbol == XK_KP_Enter) ||
- ((symbol >= XK_KP_Multiply) && (symbol <= XK_KP_9)) ||
- (symbol == XK_KP_Equal) ||
- (symbol == XK_Scroll_Lock) ||
-#ifdef DXK_PRIVATE /* DEC private keysyms */
- (symbol == DXK_Remove) ||
-#endif
- (symbol == NoSymbol) ||
- (symbol == XK_Delete))))))
- return 0;
-
- /* if X keysym, convert to ascii by grabbing low 7 bits */
- if (symbol == XK_KP_Space)
- c = XK_space & 0x7F; /* patch encoding botch */
-/* not for Thai
- else if (symbol == XK_hyphen)
- c = XK_minus & 0xFF; */ /* map to equiv character */
- else if (hiBytes == 0xFF)
- c = symbol & 0x7F;
- else
- c = symbol & 0xFF;
- /* only apply Control key if it makes sense, else ignore it */
- if (modifiers & ControlMask) {
- if (!(IsKeypadKey(lsym) || lsym==XK_Return || lsym==XK_Tab)) {
- if (IsISOControlKey(lsym)) ckey = lsym;
- else if (IsISOControlKey(usym)) ckey = usym;
- else if (lsym == XK_question) ckey = lsym;
- else if (usym == XK_question) ckey = usym;
- else if (IsValidControlKey(lsym)) ckey = lsym;
- else if (IsValidControlKey(usym)) ckey = usym;
- else length = 0;
-
- if (length != 0) {
- if (ckey == XK_2) c = '\000';
- else if (ckey >= XK_3 && ckey <= XK_7)
- c = (char)(ckey-('3'-'\033'));
- else if (ckey == XK_8) c = '\177';
- else if (ckey == XK_Delete) c = '\030';
- else if (ckey == XK_question) c = '\037';
- else if (ckey == XK_quoteleft) c = '\036'; /* KLee 1/24/91 */
- else c = (char)(ckey & 0x1f);
- }
- }
- }
- /*
- * ThaiCat has a key that generates two TACTIS codes D1 & E9.
- * It is represented by the latin-1 keysym XK_thorn (0xfe).
- * If c is XK_thorn, this key is pressed and it is converted to
- * 0xd1 0xe9.
- */
- if (c == XK_thorn) {
- buffer[0] = 0xd1;
- buffer[1] = 0xe9;
- buffer[2] = '\0';
- return 2;
- }
- else {
- /* Normal case */
- buffer[0] = c;
- buffer[1] = '\0';
- return 1;
- }
-}
-
-/*
- * given a KeySym, returns the first keycode containing it, if any.
- */
-Private CARD8
-FindKeyCode(
- register Display *dpy,
- register KeySym code)
-{
-
- register KeySym *kmax = dpy->keysyms +
- (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode;
- register KeySym *k = dpy->keysyms;
- while (k < kmax) {
- if (*k == code)
- return (((k - dpy->keysyms) / dpy->keysyms_per_keycode) +
- dpy->min_keycode);
- k += 1;
- }
- return 0;
-}
-
-/*
- * given a list of modifiers, computes the mask necessary for later matching.
- * This routine must lookup the key in the Keymap and then search to see
- * what modifier it is bound to, if any. Sets the AnyModifier bit if it
- * can't map some keysym to a modifier.
- */
-Private void
-ComputeMaskFromKeytrans(
- Display *dpy,
- register struct _XKeytrans *p)
-{
- register int i;
- register CARD8 code;
- register XModifierKeymap *m = dpy->modifiermap;
-
- p->state = AnyModifier;
- for (i = 0; i < p->mlen; i++) {
- /* if not found, then not on current keyboard */
- if ((code = FindKeyCode(dpy, p->modifiers[i])) == 0)
- return;
- /* code is now the keycode for the modifier you want */
- {
- register int j = m->max_keypermod<<3;
-
- while ((--j >= 0) && (code != m->modifiermap[j]))
- ;
- if (j < 0)
- return;
- p->state |= (1<<(j/m->max_keypermod));
- }
- }
- p->state &= AllMods;
-}
-
-/************************************************************************
- *
- *
- * Compose handling routines - compose handlers 0,1,2
- *
- *
- ************************************************************************/
-
-#define NORMAL_KEY_STATE 0
-#define FIRST_COMPOSE_KEY_STATE 1
-#define SECOND_COMPOSE_KEY_STATE 2
-
-Private
-KeySym HexIMNormalKey(
- XicThaiPart *thai_part,
- KeySym symbol,
- XKeyEvent *event)
-{
- if (IsComposeKey (symbol, event)) /* start compose sequence */
- {
- SetLed (event->display,COMPOSE_LED, LedModeOn);
- thai_part->comp_state = FIRST_COMPOSE_KEY_STATE;
- return NoSymbol;
- }
- return symbol;
-}
-
-
-Private
-KeySym HexIMFirstComposeKey(
- XicThaiPart *thai_part,
- KeySym symbol,
- XKeyEvent *event)
-{
- if (IsModifierKey (symbol)) return symbol; /* ignore shift etc. */
- if (IsCancelComposeKey (&symbol, event)) /* cancel sequence */
- {
- SetLed (event->display,COMPOSE_LED, LedModeOff);
- thai_part->comp_state = NORMAL_KEY_STATE;
- return symbol;
- }
- if (IsComposeKey (symbol, event)) /* restart sequence ?? */
- {
- return NoSymbol; /* no state change necessary */
- }
-
- thai_part->keysym = symbol; /* save key pressed */
- thai_part->comp_state = SECOND_COMPOSE_KEY_STATE;
- return NoSymbol;
-}
-
-Private
-KeySym HexIMSecondComposeKey(
- XicThaiPart *thai_part,
- KeySym symbol,
- XKeyEvent *event)
-{
- if (IsModifierKey (symbol)) return symbol; /* ignore shift etc. */
- if (IsComposeKey (symbol, event)) /* restart sequence ? */
- {
- thai_part->comp_state =FIRST_COMPOSE_KEY_STATE;
- return NoSymbol;
- }
- SetLed (event->display,COMPOSE_LED, LedModeOff);
- if (IsCancelComposeKey (&symbol, event)) /* cancel sequence ? */
- {
- thai_part->comp_state = NORMAL_KEY_STATE;
- return symbol;
- }
-
- if ((symbol = HexIMComposeSequence (thai_part->keysym, symbol))
- ==NoSymbol)
- { /* invalid compose sequence */
- XBell(event->display, BellVolume);
- }
- thai_part->comp_state = NORMAL_KEY_STATE; /* reset to normal state */
- return symbol;
-}
-
-
-/*
- * Interprets two keysyms entered as hex digits and return the Thai keysym
- * correspond to the TACTIS code formed.
- * The current implementation of this routine returns ISO Latin Keysyms.
- */
-
-Private
-KeySym HexIMComposeSequence(KeySym ks1, KeySym ks2)
-{
-int hi_digit;
-int lo_digit;
-int tactis_code;
-
- if ((ks1 >= XK_0) && (ks1 <= XK_9))
- hi_digit = ks1 - XK_0;
- else if ((ks1 >= XK_A) && (ks1 <= XK_F))
- hi_digit = ks1 - XK_A + 10;
- else if ((ks1 >= XK_a) && (ks1 <= XK_f))
- hi_digit = ks1 - XK_a + 10;
- else /* out of range */
- return NoSymbol;
-
- if ((ks2 >= XK_0) && (ks2 <= XK_9))
- lo_digit = ks2 - XK_0;
- else if ((ks2 >= XK_A) && (ks2 <= XK_F))
- lo_digit = ks2 - XK_A + 10;
- else if ((ks2 >= XK_a) && (ks2 <= XK_f))
- lo_digit = ks2 - XK_a + 10;
- else /* out of range */
- return NoSymbol;
-
- tactis_code = hi_digit * 0x10 + lo_digit ;
-
- return (KeySym)tactis_code;
-
-}
-
-/*
- * routine determines
- * 1) whether key event should cancel a compose sequence
- * 2) whether cancelling key event should be processed or ignored
- */
-
-Private
-int IsCancelComposeKey(
- KeySym *symbol,
- XKeyEvent *event)
-{
- if (*symbol==XK_Delete && !IsControl(event->state) &&
- !IsMod1(event->state)) {
- *symbol=NoSymbol; /* cancel compose sequence, and ignore key */
- return True;
- }
- if (IsComposeKey(*symbol, event)) return False;
- return (
- IsControl (event->state) ||
- IsMod1(event->state) ||
- IsKeypadKey (*symbol) ||
- IsFunctionKey (*symbol) ||
- IsMiscFunctionKey (*symbol) ||
-#ifdef DXK_PRIVATE /* DEC private keysyms */
- *symbol == DXK_Remove ||
-#endif
- IsPFKey (*symbol) ||
- IsCursorKey (*symbol) ||
- (*symbol >= XK_Tab && *symbol < XK_Multi_key)
- ? True : False); /* cancel compose sequence and pass */
- /* cancelling key through */
-}
-
-
-/*
- * set specified keyboard LED on or off
- */
-
-Private
-void SetLed(
- Display *dpy,
- int num,
- int state)
-{
- XKeyboardControl led_control;
-
- led_control.led_mode = state;
- led_control.led = num;
- XChangeKeyboardControl (dpy, KBLed | KBLedMode, &led_control);
-}
-#endif
-
-/*
- * Initialize ISC mode from im modifier
- */
-Private void InitIscMode(Xic ic)
-{
- Xim im;
- char *im_modifier_name;
-
- /* If already defined, just return */
-
- if (IC_IscMode(ic)) return;
-
- /* Get IM modifier */
-
- im = (Xim) XIMOfIC((XIC)ic);
- im_modifier_name = im->core.im_name;
-
- /* Match with predefined value, default is Basic Check */
-
- if (!strncmp(im_modifier_name,"BasicCheck",MAXTHAIIMMODLEN+1))
- IC_IscMode(ic) = WTT_ISC1;
- else if (!strncmp(im_modifier_name,"Strict",MAXTHAIIMMODLEN+1))
- IC_IscMode(ic) = WTT_ISC2;
- else if (!strncmp(im_modifier_name,"Thaicat",MAXTHAIIMMODLEN+1))
- IC_IscMode(ic) = THAICAT_ISC;
- else if (!strncmp(im_modifier_name,"Passthrough",MAXTHAIIMMODLEN+1))
- IC_IscMode(ic) = NOISC;
- else
- IC_IscMode(ic) = WTT_ISC1;
-
- return;
-}
-
-/*
- * Helper functions for _XimThaiFilter()
- */
-Private Bool
-ThaiFltAcceptInput(Xic ic, unsigned char new_char, KeySym symbol)
-{
- 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))
- b->tree[ic->private.local.composed].keysym = symbol;
- else
- b->tree[ic->private.local.composed].keysym = NoSymbol;
-
- return True;
-}
-
-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;
- 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';
-
- b->tree[ic->private.local.composed].keysym = NoSymbol;
-
- return True;
-}
-
-Private Bool
-ThaiFltReplaceInput(Xic ic, unsigned char new_char, KeySym symbol)
-{
- DefTreeBase *b = &ic->private.local.base;
- if (!IC_DeletePreviousChar(ic)) return False;
- 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))
- b->tree[ic->private.local.composed].keysym = symbol;
- else
- b->tree[ic->private.local.composed].keysym = NoSymbol;
-
- return True;
-}
-
-Private unsigned
-NumLockMask(Display *d)
-{
- int i;
- XModifierKeymap *map;
- KeyCode numlock_keycode = XKeysymToKeycode (d, XK_Num_Lock);
- if (numlock_keycode == NoSymbol)
- return 0;
-
- map = XGetModifierMapping (d);
- if (!map)
- return 0;
-
- for (i = 0; i < 8; i++) {
- if (map->modifiermap[map->max_keypermod * i] == numlock_keycode) {
- XFreeModifiermap(map);
- return 1 << i;
- }
- }
- XFreeModifiermap(map);
- return 0;
-}
-
-/*
- * Filter function for TACTIS
- */
-Bool
-_XimThaiFilter(Display *d, Window w, XEvent *ev, XPointer client_data)
-{
- Xic ic = (Xic)client_data;
- KeySym symbol;
- int isc_mode; /* Thai Input Sequence Check mode */
- unsigned char previous_char; /* Last inputted Thai char */
- unsigned char new_char;
-#ifdef UNUSED
- unsigned int modifiers;
- KeySym lsym,usym;
- int state;
- XicThaiPart *thai_part;
- char buf[10];
-#endif
- wchar_t wbuf[10];
- Bool isReject;
- DefTreeBase *b = &ic->private.local.base;
-
- if ((ev->type != KeyPress)
- || (ev->xkey.keycode == 0))
- return False;
-
- if (!IC_IscMode(ic)) InitIscMode(ic);
-
- XwcLookupString((XIC)ic, &ev->xkey, wbuf, sizeof(wbuf) / sizeof(wbuf[0]),
- &symbol, NULL);
-
- if ((ev->xkey.state & (AllMods & ~(ShiftMask|LockMask|NumLockMask(d)))) ||
- ((symbol >> 8 == 0xFF) &&
- ((XK_BackSpace <= symbol && symbol <= XK_Clear) ||
- (symbol == XK_Return) ||
- (symbol == XK_Pause) ||
- (symbol == XK_Scroll_Lock) ||
- (symbol == XK_Sys_Req) ||
- (symbol == XK_Escape) ||
- (symbol == XK_Delete) ||
- IsCursorKey(symbol) ||
- IsKeypadKey(symbol) ||
- IsMiscFunctionKey(symbol) ||
- IsFunctionKey(symbol))))
- {
- IC_ClearPreviousChar(ic);
- return False;
- }
- if (((symbol >> 8 == 0xFF) &&
- IsModifierKey(symbol)) ||
-#ifdef XK_XKB_KEYS
- ((symbol >> 8 == 0xFE) &&
- (XK_ISO_Lock <= symbol && symbol <= XK_ISO_Last_Group_Lock)) ||
-#endif
- (symbol == NoSymbol))
- {
- return False;
- }
-#ifdef UNUSED
- if (! XThaiTranslateKey(ev->xkey.display, ev->xkey.keycode, ev->xkey.state,
- &modifiers, &symbol, &lsym, &usym))
- return False;
-
- /*
- * Hex input method processing
- */
-
- thai_part = &ic->private.local.thai;
- state = thai_part->comp_state;
- if (state >= 0 && state < nstate_handlers) /* call handler for state */
- {
- symbol = (* state_handler[state])(thai_part, symbol, (XKeyEvent *)ev);
- }
-
- /*
- * Translate KeySym into mb.
- */
- count = XThaiTranslateKeySym(ev->xkey.display, symbol, lsym,
- usym, ev->xkey.state, buf, 10);
-
- if (!symbol && !count)
- return True;
-
- /* Return symbol if cannot convert to character */
- if (!count)
- return False;
-#endif
-
- /*
- * Thai Input sequence check
- */
- isc_mode = IC_IscMode(ic);
- if (!(previous_char = IC_GetPreviousChar(ic))) previous_char = ' ';
- new_char = ucs2tis(wbuf[0]);
- isReject = True;
- if (THAI_isaccepted(new_char, previous_char, isc_mode)) {
- ThaiFltAcceptInput(ic, new_char, symbol);
- isReject = False;
- } else {
- unsigned char context_char;
-
- context_char = IC_GetContextChar(ic);
- if (context_char) {
- if (THAI_iscomposible(new_char, context_char)) {
- if (THAI_iscomposible(previous_char, new_char)) {
- isReject = !ThaiFltReorderInput(ic, previous_char, new_char);
- } else if (THAI_iscomposible(previous_char, context_char)) {
- isReject = !ThaiFltReplaceInput(ic, new_char, symbol);
- } else if (THAI_chtype(previous_char) == FV1
- && THAI_chtype(new_char) == TONE) {
- isReject = !ThaiFltReorderInput(ic, previous_char, new_char);
- }
- } else if (THAI_isaccepted(new_char, context_char, isc_mode)) {
- isReject = !ThaiFltReplaceInput(ic, new_char, symbol);
- }
- }
- }
- if (isReject) {
- /* reject character */
- XBell(ev->xkey.display, BellVolume);
- return True;
- }
-
- _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, &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)
- */
- IC_SavePreviousChar(ic, new_char);
-
- ev->xkey.keycode = 0;
- XPutBackEvent(d, ev);
- return True;
-}
+/***********************************************************
+
+Copyright 1993, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1993 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+**++
+** FACILITY:
+**
+** Xlib
+**
+** ABSTRACT:
+**
+** Thai specific functions.
+** Handles character classifications, composibility checking,
+** Input sequence check and other Thai specific requirements
+** according to WTT specification and DEC extensions.
+**
+** MODIFICATION HISTORY:
+**
+**/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xmd.h>
+#include <X11/keysym.h>
+#include <X11/Xutil.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+#include "XimThai.h"
+#include "XlcPubI.h"
+
+
+#define SPACE 32
+
+/* character classification table */
+#define TACTIS_CHARS 256
+Private
+char const tactis_chtype[TACTIS_CHARS] = {
+ CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 0 - 7 */
+ CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 8 - 15 */
+ CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 16 - 23 */
+ CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 24 - 31 */
+ NON, NON, NON, NON, NON, NON, NON, NON, /* 32 - 39 */
+ NON, NON, NON, NON, NON, NON, NON, NON, /* 40 - 47 */
+ NON, NON, NON, NON, NON, NON, NON, NON, /* 48 - 55 */
+ NON, NON, NON, NON, NON, NON, NON, NON, /* 56 - 63 */
+ NON, NON, NON, NON, NON, NON, NON, NON, /* 64 - 71 */
+ NON, NON, NON, NON, NON, NON, NON, NON, /* 72 - 79 */
+ NON, NON, NON, NON, NON, NON, NON, NON, /* 80 - 87 */
+ NON, NON, NON, NON, NON, NON, NON, NON, /* 88 - 95 */
+ NON, NON, NON, NON, NON, NON, NON, NON, /* 96 - 103 */
+ NON, NON, NON, NON, NON, NON, NON, NON, /* 104 - 111 */
+ NON, NON, NON, NON, NON, NON, NON, NON, /* 112 - 119 */
+ NON, NON, NON, NON, NON, NON, NON, CTRL, /* 120 - 127 */
+ CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 128 - 135 */
+ CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 136 - 143 */
+ CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 144 - 151 */
+ CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 152 - 159 */
+ NON, CONS, CONS, CONS, CONS, CONS, CONS, CONS, /* 160 - 167 */
+ CONS, CONS, CONS, CONS, CONS, CONS, CONS, CONS, /* 168 - 175 */
+ CONS, CONS, CONS, CONS, CONS, CONS, CONS, CONS, /* 176 - 183 */
+ CONS, CONS, CONS, CONS, CONS, CONS, CONS, CONS, /* 184 - 191 */
+ CONS, CONS, CONS, CONS, FV3, CONS, FV3, CONS, /* 192 - 199 */
+ CONS, CONS, CONS, CONS, CONS, CONS, CONS, NON, /* 200 - 207 */
+ FV1, AV2, FV1, FV1, AV1, AV3, AV2, AV3, /* 208 - 215 */
+ BV1, BV2, BD, NON, NON, NON, NON, NON, /* 216 - 223 */
+ LV, LV, LV, LV, LV, FV2, NON, AD2, /* 224 - 231 */
+ TONE, TONE, TONE, TONE, AD1, AD1, AD3, NON, /* 232 - 239 */
+ NON, NON, NON, NON, NON, NON, NON, NON, /* 240 - 247 */
+ NON, NON, NON, NON, NON, NON, NON, CTRL /* 248 - 255 */
+};
+
+/* Composibility checking tables */
+#define NC 0 /* NOT COMPOSIBLE - following char displays in next cell */
+#define CP 1 /* COMPOSIBLE - following char is displayed in the same cell
+ as leading char, also implies ACCEPT */
+#define XC 3 /* Non-display */
+#define AC 4 /* ACCEPT - display the following char in the next cell */
+#define RJ 5 /* REJECT - discard that following char, ignore it */
+
+#define CH_CLASSES 17 /* 17 classes of chars */
+
+Private
+char const write_rules_lookup[CH_CLASSES][CH_CLASSES] = {
+ /* Table 0: writing/outputing rules */
+ /* row: leading char, column: following char */
+/* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
+ {XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*CTRL*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*NON*/
+ ,{XC, NC, NC, NC, NC, NC, NC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*LV*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*FV1*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*FV2*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*FV3*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, CP, NC, NC, NC, NC, NC}/*BV1*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, NC, NC, NC, NC, NC, NC}/*BV2*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*BD*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*TONE*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*AD1*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*AD2*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*AD3*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, CP, NC, NC, NC, NC, NC}/*AV1*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, NC, NC, NC, NC, NC, NC}/*AV2*/
+ ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, NC, CP, NC, NC, NC, NC}/*AV3*/
+};
+
+Private
+char const wtt_isc1_lookup[CH_CLASSES][CH_CLASSES] = {
+ /* Table 1: WTT default input sequence check rules */
+ /* row: leading char, column: following char */
+/* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
+ {XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*CTRL*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*NON*/
+ ,{XC, AC, AC, AC, AC, AC, AC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*LV*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV1*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV2*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV3*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*BV1*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*BV2*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*BD*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*TONE*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD1*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD2*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD3*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*AV1*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*AV2*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, CP, RJ, RJ, RJ, RJ}/*AV3*/
+};
+
+Private
+char const wtt_isc2_lookup[CH_CLASSES][CH_CLASSES] = {
+ /* Table 2: WTT strict input sequence check rules */
+ /* row: leading char, column: following char */
+/* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
+ {XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*CTRL*/
+ ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*NON*/
+ ,{XC, AC, AC, AC, AC, RJ, AC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
+ ,{XC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*LV*/
+ ,{XC, AC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV1*/
+ ,{XC, AC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV2*/
+ ,{XC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV3*/
+ ,{XC, AC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*BV1*/
+ ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*BV2*/
+ ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*BD*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*TONE*/
+ ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD1*/
+ ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD2*/
+ ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD3*/
+ ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*AV1*/
+ ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*AV2*/
+ ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, RJ, CP, RJ, RJ, RJ, RJ}/*AV3*/
+};
+
+Private
+char const thaicat_isc_lookup[CH_CLASSES][CH_CLASSES] = {
+ /* Table 3: Thaicat input sequence check rules */
+ /* row: leading char, column: following char */
+/* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
+ {XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*CTRL*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*NON*/
+ ,{XC, AC, AC, AC, AC, AC, AC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*LV*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV1*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV2*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ} /*FV3*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*BV1*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*BV2*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*BD*/
+ ,{XC, AC, AC, AC, AC, AC, AC, CP, CP, RJ, RJ, RJ, RJ, RJ, CP, CP, CP}/*TONE*/
+ ,{XC, AC, AC, AC, AC, AC, AC, CP, RJ, RJ, RJ, RJ, RJ, RJ, CP, RJ, RJ}/*AD1*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, CP}/*AD2*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD3*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*AV1*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*AV2*/
+ ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, CP, RJ, RJ, RJ, RJ}/*AV3*/
+};
+
+
+/* returns classification of a char */
+Private int
+THAI_chtype (unsigned char ch)
+{
+ return tactis_chtype[ch];
+}
+
+#ifdef UNUSED
+/* returns the display level */
+Private int
+THAI_chlevel (unsigned char ch)
+{
+ int chlevel;
+
+ switch (tactis_chtype[ch])
+ {
+ case CTRL:
+ chlevel = NON;
+ break;
+ case BV1:
+ case BV2:
+ case BD:
+ chlevel = BELOW;
+ break;
+ case TONE:
+ case AD1:
+ case AD2:
+ chlevel = TOP;
+ break;
+ case AV1:
+ case AV2:
+ case AV3:
+ case AD3:
+ chlevel = ABOVE;
+ break;
+ case NON:
+ case CONS:
+ case LV:
+ case FV1:
+ case FV2:
+ case FV3:
+ default: /* if tactis_chtype is invalid */
+ chlevel = BASE;
+ break;
+ }
+ return chlevel;
+}
+
+
+/* return True if char is non-spacing */
+Private Bool
+THAI_isdead (unsigned char ch)
+{
+ return ((tactis_chtype[ch] == CTRL) || (tactis_chtype[ch] == BV1) ||
+ (tactis_chtype[ch] == BV2) || (tactis_chtype[ch] == BD) ||
+ (tactis_chtype[ch] == TONE) || (tactis_chtype[ch] == AD1) ||
+ (tactis_chtype[ch] == AD2) || (tactis_chtype[ch] == AD3) ||
+ (tactis_chtype[ch] == AV1) || (tactis_chtype[ch] == AV2) ||
+ (tactis_chtype[ch] == AV3));
+}
+
+
+/* return True if char is consonant */
+Private Bool
+THAI_iscons (unsigned char ch)
+{
+ return (tactis_chtype[ch] == CONS);
+}
+
+
+/* return True if char is vowel */
+Private Bool
+THAI_isvowel (unsigned char ch)
+{
+ return ((tactis_chtype[ch] == LV) || (tactis_chtype[ch] == FV1) ||
+ (tactis_chtype[ch] == FV2) || (tactis_chtype[ch] == FV3) ||
+ (tactis_chtype[ch] == BV1) || (tactis_chtype[ch] == BV2) ||
+ (tactis_chtype[ch] == AV1) || (tactis_chtype[ch] == AV2) ||
+ (tactis_chtype[ch] == AV3));
+}
+
+
+/* return True if char is tonemark */
+Private Bool
+THAI_istone (unsigned char ch)
+{
+ return (tactis_chtype[ch] == TONE);
+}
+#endif
+
+Private Bool
+THAI_iscomposible (
+ unsigned char follow_ch,
+ unsigned char lead_ch)
+{/* "Can follow_ch be put in the same display cell as lead_ch?" */
+
+ return (write_rules_lookup[THAI_chtype(lead_ch)][THAI_chtype(follow_ch)]
+ == CP);
+}
+
+Private Bool
+THAI_isaccepted (
+ unsigned char follow_ch,
+ unsigned char lead_ch,
+ unsigned char mode)
+{
+ Bool iskeyvalid; /* means "Can follow_ch be keyed in after lead_ch?" */
+
+ switch (mode)
+ {
+ case WTT_ISC1:
+ iskeyvalid =
+ (wtt_isc1_lookup[THAI_chtype(lead_ch)][THAI_chtype(follow_ch)] != RJ);
+ break;
+ case WTT_ISC2:
+ iskeyvalid =
+ (wtt_isc2_lookup[THAI_chtype(lead_ch)][THAI_chtype(follow_ch)] != RJ);
+ break;
+ case THAICAT_ISC:
+ iskeyvalid =
+ (thaicat_isc_lookup[THAI_chtype(lead_ch)][THAI_chtype(follow_ch)] != RJ);
+ break;
+ default:
+ iskeyvalid = True;
+ break;
+ }
+
+ return iskeyvalid;
+}
+
+#ifdef UNUSED
+Private void
+THAI_apply_write_rules(
+ unsigned char *instr,
+ unsigned char *outstr,
+ unsigned char insert_ch,
+ int *num_insert_ch)
+{
+/*
+Input parameters:
+ instr - input string
+ insert_ch specify what char to be added when invalid composition is found
+Output parameters:
+ outstr - output string after input string has been applied the rules
+ num_insert_ch - number of insert_ch added to outstr.
+*/
+ unsigned char *lead_ch = NULL, *follow_ch = NULL, *out_ch = NULL;
+
+ *num_insert_ch = 0;
+ lead_ch = follow_ch = instr;
+ out_ch = outstr;
+ if ((*lead_ch == '\0') || !(THAI_find_chtype(instr,DEAD)))
+ { /* Empty string or can't find any non-spacing char*/
+ strcpy((char *)outstr, (char *)instr);
+ } else { /* String of length >= 1, keep looking */
+ follow_ch++;
+ if (THAI_isdead(*lead_ch)) { /* is first char non-spacing? */
+ *out_ch++ = SPACE;
+ (*num_insert_ch)++;
+ }
+ *out_ch++ = *lead_ch;
+ while (*follow_ch != '\0') /* more char in string to check */
+ {
+ if (THAI_isdead(*follow_ch) &&
+ !THAI_iscomposible(*follow_ch,*lead_ch))
+ {
+ *out_ch++ = SPACE;
+ (*num_insert_ch)++;
+ }
+ *out_ch++ = *follow_ch;
+ lead_ch = follow_ch;
+ follow_ch++;
+ }
+ *out_ch = '\0';
+ }
+}
+
+Private int
+THAI_find_chtype (
+ unsigned char *instr,
+ int chtype)
+{
+/*
+Input parameters:
+ instr - input string
+ chtype - type of character to look for
+Output parameters:
+ function returns first position of character with matched chtype
+ function returns -1 if it does not find.
+*/
+ int i = 0, position = -1;
+
+ switch (chtype)
+ {
+ case DEAD:
+ for (i = 0; *instr != '\0' && THAI_isdead(*instr); i++, instr++)
+ ;
+ if (*instr != '\0') position = i;
+ break;
+ default:
+ break;
+ }
+ return position;
+}
+
+
+Private int
+THAI_apply_scm(
+ unsigned char *instr,
+ unsigned char *outstr,
+ unsigned char spec_ch,
+ int num_sp,
+ unsigned char insert_ch)
+{
+ unsigned char *scan, *outch;
+ int i, dead_count, found_count;
+ Bool isconsecutive;
+
+ scan = instr;
+ outch = outstr;
+ dead_count = found_count = 0;
+ isconsecutive = False;
+ while (*scan != '\0') {
+ if (THAI_isdead(*scan))
+ dead_count++; /* count number of non-spacing char */
+ if (*scan == spec_ch)
+ if (!isconsecutive)
+ found_count++; /* count number consecutive spec char found */
+ *outch++ = *scan++;
+ if (found_count == num_sp) {
+ for (i = 0; i < dead_count; i++)
+ *outch++ = insert_ch;
+ dead_count = found_count = 0;
+ }
+ }
+ /* what to return? */
+ return 0; /* probably not right but better than returning garbage */
+}
+
+
+/* The following functions are copied from XKeyBind.c */
+
+Private void ComputeMaskFromKeytrans();
+Private int IsCancelComposeKey(KeySym *symbol, XKeyEvent *event);
+Private void SetLed(Display *dpy, int num, int state);
+Private CARD8 FindKeyCode();
+
+
+/* The following functions are specific to this module */
+
+Private int XThaiTranslateKey();
+Private int XThaiTranslateKeySym();
+
+
+Private KeySym HexIMNormalKey(
+ XicThaiPart *thai_part,
+ KeySym symbol,
+ XKeyEvent *event);
+Private KeySym HexIMFirstComposeKey(
+ XicThaiPart *thai_part,
+ KeySym symbol,
+ XKeyEvent *event);
+Private KeySym HexIMSecondComposeKey(
+ XicThaiPart *thai_part,
+ KeySym symbol
+ XKeyEvent *event);
+Private KeySym HexIMComposeSequence(KeySym ks1, KeySym ks2);
+Private void InitIscMode(Xic ic);
+Private Bool ThaiComposeConvert(
+ Display *dpy,
+ KeySym insym,
+ KeySym *outsym, KeySym *lower, KeySym *upper);
+#endif
+
+/*
+ * Definitions
+ */
+
+#define BellVolume 0
+
+#define ucs2tis(wc) \
+ (unsigned char) ( \
+ (0<=(wc)&&(wc)<=0x7F) ? \
+ (wc) : \
+ ((0x0E01<=(wc)&&(wc)<=0x0E5F) ? ((wc)-0x0E00+0xA0) : 0))
+/* "c" is an unsigned char */
+#define tis2ucs(c) \
+ ( \
+ ((c)<=0x7F) ? \
+ (wchar_t)(c) : \
+ ((0x0A1<=(c)) ? ((wchar_t)(c)-0xA0+0x0E00) : 0))
+
+/*
+ * Macros to save and recall last input character in XIC
+ */
+#define IC_SavePreviousChar(ic,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.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) \
+ (IC_RealGetPreviousChar(ic,2))
+#define IC_DeletePreviousChar(ic) \
+ (IC_RealDeletePreviousChar(ic))
+
+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;
+ unsigned char c;
+
+ /* Use a safe value of position = 0 and stretch the range to desired
+ * place, as XIM protocol is unclear here whether it could be negative
+ */
+ screc.position = 0;
+ screc.direction = XIMBackwardChar;
+ screc.operation = XIMStringConversionRetrieval;
+ screc.factor = pos;
+ screc.text = 0;
+
+ (cb->callback)((XIC)ic, cb->client_data, (XPointer)&screc);
+ if (!screc.text)
+ return (unsigned char) b->mb[b->tree[(ic)->private.local.context].mb];
+ if ((screc.text->feedback &&
+ *screc.text->feedback == XIMStringConversionLeftEdge) ||
+ screc.text->length < 1)
+ {
+ c = 0;
+ } else {
+ Xim im;
+ XlcConv conv;
+ int from_left;
+ int to_left;
+ char *from_buf;
+ char *to_buf;
+
+ im = (Xim) XIMOfIC((XIC)ic);
+ if (screc.text->encoding_is_wchar) {
+ conv = _XlcOpenConverter(im->core.lcd, XlcNWideChar,
+ im->core.lcd, XlcNCharSet);
+ from_buf = (char *) screc.text->string.wcs;
+ from_left = screc.text->length * sizeof(wchar_t);
+ } else {
+ conv = _XlcOpenConverter(im->core.lcd, XlcNMultiByte,
+ im->core.lcd, XlcNCharSet);
+ from_buf = screc.text->string.mbs;
+ from_left = screc.text->length;
+ }
+ to_buf = (char *)&c;
+ to_left = 1;
+
+ _XlcResetConverter(conv);
+ if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
+ (XPointer *)&to_buf, &to_left, NULL, 0) < 0)
+ {
+ c = (unsigned char) b->mb[b->tree[(ic)->private.local.context].mb];
+ }
+ _XlcCloseConverter(conv);
+
+ XFree(screc.text->string.mbs);
+ }
+ XFree(screc.text);
+ return c;
+ } else {
+ return (unsigned char) b->mb[b->tree[(ic)->private.local.context].mb];
+ }
+}
+
+Private unsigned char
+IC_RealDeletePreviousChar(Xic ic)
+{
+ XICCallback* cb = &ic->core.string_conversion_callback;
+
+ if (cb && cb->callback) {
+ XIMStringConversionCallbackStruct screc;
+ unsigned char c;
+
+ screc.position = 0;
+ screc.direction = XIMBackwardChar;
+ screc.operation = XIMStringConversionSubstitution;
+ screc.factor = 1;
+ screc.text = 0;
+
+ (cb->callback)((XIC)ic, cb->client_data, (XPointer)&screc);
+ if (!screc.text) { return 0; }
+ if ((screc.text->feedback &&
+ *screc.text->feedback == XIMStringConversionLeftEdge) ||
+ screc.text->length < 1)
+ {
+ c = 0;
+ } else {
+ if (screc.text->encoding_is_wchar) {
+ c = ucs2tis(screc.text->string.wcs[0]);
+ XFree(screc.text->string.wcs);
+ } else {
+ c = screc.text->string.mbs[0];
+ XFree(screc.text->string.mbs);
+ }
+ }
+ XFree(screc.text);
+ return c;
+ } else {
+ return 0;
+ }
+}
+/*
+ * Input sequence check mode in XIC
+ */
+#define IC_IscMode(ic) ((ic)->private.local.thai.input_mode)
+
+/*
+ * Max. size of string handled by the two String Lookup functions.
+ */
+#define STR_LKUP_BUF_SIZE 256
+
+/*
+ * Size of buffer to contain previous locale name.
+ */
+#define SAV_LOCALE_NAME_SIZE 256
+
+/*
+ * Size of buffer to contain the IM modifier.
+ */
+#define MAXTHAIIMMODLEN 20
+
+#define AllMods (ShiftMask|LockMask|ControlMask| \
+ Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
+
+
+#define IsISOControlKey(ks) ((ks) >= XK_2 && (ks) <= XK_8)
+
+#define IsValidControlKey(ks) (((((ks)>=XK_A && (ks)<=XK_asciitilde) || \
+ (ks)==XK_space || (ks)==XK_Delete) && \
+ ((ks)!=0)))
+
+#define COMPOSE_LED 2
+
+#ifdef UNUSED
+typedef KeySym (*StateProc)(
+ XicThaiPart *thai_part,
+ KeySym symbol,
+ XKeyEvent *event);
+
+
+/*
+ * macros to classify XKeyEvent state field
+ */
+
+#define IsShift(state) (((state) & ShiftMask) != 0)
+#define IsLock(state) (((state) & LockMask) != 0)
+#define IsControl(state) (((state) & ControlMask) != 0)
+#define IsMod1(state) (((state) & Mod1Mask) != 0)
+#define IsMod2(state) (((state) & Mod2Mask) != 0)
+#define IsMod3(state) (((state) & Mod3Mask) != 0)
+#define IsMod4(state) (((state) & Mod4Mask) != 0)
+#define IsMod5(state) (((state) & Mod5Mask) != 0)
+
+/*
+ * key starts Thai compose sequence (Hex input method) if :
+ */
+
+#define IsComposeKey(ks, event) \
+ (( ks==XK_Alt_L && \
+ IsControl((event)->state) && \
+ !IsShift((event)->state)) \
+ ? True : False)
+
+
+/*
+ * State handler to implement the Thai hex input method.
+ */
+
+Private int const nstate_handlers = 3;
+Private StateProc state_handler[] = {
+ HexIMNormalKey,
+ HexIMFirstComposeKey,
+ HexIMSecondComposeKey
+};
+
+
+/*
+ * Table for 'Thai Compose' character input.
+ * The current implementation uses latin-1 keysyms.
+ */
+struct _XMapThaiKey {
+ KeySym from;
+ KeySym to;
+};
+
+Private struct _XMapThaiKey const ThaiComposeTable[] = {
+ { /* 0xa4 */ XK_currency, /* 0xa5 */ XK_yen },
+ { /* 0xa2 */ XK_cent, /* 0xa3 */ XK_sterling },
+ { /* 0xe6 */ XK_ae, /* 0xef */ XK_idiaeresis },
+ { /* 0xd3 */ XK_Oacute, /* 0xee */ XK_icircumflex },
+ { /* 0xb9 */ XK_onesuperior, /* 0xfa */ XK_uacute },
+ { /* 0xd2 */ XK_Ograve, /* 0xe5 */ XK_aring },
+ { /* 0xbc */ XK_onequarter, /* 0xfb */ XK_ucircumflex },
+ { XK_VoidSymbol, XK_VoidSymbol }
+};
+
+struct _XKeytrans {
+ struct _XKeytrans *next;/* next on list */
+ char *string; /* string to return when the time comes */
+ int len; /* length of string (since NULL is legit)*/
+ KeySym key; /* keysym rebound */
+ unsigned int state; /* modifier state */
+ KeySym *modifiers; /* modifier keysyms you want */
+ int mlen; /* length of modifier list */
+};
+
+
+/* Convert keysym to 'Thai Compose' keysym */
+/* The current implementation use latin-1 keysyms */
+Private Bool
+ThaiComposeConvert(
+ Display *dpy,
+ KeySym insym,
+ KeySym *outsym, KeySym *lower, KeySym *upper)
+{
+ struct _XMapThaiKey const *table_entry = ThaiComposeTable;
+
+ while (table_entry->from != XK_VoidSymbol) {
+ if (table_entry->from == insym) {
+ *outsym = table_entry->to;
+ *lower = *outsym;
+ *upper = *outsym;
+ return True;
+ }
+ table_entry++;
+ }
+ return False;
+}
+
+Private int
+XThaiTranslateKey(
+ register Display *dpy,
+ KeyCode keycode,
+ register unsigned int modifiers,
+ unsigned int *modifiers_return,
+ KeySym *keysym_return,
+ KeySym *lsym_return,
+ KeySym *usym_return)
+{
+ int per;
+ register KeySym *syms;
+ KeySym sym = 0, lsym = 0, usym = 0;
+
+ if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
+ return 0;
+ *modifiers_return = (ShiftMask|LockMask) | dpy->mode_switch;
+ if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
+ {
+ *keysym_return = NoSymbol;
+ return 1;
+ }
+ per = dpy->keysyms_per_keycode;
+ syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
+ while ((per > 2) && (syms[per - 1] == NoSymbol))
+ per--;
+ if ((per > 2) && (modifiers & dpy->mode_switch)) {
+ syms += 2;
+ per -= 2;
+ }
+ if (!(modifiers & ShiftMask) &&
+ (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) {
+ if ((per == 1) || (syms[1] == NoSymbol))
+ XConvertCase(syms[0], keysym_return, &usym);
+ else {
+ XConvertCase(syms[0], &lsym, &usym);
+ *keysym_return = syms[0];
+ }
+ } else if (!(modifiers & LockMask) ||
+ (dpy->lock_meaning != XK_Caps_Lock)) {
+ if ((per == 1) || ((usym = syms[1]) == NoSymbol))
+ XConvertCase(syms[0], &lsym, &usym);
+ *keysym_return = usym;
+ } else {
+ if ((per == 1) || ((sym = syms[1]) == NoSymbol))
+ sym = syms[0];
+ XConvertCase(sym, &lsym, &usym);
+ if (!(modifiers & ShiftMask) && (sym != syms[0]) &&
+ ((sym != usym) || (lsym == usym)))
+ XConvertCase(syms[0], &lsym, &usym);
+ *keysym_return = usym;
+ }
+ /*
+ * ThaiCat keyboard support :
+ * When the Shift and Thai keys are hold for some keys a 'Thai Compose'
+ * character code is generated which is different from column 3 and
+ * 4 of the keymap.
+ * Since we don't know whether ThaiCat keyboard or WTT keyboard is
+ * in use, the same mapping is done for all Thai input.
+ * We just arbitary choose to use column 3 keysyms as the indices of
+ * this mapping.
+ * When the control key is also hold, this mapping has no effect.
+ */
+ if ((modifiers & Mod1Mask) &&
+ (modifiers & ShiftMask) &&
+ !(modifiers & ControlMask)) {
+ if (ThaiComposeConvert(dpy, syms[0], &sym, &lsym, &usym))
+ *keysym_return = sym;
+ }
+
+ if (*keysym_return == XK_VoidSymbol)
+ *keysym_return = NoSymbol;
+ *lsym_return = lsym;
+ *usym_return = usym;
+ return 1;
+}
+
+/*
+ * XThaiTranslateKeySym
+ *
+ * Translate KeySym to TACTIS code output.
+ * The current implementation uses ISO latin-1 keysym.
+ * Should be changed to TACTIS keysyms when they are defined by the
+ * standard.
+ */
+Private int
+XThaiTranslateKeySym(
+ Display *dpy,
+ register KeySym symbol,
+ register KeySym lsym,
+ register KeySym usym,
+ unsigned int modifiers,
+ unsigned char *buffer,
+ int nbytes)
+{
+ KeySym ckey = 0;
+ register struct _XKeytrans *p;
+ int length;
+ unsigned long hiBytes;
+ register unsigned char c;
+
+ /*
+ * initialize length = 1 ;
+ */
+ length = 1;
+
+ if (!symbol)
+ return 0;
+ /* see if symbol rebound, if so, return that string. */
+ for (p = dpy->key_bindings; p; p = p->next) {
+ if (((modifiers & AllMods) == p->state) && (symbol == p->key)) {
+ length = p->len;
+ if (length > nbytes) length = nbytes;
+ memcpy (buffer, p->string, length);
+ return length;
+ }
+ }
+ /* try to convert to TACTIS, handling control */
+ hiBytes = symbol >> 8;
+ if (!(nbytes &&
+ ((hiBytes == 0) ||
+ ((hiBytes == 0xFF) &&
+ (((symbol >= XK_BackSpace) && (symbol <= XK_Clear)) ||
+ (symbol == XK_Return) ||
+ (symbol == XK_Escape) ||
+ (symbol == XK_KP_Space) ||
+ (symbol == XK_KP_Tab) ||
+ (symbol == XK_KP_Enter) ||
+ ((symbol >= XK_KP_Multiply) && (symbol <= XK_KP_9)) ||
+ (symbol == XK_KP_Equal) ||
+ (symbol == XK_Scroll_Lock) ||
+#ifdef DXK_PRIVATE /* DEC private keysyms */
+ (symbol == DXK_Remove) ||
+#endif
+ (symbol == NoSymbol) ||
+ (symbol == XK_Delete))))))
+ return 0;
+
+ /* if X keysym, convert to ascii by grabbing low 7 bits */
+ if (symbol == XK_KP_Space)
+ c = XK_space & 0x7F; /* patch encoding botch */
+/* not for Thai
+ else if (symbol == XK_hyphen)
+ c = XK_minus & 0xFF; */ /* map to equiv character */
+ else if (hiBytes == 0xFF)
+ c = symbol & 0x7F;
+ else
+ c = symbol & 0xFF;
+ /* only apply Control key if it makes sense, else ignore it */
+ if (modifiers & ControlMask) {
+ if (!(IsKeypadKey(lsym) || lsym==XK_Return || lsym==XK_Tab)) {
+ if (IsISOControlKey(lsym)) ckey = lsym;
+ else if (IsISOControlKey(usym)) ckey = usym;
+ else if (lsym == XK_question) ckey = lsym;
+ else if (usym == XK_question) ckey = usym;
+ else if (IsValidControlKey(lsym)) ckey = lsym;
+ else if (IsValidControlKey(usym)) ckey = usym;
+ else length = 0;
+
+ if (length != 0) {
+ if (ckey == XK_2) c = '\000';
+ else if (ckey >= XK_3 && ckey <= XK_7)
+ c = (char)(ckey-('3'-'\033'));
+ else if (ckey == XK_8) c = '\177';
+ else if (ckey == XK_Delete) c = '\030';
+ else if (ckey == XK_question) c = '\037';
+ else if (ckey == XK_quoteleft) c = '\036'; /* KLee 1/24/91 */
+ else c = (char)(ckey & 0x1f);
+ }
+ }
+ }
+ /*
+ * ThaiCat has a key that generates two TACTIS codes D1 & E9.
+ * It is represented by the latin-1 keysym XK_thorn (0xfe).
+ * If c is XK_thorn, this key is pressed and it is converted to
+ * 0xd1 0xe9.
+ */
+ if (c == XK_thorn) {
+ buffer[0] = 0xd1;
+ buffer[1] = 0xe9;
+ buffer[2] = '\0';
+ return 2;
+ }
+ else {
+ /* Normal case */
+ buffer[0] = c;
+ buffer[1] = '\0';
+ return 1;
+ }
+}
+
+/*
+ * given a KeySym, returns the first keycode containing it, if any.
+ */
+Private CARD8
+FindKeyCode(
+ register Display *dpy,
+ register KeySym code)
+{
+
+ register KeySym *kmax = dpy->keysyms +
+ (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode;
+ register KeySym *k = dpy->keysyms;
+ while (k < kmax) {
+ if (*k == code)
+ return (((k - dpy->keysyms) / dpy->keysyms_per_keycode) +
+ dpy->min_keycode);
+ k += 1;
+ }
+ return 0;
+}
+
+/*
+ * given a list of modifiers, computes the mask necessary for later matching.
+ * This routine must lookup the key in the Keymap and then search to see
+ * what modifier it is bound to, if any. Sets the AnyModifier bit if it
+ * can't map some keysym to a modifier.
+ */
+Private void
+ComputeMaskFromKeytrans(
+ Display *dpy,
+ register struct _XKeytrans *p)
+{
+ register int i;
+ register CARD8 code;
+ register XModifierKeymap *m = dpy->modifiermap;
+
+ p->state = AnyModifier;
+ for (i = 0; i < p->mlen; i++) {
+ /* if not found, then not on current keyboard */
+ if ((code = FindKeyCode(dpy, p->modifiers[i])) == 0)
+ return;
+ /* code is now the keycode for the modifier you want */
+ {
+ register int j = m->max_keypermod<<3;
+
+ while ((--j >= 0) && (code != m->modifiermap[j]))
+ ;
+ if (j < 0)
+ return;
+ p->state |= (1<<(j/m->max_keypermod));
+ }
+ }
+ p->state &= AllMods;
+}
+
+/************************************************************************
+ *
+ *
+ * Compose handling routines - compose handlers 0,1,2
+ *
+ *
+ ************************************************************************/
+
+#define NORMAL_KEY_STATE 0
+#define FIRST_COMPOSE_KEY_STATE 1
+#define SECOND_COMPOSE_KEY_STATE 2
+
+Private
+KeySym HexIMNormalKey(
+ XicThaiPart *thai_part,
+ KeySym symbol,
+ XKeyEvent *event)
+{
+ if (IsComposeKey (symbol, event)) /* start compose sequence */
+ {
+ SetLed (event->display,COMPOSE_LED, LedModeOn);
+ thai_part->comp_state = FIRST_COMPOSE_KEY_STATE;
+ return NoSymbol;
+ }
+ return symbol;
+}
+
+
+Private
+KeySym HexIMFirstComposeKey(
+ XicThaiPart *thai_part,
+ KeySym symbol,
+ XKeyEvent *event)
+{
+ if (IsModifierKey (symbol)) return symbol; /* ignore shift etc. */
+ if (IsCancelComposeKey (&symbol, event)) /* cancel sequence */
+ {
+ SetLed (event->display,COMPOSE_LED, LedModeOff);
+ thai_part->comp_state = NORMAL_KEY_STATE;
+ return symbol;
+ }
+ if (IsComposeKey (symbol, event)) /* restart sequence ?? */
+ {
+ return NoSymbol; /* no state change necessary */
+ }
+
+ thai_part->keysym = symbol; /* save key pressed */
+ thai_part->comp_state = SECOND_COMPOSE_KEY_STATE;
+ return NoSymbol;
+}
+
+Private
+KeySym HexIMSecondComposeKey(
+ XicThaiPart *thai_part,
+ KeySym symbol,
+ XKeyEvent *event)
+{
+ if (IsModifierKey (symbol)) return symbol; /* ignore shift etc. */
+ if (IsComposeKey (symbol, event)) /* restart sequence ? */
+ {
+ thai_part->comp_state =FIRST_COMPOSE_KEY_STATE;
+ return NoSymbol;
+ }
+ SetLed (event->display,COMPOSE_LED, LedModeOff);
+ if (IsCancelComposeKey (&symbol, event)) /* cancel sequence ? */
+ {
+ thai_part->comp_state = NORMAL_KEY_STATE;
+ return symbol;
+ }
+
+ if ((symbol = HexIMComposeSequence (thai_part->keysym, symbol))
+ ==NoSymbol)
+ { /* invalid compose sequence */
+ XBell(event->display, BellVolume);
+ }
+ thai_part->comp_state = NORMAL_KEY_STATE; /* reset to normal state */
+ return symbol;
+}
+
+
+/*
+ * Interprets two keysyms entered as hex digits and return the Thai keysym
+ * correspond to the TACTIS code formed.
+ * The current implementation of this routine returns ISO Latin Keysyms.
+ */
+
+Private
+KeySym HexIMComposeSequence(KeySym ks1, KeySym ks2)
+{
+int hi_digit;
+int lo_digit;
+int tactis_code;
+
+ if ((ks1 >= XK_0) && (ks1 <= XK_9))
+ hi_digit = ks1 - XK_0;
+ else if ((ks1 >= XK_A) && (ks1 <= XK_F))
+ hi_digit = ks1 - XK_A + 10;
+ else if ((ks1 >= XK_a) && (ks1 <= XK_f))
+ hi_digit = ks1 - XK_a + 10;
+ else /* out of range */
+ return NoSymbol;
+
+ if ((ks2 >= XK_0) && (ks2 <= XK_9))
+ lo_digit = ks2 - XK_0;
+ else if ((ks2 >= XK_A) && (ks2 <= XK_F))
+ lo_digit = ks2 - XK_A + 10;
+ else if ((ks2 >= XK_a) && (ks2 <= XK_f))
+ lo_digit = ks2 - XK_a + 10;
+ else /* out of range */
+ return NoSymbol;
+
+ tactis_code = hi_digit * 0x10 + lo_digit ;
+
+ return (KeySym)tactis_code;
+
+}
+
+/*
+ * routine determines
+ * 1) whether key event should cancel a compose sequence
+ * 2) whether cancelling key event should be processed or ignored
+ */
+
+Private
+int IsCancelComposeKey(
+ KeySym *symbol,
+ XKeyEvent *event)
+{
+ if (*symbol==XK_Delete && !IsControl(event->state) &&
+ !IsMod1(event->state)) {
+ *symbol=NoSymbol; /* cancel compose sequence, and ignore key */
+ return True;
+ }
+ if (IsComposeKey(*symbol, event)) return False;
+ return (
+ IsControl (event->state) ||
+ IsMod1(event->state) ||
+ IsKeypadKey (*symbol) ||
+ IsFunctionKey (*symbol) ||
+ IsMiscFunctionKey (*symbol) ||
+#ifdef DXK_PRIVATE /* DEC private keysyms */
+ *symbol == DXK_Remove ||
+#endif
+ IsPFKey (*symbol) ||
+ IsCursorKey (*symbol) ||
+ (*symbol >= XK_Tab && *symbol < XK_Multi_key)
+ ? True : False); /* cancel compose sequence and pass */
+ /* cancelling key through */
+}
+
+
+/*
+ * set specified keyboard LED on or off
+ */
+
+Private
+void SetLed(
+ Display *dpy,
+ int num,
+ int state)
+{
+ XKeyboardControl led_control;
+
+ led_control.led_mode = state;
+ led_control.led = num;
+ XChangeKeyboardControl (dpy, KBLed | KBLedMode, &led_control);
+}
+#endif
+
+/*
+ * Initialize ISC mode from im modifier
+ */
+Private void InitIscMode(Xic ic)
+{
+ Xim im;
+ char *im_modifier_name;
+
+ /* If already defined, just return */
+
+ if (IC_IscMode(ic)) return;
+
+ /* Get IM modifier */
+
+ im = (Xim) XIMOfIC((XIC)ic);
+ im_modifier_name = im->core.im_name;
+
+ /* Match with predefined value, default is Basic Check */
+
+ if (!strncmp(im_modifier_name,"BasicCheck",MAXTHAIIMMODLEN+1))
+ IC_IscMode(ic) = WTT_ISC1;
+ else if (!strncmp(im_modifier_name,"Strict",MAXTHAIIMMODLEN+1))
+ IC_IscMode(ic) = WTT_ISC2;
+ else if (!strncmp(im_modifier_name,"Thaicat",MAXTHAIIMMODLEN+1))
+ IC_IscMode(ic) = THAICAT_ISC;
+ else if (!strncmp(im_modifier_name,"Passthrough",MAXTHAIIMMODLEN+1))
+ IC_IscMode(ic) = NOISC;
+ else
+ IC_IscMode(ic) = WTT_ISC1;
+
+ return;
+}
+
+/*
+ * Helper functions for _XimThaiFilter()
+ */
+Private Bool
+ThaiFltAcceptInput(Xic ic, unsigned char new_char, KeySym symbol)
+{
+ 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))
+ b->tree[ic->private.local.composed].keysym = symbol;
+ else
+ b->tree[ic->private.local.composed].keysym = NoSymbol;
+
+ return True;
+}
+
+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;
+ 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';
+
+ b->tree[ic->private.local.composed].keysym = NoSymbol;
+
+ return True;
+}
+
+Private Bool
+ThaiFltReplaceInput(Xic ic, unsigned char new_char, KeySym symbol)
+{
+ DefTreeBase *b = &ic->private.local.base;
+ if (!IC_DeletePreviousChar(ic)) return False;
+ 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))
+ b->tree[ic->private.local.composed].keysym = symbol;
+ else
+ b->tree[ic->private.local.composed].keysym = NoSymbol;
+
+ return True;
+}
+
+Private unsigned
+NumLockMask(Display *d)
+{
+ int i;
+ XModifierKeymap *map;
+ KeyCode numlock_keycode = XKeysymToKeycode (d, XK_Num_Lock);
+ if (numlock_keycode == NoSymbol)
+ return 0;
+
+ map = XGetModifierMapping (d);
+ if (!map)
+ return 0;
+
+ for (i = 0; i < 8; i++) {
+ if (map->modifiermap[map->max_keypermod * i] == numlock_keycode) {
+ XFreeModifiermap(map);
+ return 1 << i;
+ }
+ }
+ XFreeModifiermap(map);
+ return 0;
+}
+
+/*
+ * Filter function for TACTIS
+ */
+Bool
+_XimThaiFilter(Display *d, Window w, XEvent *ev, XPointer client_data)
+{
+ Xic ic = (Xic)client_data;
+ KeySym symbol;
+ int isc_mode; /* Thai Input Sequence Check mode */
+ unsigned char previous_char; /* Last inputted Thai char */
+ unsigned char new_char;
+#ifdef UNUSED
+ unsigned int modifiers;
+ KeySym lsym,usym;
+ int state;
+ XicThaiPart *thai_part;
+ char buf[10];
+#endif
+ wchar_t wbuf[10];
+ Bool isReject;
+ DefTreeBase *b = &ic->private.local.base;
+
+ if ((ev->type != KeyPress)
+ || (ev->xkey.keycode == 0))
+ return False;
+
+ if (!IC_IscMode(ic)) InitIscMode(ic);
+
+ XwcLookupString((XIC)ic, &ev->xkey, wbuf, sizeof(wbuf) / sizeof(wbuf[0]),
+ &symbol, NULL);
+
+ if ((ev->xkey.state & (AllMods & ~(ShiftMask|LockMask|NumLockMask(d)))) ||
+ ((symbol >> 8 == 0xFF) &&
+ ((XK_BackSpace <= symbol && symbol <= XK_Clear) ||
+ (symbol == XK_Return) ||
+ (symbol == XK_Pause) ||
+ (symbol == XK_Scroll_Lock) ||
+ (symbol == XK_Sys_Req) ||
+ (symbol == XK_Escape) ||
+ (symbol == XK_Delete) ||
+ IsCursorKey(symbol) ||
+ IsKeypadKey(symbol) ||
+ IsMiscFunctionKey(symbol) ||
+ IsFunctionKey(symbol))))
+ {
+ IC_ClearPreviousChar(ic);
+ return False;
+ }
+ if (((symbol >> 8 == 0xFF) &&
+ IsModifierKey(symbol)) ||
+#ifdef XK_XKB_KEYS
+ ((symbol >> 8 == 0xFE) &&
+ (XK_ISO_Lock <= symbol && symbol <= XK_ISO_Last_Group_Lock)) ||
+#endif
+ (symbol == NoSymbol))
+ {
+ return False;
+ }
+#ifdef UNUSED
+ if (! XThaiTranslateKey(ev->xkey.display, ev->xkey.keycode, ev->xkey.state,
+ &modifiers, &symbol, &lsym, &usym))
+ return False;
+
+ /*
+ * Hex input method processing
+ */
+
+ thai_part = &ic->private.local.thai;
+ state = thai_part->comp_state;
+ if (state >= 0 && state < nstate_handlers) /* call handler for state */
+ {
+ symbol = (* state_handler[state])(thai_part, symbol, (XKeyEvent *)ev);
+ }
+
+ /*
+ * Translate KeySym into mb.
+ */
+ count = XThaiTranslateKeySym(ev->xkey.display, symbol, lsym,
+ usym, ev->xkey.state, buf, 10);
+
+ if (!symbol && !count)
+ return True;
+
+ /* Return symbol if cannot convert to character */
+ if (!count)
+ return False;
+#endif
+
+ /*
+ * Thai Input sequence check
+ */
+ isc_mode = IC_IscMode(ic);
+ if (!(previous_char = IC_GetPreviousChar(ic))) previous_char = ' ';
+ new_char = ucs2tis(wbuf[0]);
+ isReject = True;
+ if (THAI_isaccepted(new_char, previous_char, isc_mode)) {
+ ThaiFltAcceptInput(ic, new_char, symbol);
+ isReject = False;
+ } else {
+ unsigned char context_char;
+
+ context_char = IC_GetContextChar(ic);
+ if (context_char) {
+ if (THAI_iscomposible(new_char, context_char)) {
+ if (THAI_iscomposible(previous_char, new_char)) {
+ isReject = !ThaiFltReorderInput(ic, previous_char, new_char);
+ } else if (THAI_iscomposible(previous_char, context_char)) {
+ isReject = !ThaiFltReplaceInput(ic, new_char, symbol);
+ } else if (THAI_chtype(previous_char) == FV1
+ && THAI_chtype(new_char) == TONE) {
+ isReject = !ThaiFltReorderInput(ic, previous_char, new_char);
+ }
+ } else if (THAI_isaccepted(new_char, context_char, isc_mode)) {
+ isReject = !ThaiFltReplaceInput(ic, new_char, symbol);
+ }
+ }
+ }
+ if (isReject) {
+ /* reject character */
+ XBell(ev->xkey.display, BellVolume);
+ return True;
+ }
+
+ _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, &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)
+ */
+ IC_SavePreviousChar(ic, new_char);
+
+ ev->xkey.keycode = 0;
+ XPutBackEvent(d, ev);
+ return True;
+}
diff --git a/libX11/modules/im/ximcp/imThaiIm.c b/libX11/modules/im/ximcp/imThaiIm.c
index 767b52c2a..45c690bbc 100644
--- a/libX11/modules/im/ximcp/imThaiIm.c
+++ b/libX11/modules/im/ximcp/imThaiIm.c
@@ -1,235 +1,235 @@
-/******************************************************************
-
- Copyright 1992, 1993, 1994 by FUJITSU LIMITED
- Copyright 1993 by Digital Equipment Corporation
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of FUJITSU LIMITED and
-Digital Equipment Corporation not be used in advertising or publicity
-pertaining to distribution of the software without specific, written
-prior permission. FUJITSU LIMITED and Digital Equipment Corporation
-makes no representations about the suitability of this software for
-any purpose. It is provided "as is" without express or implied
-warranty.
-
-FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL
-WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR
-ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-THIS SOFTWARE.
-
- Author: Takashi Fujiwara FUJITSU LIMITED
- fujiwara@a80.tech.yk.fujitsu.co.jp
- Modifier: Franky Ling Digital Equipment Corporation
- frankyling@hgrd01.enet.dec.com
-
-******************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/Xmd.h>
-#include <X11/Xatom.h>
-#include <X11/Xos.h>
-#include "Xlibint.h"
-#include "Xlcint.h"
-#include "XlcPublic.h"
-#include "XlcPubI.h"
-#include "Ximint.h"
-
-Private XIMMethodsRec Xim_im_thai_methods = {
- _XimThaiCloseIM, /* close */
- _XimLocalSetIMValues, /* set_values */
- _XimLocalGetIMValues, /* get_values */
- _XimThaiCreateIC, /* create_ic */
- _XimLcctstombs, /* ctstombs */
- _XimLcctstowcs, /* ctstowcs */
- _XimLcctstoutf8 /* ctstoutf8 */
-};
-
-#define THAI_LANGUAGE_NAME "th"
-
-Bool
-_XimCheckIfThaiProcessing(Xim im)
-{
- char *language;
-
- _XGetLCValues(im->core.lcd, XlcNLanguage, &language, NULL);
- if(strcmp(language, THAI_LANGUAGE_NAME) == 0 &&
- (strcmp(im->core.im_name, "") == 0 ||
- strcmp(im->core.im_name, "BasicCheck") == 0 ||
- strcmp(im->core.im_name, "Strict") == 0 ||
- strcmp(im->core.im_name, "Thaicat") == 0 ||
- strcmp(im->core.im_name, "Passthrough") == 0))
- {
- return(True);
- }
- return(False);
-}
-
-Public Bool
-_XimThaiOpenIM(Xim im)
-{
- XLCd lcd = im->core.lcd;
- XlcConv conv;
- XimDefIMValues im_values;
- XimLocalPrivateRec* private = &im->private.local;
-
- _XimInitialResourceInfo();
- if(_XimSetIMResourceList(&im->core.im_resources,
- &im->core.im_num_resources) == False) {
- goto Open_Error;
- }
- if(_XimSetICResourceList(&im->core.ic_resources,
- &im->core.ic_num_resources) == False) {
- goto Open_Error;
- }
-
- _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
-
- _XimGetCurrentIMValues(im, &im_values);
- if(_XimSetLocalIMDefaults(im, (XPointer)&im_values,
- im->core.im_resources, im->core.im_num_resources) == False) {
- goto Open_Error;
- }
- _XimSetCurrentIMValues(im, &im_values);
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte)))
- goto Open_Error;
- private->ctom_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar)))
- goto Open_Error;
- private->ctow_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNUtf8String)))
- goto Open_Error;
- private->ctoutf8_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte)))
- goto Open_Error;
- private->cstomb_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar)))
- goto Open_Error;
- private->cstowc_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String)))
- goto Open_Error;
- private->cstoutf8_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar)))
- goto Open_Error;
- private->ucstoc_conv = conv;
-
- if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String)))
- goto Open_Error;
- private->ucstoutf8_conv = conv;
-
- im->methods = &Xim_im_thai_methods;
- private->current_ic = (XIC)NULL;
-
- return(True);
-
-Open_Error :
- _XimThaiIMFree(im);
- return(False);
-}
-
-Public void
-_XimThaiIMFree(Xim im)
-{
- if(im->core.im_resources) {
- Xfree(im->core.im_resources);
- im->core.im_resources = NULL;
- }
- if(im->core.ic_resources) {
- Xfree(im->core.ic_resources);
- im->core.ic_resources = NULL;
- }
- if(im->core.im_values_list) {
- Xfree(im->core.im_values_list);
- im->core.im_values_list = NULL;
- }
- if(im->core.ic_values_list) {
- Xfree(im->core.ic_values_list);
- im->core.ic_values_list = NULL;
- }
- if(im->core.styles) {
- Xfree(im->core.styles);
- im->core.styles = NULL;
- }
- if(im->core.res_name) {
- Xfree(im->core.res_name);
- im->core.res_name = NULL;
- }
- if(im->core.res_class) {
- Xfree(im->core.res_class);
- im->core.res_class = NULL;
- }
- if(im->core.im_name) {
- Xfree(im->core.im_name);
- im->core.im_name = NULL;
- }
- if (im->private.local.ctom_conv) {
- _XlcCloseConverter(im->private.local.ctom_conv);
- im->private.local.ctom_conv = NULL;
- }
- if (im->private.local.ctow_conv) {
- _XlcCloseConverter(im->private.local.ctow_conv);
- im->private.local.ctow_conv = NULL;
- }
- if (im->private.local.ctoutf8_conv) {
- _XlcCloseConverter(im->private.local.ctoutf8_conv);
- im->private.local.ctoutf8_conv = NULL;
- }
- if (im->private.local.cstomb_conv) {
- _XlcCloseConverter(im->private.local.cstomb_conv);
- im->private.local.cstomb_conv = NULL;
- }
- if (im->private.local.cstowc_conv) {
- _XlcCloseConverter(im->private.local.cstowc_conv);
- im->private.local.cstowc_conv = NULL;
- }
- if (im->private.local.cstoutf8_conv) {
- _XlcCloseConverter(im->private.local.cstoutf8_conv);
- im->private.local.cstoutf8_conv = NULL;
- }
- if (im->private.local.ucstoc_conv) {
- _XlcCloseConverter(im->private.local.ucstoc_conv);
- im->private.local.ucstoc_conv = NULL;
- }
- if (im->private.local.ucstoutf8_conv) {
- _XlcCloseConverter(im->private.local.ucstoutf8_conv);
- im->private.local.ucstoutf8_conv = NULL;
- }
- return;
-}
-
-Public Status
-_XimThaiCloseIM(XIM xim)
-{
- Xim im = (Xim)xim;
- XIC ic;
- XIC next;
-
- ic = im->core.ic_chain;
- im->core.ic_chain = NULL;
- while (ic) {
- (*ic->methods->destroy) (ic);
- next = ic->core.next;
- Xfree ((char *) ic);
- ic = next;
- }
- _XimThaiIMFree(im);
- return(True);
-}
+/******************************************************************
+
+ Copyright 1992, 1993, 1994 by FUJITSU LIMITED
+ Copyright 1993 by Digital Equipment Corporation
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of FUJITSU LIMITED and
+Digital Equipment Corporation not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission. FUJITSU LIMITED and Digital Equipment Corporation
+makes no representations about the suitability of this software for
+any purpose. It is provided "as is" without express or implied
+warranty.
+
+FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL
+WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR
+ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+ Author: Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+ Modifier: Franky Ling Digital Equipment Corporation
+ frankyling@hgrd01.enet.dec.com
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xmd.h>
+#include <X11/Xatom.h>
+#include <X11/Xos.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "XlcPublic.h"
+#include "XlcPubI.h"
+#include "Ximint.h"
+
+Private XIMMethodsRec Xim_im_thai_methods = {
+ _XimThaiCloseIM, /* close */
+ _XimLocalSetIMValues, /* set_values */
+ _XimLocalGetIMValues, /* get_values */
+ _XimThaiCreateIC, /* create_ic */
+ _XimLcctstombs, /* ctstombs */
+ _XimLcctstowcs, /* ctstowcs */
+ _XimLcctstoutf8 /* ctstoutf8 */
+};
+
+#define THAI_LANGUAGE_NAME "th"
+
+Bool
+_XimCheckIfThaiProcessing(Xim im)
+{
+ char *language;
+
+ _XGetLCValues(im->core.lcd, XlcNLanguage, &language, NULL);
+ if(strcmp(language, THAI_LANGUAGE_NAME) == 0 &&
+ (strcmp(im->core.im_name, "") == 0 ||
+ strcmp(im->core.im_name, "BasicCheck") == 0 ||
+ strcmp(im->core.im_name, "Strict") == 0 ||
+ strcmp(im->core.im_name, "Thaicat") == 0 ||
+ strcmp(im->core.im_name, "Passthrough") == 0))
+ {
+ return(True);
+ }
+ return(False);
+}
+
+Public Bool
+_XimThaiOpenIM(Xim im)
+{
+ XLCd lcd = im->core.lcd;
+ XlcConv conv;
+ XimDefIMValues im_values;
+ XimLocalPrivateRec* private = &im->private.local;
+
+ _XimInitialResourceInfo();
+ if(_XimSetIMResourceList(&im->core.im_resources,
+ &im->core.im_num_resources) == False) {
+ goto Open_Error;
+ }
+ if(_XimSetICResourceList(&im->core.ic_resources,
+ &im->core.ic_num_resources) == False) {
+ goto Open_Error;
+ }
+
+ _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
+
+ _XimGetCurrentIMValues(im, &im_values);
+ if(_XimSetLocalIMDefaults(im, (XPointer)&im_values,
+ im->core.im_resources, im->core.im_num_resources) == False) {
+ goto Open_Error;
+ }
+ _XimSetCurrentIMValues(im, &im_values);
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte)))
+ goto Open_Error;
+ private->ctom_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar)))
+ goto Open_Error;
+ private->ctow_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNUtf8String)))
+ goto Open_Error;
+ private->ctoutf8_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte)))
+ goto Open_Error;
+ private->cstomb_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar)))
+ goto Open_Error;
+ private->cstowc_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String)))
+ goto Open_Error;
+ private->cstoutf8_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar)))
+ goto Open_Error;
+ private->ucstoc_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String)))
+ goto Open_Error;
+ private->ucstoutf8_conv = conv;
+
+ im->methods = &Xim_im_thai_methods;
+ private->current_ic = (XIC)NULL;
+
+ return(True);
+
+Open_Error :
+ _XimThaiIMFree(im);
+ return(False);
+}
+
+Public void
+_XimThaiIMFree(Xim im)
+{
+ if(im->core.im_resources) {
+ Xfree(im->core.im_resources);
+ im->core.im_resources = NULL;
+ }
+ if(im->core.ic_resources) {
+ Xfree(im->core.ic_resources);
+ im->core.ic_resources = NULL;
+ }
+ if(im->core.im_values_list) {
+ Xfree(im->core.im_values_list);
+ im->core.im_values_list = NULL;
+ }
+ if(im->core.ic_values_list) {
+ Xfree(im->core.ic_values_list);
+ im->core.ic_values_list = NULL;
+ }
+ if(im->core.styles) {
+ Xfree(im->core.styles);
+ im->core.styles = NULL;
+ }
+ if(im->core.res_name) {
+ Xfree(im->core.res_name);
+ im->core.res_name = NULL;
+ }
+ if(im->core.res_class) {
+ Xfree(im->core.res_class);
+ im->core.res_class = NULL;
+ }
+ if(im->core.im_name) {
+ Xfree(im->core.im_name);
+ im->core.im_name = NULL;
+ }
+ if (im->private.local.ctom_conv) {
+ _XlcCloseConverter(im->private.local.ctom_conv);
+ im->private.local.ctom_conv = NULL;
+ }
+ if (im->private.local.ctow_conv) {
+ _XlcCloseConverter(im->private.local.ctow_conv);
+ im->private.local.ctow_conv = NULL;
+ }
+ if (im->private.local.ctoutf8_conv) {
+ _XlcCloseConverter(im->private.local.ctoutf8_conv);
+ im->private.local.ctoutf8_conv = NULL;
+ }
+ if (im->private.local.cstomb_conv) {
+ _XlcCloseConverter(im->private.local.cstomb_conv);
+ im->private.local.cstomb_conv = NULL;
+ }
+ if (im->private.local.cstowc_conv) {
+ _XlcCloseConverter(im->private.local.cstowc_conv);
+ im->private.local.cstowc_conv = NULL;
+ }
+ if (im->private.local.cstoutf8_conv) {
+ _XlcCloseConverter(im->private.local.cstoutf8_conv);
+ im->private.local.cstoutf8_conv = NULL;
+ }
+ if (im->private.local.ucstoc_conv) {
+ _XlcCloseConverter(im->private.local.ucstoc_conv);
+ im->private.local.ucstoc_conv = NULL;
+ }
+ if (im->private.local.ucstoutf8_conv) {
+ _XlcCloseConverter(im->private.local.ucstoutf8_conv);
+ im->private.local.ucstoutf8_conv = NULL;
+ }
+ return;
+}
+
+Public Status
+_XimThaiCloseIM(XIM xim)
+{
+ Xim im = (Xim)xim;
+ XIC ic;
+ XIC next;
+
+ ic = im->core.ic_chain;
+ im->core.ic_chain = NULL;
+ while (ic) {
+ (*ic->methods->destroy) (ic);
+ next = ic->core.next;
+ Xfree ((char *) ic);
+ ic = next;
+ }
+ _XimThaiIMFree(im);
+ return(True);
+}