This is the first patch for "kinput", kana-kanji conversion front-end program in X11R4 contrib/clients. You should specify '-p0' option to 'patch' command to apply this correctly. % cd R4src/contrib/clients/kinput % patch -p0 < thisfile % make % make install This patch fixes the following problems: o kinput dumps core if the character conversion rule file includes non-existing files. o kinput dumps core if you don't specify jserver-hostname in the resource (kinput*jserver:) nor the environment variable 'JSERVER'. o wrong arguments to XQueryFont() in xlocal/xwstr.c:XWSSetGCSet(). since this function isn't used by kinput, it's considered harmless, but ANSI-C based compilers (such as gcc) that checks function prototypes complains about it. o error occurs when dictionary and its frequency file aren't coherent. now kinput makes new frequency file. And adds some features: o support keyboard group (for bilingual keyboards). but not completed yet. o search path of character conversion rule files can be specified by the envrironment variable 'CC_DEF_PATH'. you can specify two or more directories by separating them with colon, like $PATH. If you have any other problems, please let me know. Makoto Ishisone Software Research Associates, Inc. ishisone@sra.co.jp or ishisone%sra.co.jp@uunet.uu.net diff -r -c ../../R4/kinput/KanjiInpuP.h ./KanjiInpuP.h *** ../../R4/kinput/KanjiInpuP.h Tue Oct 31 16:28:31 1989 --- ./KanjiInpuP.h Mon Feb 26 13:25:17 1990 *************** *** 15,27 **** * Author: Makoto Ishisone, Software Research Associates, Inc., Japan */ ! /* $Header: /private/usr/mmb/ishisone/job/x11/kinput/RCS/KanjiInpuP.h,v 3.2 89/10/30 19:18:40 ishisone Exp $ */ #ifndef _KanjiInputP_h #define _KanjiInputP_h /* default ccdef file */ ! #define DEF_CCDEF_FILE "/usr/lib/X11/ccdef/ccdef.kinput" /* ステータスラインに表示する候補の最大数 */ #define MAXSELECTION 20 --- 15,27 ---- * Author: Makoto Ishisone, Software Research Associates, Inc., Japan */ ! /* $Header: /private/usr/mmb/ishisone/job/x11/kinput/RCS/KanjiInpuP.h,v 3.3 90/02/20 09:40:40 ishisone Exp $ */ #ifndef _KanjiInputP_h #define _KanjiInputP_h /* default ccdef file */ ! #define DEF_CCDEF_FILE "ccdef.kinput" /* ステータスラインに表示する候補の最大数 */ #define MAXSELECTION 20 Common subdirectories: ../../R4/kinput/cconv and ./cconv Common subdirectories: ../../R4/kinput/jclib and ./jclib diff -r -c ../../R4/kinput/kinput.c ./kinput.c *** ../../R4/kinput/kinput.c Tue Oct 31 16:28:55 1989 --- ./kinput.c Mon Feb 26 13:25:27 1990 *************** *** 23,29 **** */ #ifndef lint ! static char *rcsid = "$Header: /private/usr/mmb/ishisone/job/x11/kinput/RCS/kinput.c,v 3.2 89/10/27 17:23:50 ishisone Rel $"; #endif #include --- 23,29 ---- */ #ifndef lint ! static char *rcsid = "$Header: /private/usr/mmb/ishisone/job/x11/kinput/RCS/kinput.c,v 3.3 90/01/26 15:32:41 ishisone Exp $"; #endif #include *************** *** 156,162 **** Arg args[20]; Display *disp; ! toplevel = XtInitialize("main", "XJconv", options, XtNumber(options), &ac,av); disp = XtDisplay(toplevel); --- 156,162 ---- Arg args[20]; Display *disp; ! toplevel = XtInitialize("main", "Kinput", options, XtNumber(options), &ac,av); disp = XtDisplay(toplevel); Common subdirectories: ../../R4/kinput/xlocal and ./xlocal Common subdirectories: ../../R4/kinput/cconv/ccdef and ./cconv/ccdef diff -r -c ../../R4/kinput/cconv/cconv.c ./cconv/cconv.c *** ../../R4/kinput/cconv/cconv.c Tue Oct 31 16:28:37 1989 --- ./cconv/cconv.c Mon Feb 26 13:25:22 1990 *************** *** 1,6 **** /* * cconv.c -- 入力文字変換ライブラリ (for X11) ! * ver 8.0 */ /* --- 1,6 ---- /* * cconv.c -- 入力文字変換ライブラリ (for X11) ! * ver 8.3 */ /* *************** *** 92,97 **** --- 92,109 ---- * 問題があるが、まあこれはいいことにして。 * version 8.0 89/10/27 * R4 contrib 向けの Release にあたってバージョン番号を修正 + * version 8.1 89/12/25 + * include ファイルがなかった時にコアダンプするバグを修正 + * version 8.2 90/02/15 + * X11R4 keyboard group support 追加 + * version 8.3 90/02/16 + * keyboard group support の結果、例えば + * "" shift-Right "" foo + * "" Right "" bar + * というルールがあった時、shift-Right を押したにもかかわらず + * したのルールにマッチしてしまうというバグを修正 + * 定義ファイル (include ファイルも含む) のサーチパスとして + * 環境変数 CC_DEF_PATH を使うように修正 */ /* *************** *** 322,327 **** --- 334,341 ---- * include ファイル名 * である。ファイル名中に空白文字が含まれる時には ' か " で囲めばよい。 * ファイル名が相対パス名の時にはまずカレントディレクトリが探され、なければ + * 環境変数 CC_DEF_PATH が定義されていればそれに指定されたディレクトリ + * (':' で区切って複数指定することができる) の下が探され、それでもなければ * CCDEFPATH (/usr/lib/X11/ccdef/) の下が探される。 */ *************** *** 335,340 **** --- 349,357 ---- * deffile で指定されるファイルから変換ルールを読み込む。もしも * deffile が NULL の時は、環境変数 CC_DEF の値が使用される。 * deffile が相対パス名の時にはまずカレントディレクトリの下が探され、 + * なければ、環境変数 CC_DEF_PATH で指定されたディレクトリの下が + * 探される。CC_DEF_PATH には環境変数 PATH などと同じく複数の + * ディレクトリを ':' で区切って指定することができる。 * なければ CCDEFPATH (/usr/lib/X11/ccdef) の下が探される。 * 同じ変換ファイルに対して複数回 ccParseRule() を行なっても、 * 実際に読み込まれるのは最初の一回だけである。 *************** *** 477,483 **** */ #ifndef lint ! static char *rcsid = "$Id: cconv.c,v 8.0 89/10/27 20:23:48 ishisone Rel $"; #endif #include --- 494,500 ---- */ #ifndef lint ! static char *rcsid = "$Id: cconv.c,v 8.3 90/02/16 20:11:15 ishisone Exp $"; #endif #include *************** *** 836,843 **** --- 853,882 ---- FILE *fp; char filename[1024]; FILE *fopen(); + char *getenv(); if ((fp = fopen(file, "r")) == NULL && *file != '/') { + char *p, *q; + /* 環境変数 CC_DEF_PATH があればそのパスの下を + * サーチする + */ + if ((p = getenv("CC_DEF_PATH")) != NULL) { + while (*p != '¥0') { + q = filename; + while (*p != '¥0' && *p != ':') + *q++ = *p++; + if (*p == ':') p++; + if (q == filename) continue; + *q++ = '/'; + *q = '¥0'; + (void)Strcat(filename, file); + if ((fp = fopen(filename, "r")) != NULL) + return fp; + } + } + /* デフォルトのサーチパス CCDEFPATH(/usr/lib/X11/ccdef) の + * 下をサーチする + */ (void)Strcpy(filename, CCDEFPATH); (void)Strcat(filename, file); fp = fopen(filename, "r"); *************** *** 871,876 **** --- 910,916 ---- } if ((files->fp[++files->index] = openfile(name)) == NULL) { eproc(efunc, "can't open %s", name); + --files->index; return -1; } return 0; *************** *** 2124,2136 **** char *p; int nbytes; int n; /* とりあえず LookupString しておく */ ! nbytes = XLookupString(event, str, sizeof(str), 0, 0); /* まずはイベントコードで変換してみる */ ! r = convchar(buf, ccEncodeKey(event), ccEncodeMask(event), ! str, nbytes); if (r < 0) { /* ASCII 表記で変換してみる */ p = str; --- 2164,2201 ---- char *p; int nbytes; int n; + KeySym ks1, ks2; + int mask; /* とりあえず LookupString しておく */ ! nbytes = XLookupString(event, str, sizeof(str), &ks2, 0); /* まずはイベントコードで変換してみる */ ! r = -1; ! mask = ccEncodeMask(event); ! ! /* まずはモディファイアを一際考慮しない KeySym を ! * コードとして変換してみる ! */ ! ks1 = (ulong)XLookupKeysym(event, 0); ! if (ks1 != NoSymbol) { ! r = convchar(buf, (ulong)ks2 | (ulong)RAWKEY, ! mask, str, nbytes); ! } ! ! /* 上がマッチしなければ、Shift, Lock, ModeSwitch を ! * 考慮した KeySym (つまり XLookupString() が返す KeySym) が ! * NoSymbol でなければそのコードで変換してみる ! */ ! if (r < 0 && ks2 != NoSymbol && ks2 != ks1) { ! mask &= ‾(ShiftMask | LockMask | event->display->mode_switch); ! r = convchar(buf, (ulong)ks2 | (ulong)RAWKEY, ! mask, str, nbytes); ! } ! ! if (r < 0) { ! } ! if (r < 0) { /* ASCII 表記で変換してみる */ p = str; diff -r -c ../../R4/kinput/jclib/jclib.c ./jclib/jclib.c *** ../../R4/kinput/jclib/jclib.c Thu Nov 2 22:29:25 1989 --- ./jclib/jclib.c Mon Feb 26 13:25:14 1990 *************** *** 412,418 **** */ #ifndef lint ! static char *rcsid = "$Header: jclib.c,v 1.1 89/11/02 08:29:33 jim Exp $"; #endif #ifdef DEBUG --- 412,418 ---- */ #ifndef lint ! static char *rcsid = "$Header: /private/usr/mmb/ishisone/src/jclib/RCS/jclib.c,v 4.0 89/10/27 20:15:01 ishisone Rel $"; #endif #ifdef DEBUG diff -r -c ../../R4/kinput/jclib/jilib.c ./jclib/jilib.c *** ../../R4/kinput/jclib/jilib.c Thu Nov 2 22:28:26 1989 --- ./jclib/jilib.c Mon Feb 26 13:25:16 1990 *************** *** 1,6 **** /* * jilib -- かな漢字変換用ライブラリ (Wnn Version4.0 対応版) ! * version 4.1 * ishisone@sra.co.jp */ --- 1,6 ---- /* * jilib -- かな漢字変換用ライブラリ (Wnn Version4.0 対応版) ! * version 4.3 * ishisone@sra.co.jp */ *************** *** 90,95 **** --- 90,102 ---- * バージョン番号の修正 * ver 4.1 89/11/02 * SysV でうまくコンパイルできないのを修正 + * --- kinput を R4 に contribute --- + * ver 4.2 89/12/12 + * jiOpenServer() で、server に NULL または "" を指定し、環境変数 + * JSERVER が定義されていない時にコアダンプするバグを修正 + * ver 4.3 90/02/20 + * 頻度ファイルが辞書とマッチしなかった時に、単にエラーにする + * 代わりに頻度ファイルを作り直すように変更 */ /* *************** *** 180,186 **** */ #ifndef lint ! static char *rcsid = "$Header: jilib.c,v 1.1 89/11/02 08:28:30 jim Exp $"; #endif #include --- 187,193 ---- */ #ifndef lint ! static char *rcsid = "$Header: /private/usr/mmb/ishisone/src/jclib/RCS/jilib.c,v 4.3 90/02/20 14:35:08 ishisone Exp $"; #endif #include *************** *** 262,267 **** --- 269,275 ---- static int mkdirproc(WNN_ENV *, int, char *); static int createDicFile(WNN_ENV *, char *, char *, char *); static int createHindoFile(WNN_ENV *, char *, int, char *); + static int removeFile(WNN_ENV *, char *, int, char *); static char *getdicpasswd(char *); static int fileLoad(WNN_ENV *, CallbackRec *, int, char *, char *, char *, int, int *); *************** *** 624,629 **** --- 632,653 ---- } } + static int + removeFile(env, file, fid, passwd) + WNN_ENV *env; + char *file; + int fid; + char *passwd; + { + if (fid >= 0) (void)js_file_discard(env, fid); + + if (*file == C_LOCAL) { + return js_file_remove_client(env->js_id, file + 1, passwd); + } else { + return js_file_remove(env->js_id, file, passwd); + } + } + /* getdicpasswd -- 指定されたファイルからパスワードを取り出す */ static char * getdicpasswd(file) *************** *** 961,966 **** --- 985,991 ---- } PRINT(("jiOpenServer(): servername=%s¥n", servername ? servername : "")); + if (servername == NULL) servername = "unix"; /* unix domain */ return useServer(servername, timeout); } *************** *** 1259,1264 **** --- 1284,1290 ---- return 0; } + re_create: if (hindofilename) { /* 頻度ファイルが指定されている時、 * confirm されないために頻度ファイルが作られなかったならば *************** *** 1279,1284 **** --- 1305,1357 ---- if (js_dic_add(env, dicid, hindoid, rev, prio, dicro, hindoro, dicpasswd, hindopasswd) < 0) { + /* + * もし、辞書と頻度ファイルがマッチしなかったときには、 + * いきなりエラーにせず、頻度ファイルを作り直すかどうか + * 尋ねるようにする + */ + if (wnn_errorno == WNN_HINDO_NO_MATCH) { + int retry = 0; + + error(cbrec, TYPE_WARNING, + "setdic: hindo (%s) doesn't match with dic (%s)", + hindofilename, dicfilename); + + switch (*confirmp) { + case NO_CREATE: + break; + case CONFIRM: + if (doconfirm(cbrec, TYPE_HINDO, + hindofilename)) { + retry = 1; + } + break; + case CONFIRM1: + if (doconfirm(cbrec, TYPE_HINDO, + hindofilename)) { + *confirmp = CREATE_WITHOUT_CONFIRM; + retry = 1; + } else { + *confirmp = NO_CREATE; + } + break; + default: /* CREATE_WITHOUT_CONFIRM */ + retry = 1; + break; + } + + /* 一度頻度ファイルを消して、もう一度ロードする */ + if (retry) { + if (removeFile(env, hindofilename, + hindoid, hindopasswd) < 0) { + error(cbrec, TYPE_ERROR, + "setdic: can't remove hindo (%s)", + hindofilename); + } else { + goto re_create; + } + } + } error(cbrec, TYPE_ERROR, "setdic: can't add dic (%s)", dicfilename); return -1; diff -r -c ../../R4/kinput/xlocal/XWStr.h ./xlocal/XWStr.h *** ../../R4/kinput/xlocal/XWStr.h Tue Oct 31 16:28:58 1989 --- ./xlocal/XWStr.h Mon Feb 26 13:25:30 1990 *************** *** 20,26 **** * ishisone@sra.co.jp */ ! /* $Header: /private/usr/mmb/ishisone/job/x11/xlocal/RCS/XWStr.h,v 1.5 89/09/12 10:13:35 ishisone Rel $ */ #ifndef _XWStr_h #define _XWStr_h --- 20,26 ---- * ishisone@sra.co.jp */ ! /* $Header: /private/usr/mmb/ishisone/job/x11/xlocal/RCS/XWStr.h,v 1.6 90/01/25 18:44:19 ishisone Exp $ */ #ifndef _XWStr_h #define _XWStr_h *************** *** 48,54 **** #if __STDC__ == 1 /* function prototype */ ! extern XWSGC XWSSetGCSet(GC, GC, GC, GC); #ifdef _XtIntrinsic_h extern XWSGC XtWSGetGCSet(Widget, unsigned long, XGCValues *, XFontStruct *, XFontStruct *, --- 48,54 ---- #if __STDC__ == 1 /* function prototype */ ! extern XWSGC XWSSetGCSet(Display *, GC, GC, GC, GC); #ifdef _XtIntrinsic_h extern XWSGC XtWSGetGCSet(Widget, unsigned long, XGCValues *, XFontStruct *, XFontStruct *, diff -r -c ../../R4/kinput/xlocal/wconvert.c ./xlocal/wconvert.c *** ../../R4/kinput/xlocal/wconvert.c Tue Oct 31 16:28:59 1989 --- ./xlocal/wconvert.c Mon Feb 26 13:25:32 1990 *************** *** 20,26 **** * ishisone@sra.co.jp */ ! /* $Header: /private/usr/mmb/ishisone/job/x11/xlocal/RCS/wconvert.c,v 1.5 89/09/12 10:14:04 ishisone Rel $ */ #include "WStr.h" --- 20,26 ---- * ishisone@sra.co.jp */ ! /* $Header: /private/usr/mmb/ishisone/job/x11/xlocal/RCS/wconvert.c,v 1.6 89/11/30 16:54:31 ishisone Rel $ */ #include "WStr.h" *************** *** 39,44 **** --- 39,45 ---- n++; } } + *ls = '¥0'; } else { while (c = *ws++) { if ((c & 0x8080) == 0) *************** *** 68,73 **** --- 69,75 ---- n++; } } + *ws = '¥0'; } else { while (c = *ls++) { if (c < 0x80 || c == 0xa5 || c == 0xa6) diff -r -c ../../R4/kinput/xlocal/xwstr.c ./xlocal/xwstr.c *** ../../R4/kinput/xlocal/xwstr.c Tue Oct 31 16:29:00 1989 --- ./xlocal/xwstr.c Mon Feb 26 13:25:34 1990 *************** *** 66,72 **** */ #ifndef lint ! static char *rcsid = "$Header: /private/usr/mmb/ishisone/job/x11/xlocal/RCS/xwstr.c,v 1.7 89/09/12 10:14:20 ishisone Rel $"; #endif #include --- 66,72 ---- */ #ifndef lint ! static char *rcsid = "$Header: /private/usr/mmb/ishisone/job/x11/xlocal/RCS/xwstr.c,v 1.8 90/01/25 18:43:39 ishisone Exp $"; #endif #include *************** *** 97,103 **** static int (*drawstr16func)(); XWSGC ! XWSSetGCSet(gc0, gc1, gc2, gc3) GC gc0; GC gc1; GC gc2; --- 97,104 ---- static int (*drawstr16func)(); XWSGC ! XWSSetGCSet(dpy, gc0, gc1, gc2, gc3) ! Display *dpy; GC gc0; GC gc1; GC gc2; *************** *** 120,126 **** gcset->fe[i].font = NULL; } else { XFontStruct *font; ! gcset->fe[i].font = font = XQueryFont(gcset->fe[i].gc); gcset->fe[i].flag = FONTQUERY; if (IS2B(font)) gcset->fe[i].flag = TWOB; --- 121,127 ---- gcset->fe[i].font = NULL; } else { XFontStruct *font; ! gcset->fe[i].font = font = XQueryFont(dpy, gcset->fe[i].gc->gid); gcset->fe[i].flag = FONTQUERY; if (IS2B(font)) gcset->fe[i].flag = TWOB; *************** *** 259,268 **** if (cp >= cpend - 2) { /* flush */ if (is2b) ! width += XTextWidth16(fe->font, buf, (cp - buf) / 2); else ! width += XTextWidth(fe->font, buf, (cp - buf)); cp = buf; } --- 260,271 ---- if (cp >= cpend - 2) { /* flush */ if (is2b) ! width += XTextWidth16(fe->font, ! (XChar2b *)buf, (cp - buf) / 2); else ! width += XTextWidth(fe->font, ! (char *)buf, (cp - buf)); cp = buf; } *************** *** 277,285 **** /* flush */ if (is2b) ! width += XTextWidth16(fe->font, buf, (cp - buf) / 2); else ! width += XTextWidth(fe->font, buf, (cp - buf)); } return width; --- 280,289 ---- /* flush */ if (is2b) ! width += XTextWidth16(fe->font, (XChar2b *)buf, ! (cp - buf) / 2); else ! width += XTextWidth(fe->font, (char *)buf, (cp - buf)); } return width; *************** *** 346,356 **** if (cp >= cpend - 2) { /* flush */ if (is2b) ! XTextExtents16(fe->font, buf, (cp - buf) / 2, &dir, &as, &ds, &oa); else ! XTextExtents(fe->font, buf, cp - buf, &dir, &as, &ds, &oa); cp = buf; *ascent = MAX(*ascent, as); --- 350,362 ---- if (cp >= cpend - 2) { /* flush */ if (is2b) ! XTextExtents16(fe->font, ! (XChar2b *)buf, (cp - buf) / 2, &dir, &as, &ds, &oa); else ! XTextExtents(fe->font, ! (char *)buf, cp - buf, &dir, &as, &ds, &oa); cp = buf; *ascent = MAX(*ascent, as); *************** *** 374,383 **** /* flush */ if (is2b) ! XTextExtents16(fe->font, buf, (cp - buf) / 2, ! &dir, &as, &ds, &oa); else ! XTextExtents(fe->font, buf, (cp - buf), &dir, &as, &ds, &oa); *ascent = MAX(*ascent, as); *descent = MAX(*descent, ds); --- 380,390 ---- /* flush */ if (is2b) ! XTextExtents16(fe->font, (XChar2b *)buf, ! (cp - buf) / 2, ! &dir, &as, &ds, &oa); else ! XTextExtents(fe->font, (char *)buf, (cp - buf), &dir, &as, &ds, &oa); *ascent = MAX(*ascent, as); *descent = MAX(*descent, ds); *************** *** 483,492 **** if (fe->flag & TWOB) { (*drawstr16func)(d, w, fe->gc, x, y, cp0, (cp1 - cp0) / 2); ! return XTextWidth16(fe->font, cp0, (cp1 - cp0) / 2); } else { (*drawstrfunc)(d, w, fe->gc, x, y, cp0, cp1 - cp0); ! return XTextWidth(fe->font, cp0, cp1 - cp0); } /* NOTREACHED */ } --- 490,499 ---- if (fe->flag & TWOB) { (*drawstr16func)(d, w, fe->gc, x, y, cp0, (cp1 - cp0) / 2); ! return XTextWidth16(fe->font, (XChar2b *)cp0, (cp1 - cp0) / 2); } else { (*drawstrfunc)(d, w, fe->gc, x, y, cp0, cp1 - cp0); ! return XTextWidth(fe->font, (char *)cp0, cp1 - cp0); } /* NOTREACHED */ }