mule 2.3 XIM 日本語入力パッチ 10/30/1995 このパッチは mule 2.3 で XIM を使うための非公式パッチです。基本的 には X11R5/Ximp または X11R6/XIM で動作すると思いますが、現在動作 確認がとれているのは、以下の環境です。 動作確認: (1) HP 9000 715/100 HP-UX 9.05 atok8: ATOK8 Ver.1.0 /R.1.2 for HP-UX (C)1993 JUSTSYSTEM CORP. (Ver.1.0 /R.1 の atok8 はフォントセットの表示に不具合があります) XMODIFIERS='@im=_XIMP_japanese#atok8.0' kinput2 でも動作確認されています。 XMODIFIERS='@im=_XIMP_ja_JP#kinput2.0' (2) 富士通 S-4/10 model41 Solaris 2.4J / OpenWindows 3.4 ATOK7 XMODIFIERS の設定なし (3) PC/AT 互換機 Linux 1.3.30 X11R6 / kinput2 v2.fix1 XMODIFIERS='@im=kinput2' 1. パッチの概要 Hideki.Hiura@Eng.Sun.COM さんによるパッチ (mule-jp ML X-Seqno: 5234) をベースにして - XIM のフォントセットの lisp からのコントロール - mule 2.3 への対応 - configure に対する --xim オプション - memory leak の解消、数点の bug fix - resource による style の決定の bug fix - 文字化け、入力拒否の bug fix - delete-frame 時の Input Context の解放 - X11R6 コンパイル時のエラー解消 等をしています。 パッチを当てた mule は、configure に --xim オプションが指定され ると、変数 XIM が定義されます。このとき、primary-environment が japanese であれば、mule-init.el で xim-locale-lc-list が (setq xim-locale-lc-list '(lc-jp lc-jp2 lc-jpold lc-roman lc-kana)) として定義されます。ここに定義された LC に対するフォントが、IM に渡されます。(ただし、実際に IM がそれを使うかどうかは locale によりますから、余計なものを渡しても意味はありません)各 frame の 使うフォントに変更があった場合にも、IM には新しいサイズのフォン トが渡されます。 したがって、論理的には、たとえば primary-environment が korean のときには該当する locale で mule を起動して (setq xim-locale-lc-list '(lc-kr lc-roman)) とすれば韓国語の IM も利用できるはず(と思う ^^;)ですが、パッチに はこうした設定は入っていません。 2. フォントセットの定義 XIM パッチを使う場合は、mule の使うフォントセットを明示的に定義 してください。そうでない場合は、IM の使うフォントに変なスケーラ ブルフォントが使われて表示が崩れるかもしれません。 (例) Emacs*FontSetList: 16,14,24 Emacs*FontSet-14: -*-Fixed-Medium-R-Normal--14-*-ISO8859-1,\ -*-song-medium-r-*--14-*-gb2312.1980-*,\ -*-fixed-medium-r-*--14-*-jisx0201.1976-*,\ -*-fixed-medium-r-*--14-*-jisx0208.1983-*,\ -*-mincho-medium-r-*--14-*-ksc5601.1987-* Emacs*FontSet-16: -*-Fixed-Medium-R-Normal--16-*-ISO8859-1,\ -*-song-medium-r-*--16-*-gb2312.1980-*,\ -*-fixed-medium-r-*--16-*-jisx0201.1976-*,\ -*-fixed-medium-r-*--16-*-jisx0208.1983-*,\ -*-mincho-medium-r-*--16-*-ksc5601.1987-* Emacs*FontSet-24: -*-Fixed-Medium-R-Normal--24-*-ISO8859-1,\ -*-song-medium-r-*--24-*-gb2312.1980-*,\ -*-fixed-medium-r-*--24-*-jisx0201.1976-*,\ -*-fixed-medium-r-*--24-*-jisx0208.1983-*,\ -*-mincho-medium-r-*--24-*-ksc5601.1987-* 3. IM のスタイルの定義 Emacs.ximStyle というリソースで IM の入力スタイルをコントロール できます。何が設定できるかは、IM サーバがサポートするスタイルに 依存しますが、複数のスタイルをリソースで設定しておけば、IM のサ ポートするスタイルにあわせて自動的に設定順の優先度で選択されま す。ただし、このパッチによる mule がサポートするのは over-the-spot と root-window タイプです。 (例) Emacs.ximStyle: XIMPreeditPosition|XIMStatusNothing,\ XIMPreeditNothing|XIMStatusNothing 何が設定できるかは、X11/Xlib.h を見てください。わからない人は設 定しなくて良いです。"|"文字の前後にスペース等は入れてはいけませ ん。 4. keyboard-coding-system 利用する locale で入力される coding-system を定義してください。 例えば、HP では LANG=japanese のときに atok8 は SJIS による入力 になりますから、 (set-keyboard-coding-system *sjis*) というのを site-init.el なり ~/.emacs なりに書いておく必要があ ります。 5. 漢字 ON/OFF キーの設定 これは IM 側で設定します。IM に横取りされるキーは mule で認識で きなくなるので注意してください。例えば HP の atok8 では Atok8*ConversionStartKeys: Shiftspace というリソースを設定しておくことで shift-space を漢字 ON/OFF と して使うことができます。kinput2 も同様なリソースを持っています。 Solaris では Control-space 固定のようです。この場合、mule 側で set-mark-command が効かなくなりますので、set-mark-command に別の キーを使うように設定する必要があります。 6. パッチを当てたのに XIM が使えない LANG, LC_ALL, XMODIFIERS などの設定が正しくできているかどうか、 確認してください。これらの環境変数の設定は、基本的に他の XIM ク ライアントと同じです。OS によっては設定しなくて良い場合もありま す。 -DX_LOCALE で build された libX11 を使う場合は、-DX_LOCALE をつ けて mule をコンパイルしてください。これが正しく設定できていない 場合は、setlocale() で失敗して、mule が起動しません。_DX_LOCALE については、まだ configure スクリプトで判定するようにはなってい ませんので、ご注意を (^^; mule のコンパイルに vendor の供給した libX11 を使っていることを 確認してください。特に、自分で build した X11R6 を使っているよう な場合は、vendor の供給している X11R5 の Input Method は使えませ ん。明示的に X11R6 のライブラリを使っているわけではない場合でも、 たとえば --wnn-libraries= で指定したディレクトリに libX11.a があ り、こちらが先に使われてしまった、などというのはよくある話です。 コンパイルのログ等をよく調べてみてください。 Solaris では Xlib に /usr/openwin/lib/libX11.so を使ってください。 static library は Ximp のプロトコルドライバが入っていません。 7. その他、追加情報 http://www.st.rim.or.jp/~masaoki/atok.html をごらんください。 動作確認の報告も、よろしくお願いします。 ------------------------------------------------------------------ diff -urN mule-2.3/configure mule-2.3-xim/configure --- mule-2.3/configure Tue Jul 25 13:41:53 1995 +++ mule-2.3-xim/configure Mon Oct 23 13:00:19 1995 @@ -131,6 +131,7 @@ --canna Use CANNA to input Japanese. --canna-includes=DIR Search for CANNA header files in DIR. --canna-libraries=DIR Search for CANNA libraries in DIR. +--xim Use XIM. --bdf-path=DIRS Search for bdf fonts in DIRS. --valbits=NN Set extra VALBITS to NN. --x-app-default-path=DIRS Search for X resources in DIRS. @@ -254,7 +255,8 @@ ## --mcpath: Use MCPATH feature. ## --canna: Use canna. ## --sj3: Use sj3-egg. - "terminal_face" | "mcpath" | "canna" | "sj3" ) + ## --xim: Use XIM. + "terminal_face" | "mcpath" | "canna" | "sj3" | "xim" ) ## Make sure the value given was either "yes" or "no". case "${val}" in y | ye | yes ) val=yes ;; @@ -3467,6 +3469,20 @@ ac_sed_defs="${ac_sed_defs}\${ac_dA}WNN\${ac_dB}WNN\${ac_dC}1\${ac_dD} \${ac_uA}WNN\${ac_uB}WNN\${ac_uC}1\${ac_uD} \${ac_eA}WNN\${ac_eB}WNN\${ac_eC}1\${ac_eD} +" +} + +fi +if [ "${xim}" = "yes" ] ; then + +{ +test -n "$verbose" && \ +echo " defining XIM" +echo "#define" XIMMULE "1" >> confdefs.h +DEFS="$DEFS -DXIMMULE=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}XIMMULE\${ac_dB}XIMMULE\${ac_dC}1\${ac_dD} +\${ac_uA}XIMMULE\${ac_uB}XIMMULE\${ac_uC}1\${ac_uD} +\${ac_eA}XIMMULE\${ac_eB}XIMMULE\${ac_eC}1\${ac_eD} " } diff -urN mule-2.3/configure.in mule-2.3-xim/configure.in --- mule-2.3/configure.in Tue Jul 25 13:41:54 1995 +++ mule-2.3-xim/configure.in Mon Oct 23 13:00:20 1995 @@ -135,6 +135,7 @@ --canna Use CANNA to input Japanese. --canna-includes=DIR Search for CANNA header files in DIR. --canna-libraries=DIR Search for CANNA libraries in DIR. +--xim Use XIM. --bdf-path=DIRS Search for bdf fonts in DIRS. --valbits=NN Set extra VALBITS to NN. --x-app-default-path=DIRS Search for X resources in DIRS. @@ -258,7 +259,8 @@ ## --mcpath: Use MCPATH feature. ## --canna: Use canna. ## --sj3: Use sj3-egg. - "terminal_face" | "mcpath" | "canna" | "sj3" ) + ## --xim: Use XIM. + "terminal_face" | "mcpath" | "canna" | "sj3" | "xim" ) ## Make sure the value given was either "yes" or "no". case "${val}" in y | ye | yes ) val=yes ;; @@ -1837,6 +1839,9 @@ fi if [ "${wnn}" = "yes" ] ; then ] AC_DEFINE(WNN) [ +fi +if [ "${xim}" = "yes" ] ; then + ] AC_DEFINE(XIMMULE) [ fi if [ "${wnn4}" = "yes" ] ; then ] AC_DEFINE(WNN4) [ diff -urN mule-2.3/lisp/mule-init.el mule-2.3-xim/lisp/mule-init.el --- mule-2.3/lisp/mule-init.el Tue Jul 25 13:42:02 1995 +++ mule-2.3-xim/lisp/mule-init.el Mon Oct 23 13:00:21 1995 @@ -488,6 +488,10 @@ (its:get-mode-map "zenkaku-upcase")) its:*standard-modes*)))) +;; XIM specific setup +(if (boundp 'XIM) + (setq xim-locale-lc-list '(lc-jp lc-jp2 lc-jpold lc-roman lc-kana))) + (defun set-japanese-environment () (setq *coding-category-iso-8-2* '*euc-japan*) diff -urN mule-2.3/lisp/term/x-win.el mule-2.3-xim/lisp/term/x-win.el --- mule-2.3/lisp/term/x-win.el Tue Jul 25 13:42:05 1995 +++ mule-2.3-xim/lisp/term/x-win.el Mon Oct 23 13:00:21 1995 @@ -770,6 +770,11 @@ (nreverse (cons x-default-fontset namelist))) (setq default-frame-alist (append default-frame-alist (list (cons 'font (car namelist)))))) + +(defvar xim-locale-lc-list nil + "List of required character set for XIM input context. +This list must contain all character sets needed for your X11 locale.") + ;; end of patch ;; Check the reverseVideo resource. diff -urN mule-2.3/src/config.h.in mule-2.3-xim/src/config.h.in --- mule-2.3/src/config.h.in Tue Jul 25 13:42:08 1995 +++ mule-2.3-xim/src/config.h.in Mon Oct 23 13:00:20 1995 @@ -161,6 +161,7 @@ #undef C_SWITCH_CANNA /* compile switch for Canna */ #undef LD_SWITCH_CANNA /* link switch for Canna */ #undef LD_SWITCH_CANNA_AUX /* link switch for Canna if -R option is needed */ +#undef XIMMULE /* flag whether to use XIM */ #undef BDF_PATH /* bdf font path */ #undef USE_MCPATH diff -urN mule-2.3/src/dispnew.c mule-2.3-xim/src/dispnew.c --- mule-2.3/src/dispnew.c Wed Mar 15 11:37:25 1995 +++ mule-2.3-xim/src/dispnew.c Mon Oct 23 13:00:20 1995 @@ -2158,7 +2158,7 @@ newheight - FRAME_MENU_BAR_LINES (frame), 0); if (FRAME_TERMCAP_P (frame) && !pretend) - FrameRows = newheight; + set_terminal_window(FrameRows = newheight); #if 0 if (frame->output_method == output_termcap) diff -urN mule-2.3/src/mule.c mule-2.3-xim/src/mule.c --- mule-2.3/src/mule.c Tue Jul 25 13:42:09 1995 +++ mule-2.3-xim/src/mule.c Mon Oct 23 13:00:20 1995 @@ -9,6 +9,7 @@ #include "window.h" Lisp_Object VMULE, VEGG, VWNN, VSJ3; /* 92.7.8 by K.Handa and Y.Kawabe */ +Lisp_Object VXIM; /* 95.6.1 by S.Tomura */ Lisp_Object Vre_word; @@ -101,6 +102,10 @@ #endif /* SJ3 */ #endif /* not WNN */ #endif /* EGG */ +#ifdef XIMMULE + DEFVAR_LISP ("XIM", &VXIM, ""); + VXIM = Qt; +#endif /* XIMMULE */ } #ifdef MULE_DEBUG diff -urN mule-2.3/src/xfns.c mule-2.3-xim/src/xfns.c --- mule-2.3/src/xfns.c Thu Dec 29 13:19:39 1994 +++ mule-2.3-xim/src/xfns.c Thu Oct 26 15:15:39 1995 @@ -28,6 +28,7 @@ #include #endif + /* This makes the fields of a Display accessible, in Xlib header files. */ #define XLIB_ILLEGAL_ACCESS @@ -44,6 +45,26 @@ #include "keyboard.h" #include "blockinput.h" +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ +# include +# ifndef INHIBIT_STRING_HEADER +# if HAVE_STRING_H || STDC_HEADERS +# include +# ifndef bcmp +# define bcmp(s1, s2, n) memcmp ((s1), (s2), (n)) +# endif /* bcmp */ +# ifndef bcopy +# define bcopy(s, d, n) memcpy ((d), (s), (n)) +# endif /* bcopy */ +# ifndef bzero +# define bzero(s, n) memset ((s), 0, (n)) +# endif /* bzero */ +# else /* HAVE_STRING_H || STDC_HEADERS */ +# include +# endif /* HAVE_STRING_H || STDC_HEADERS */ +# endif /* INHIBIT_STRING_HEADER */ +#endif /* XIMMULE */ + #ifdef HAVE_X_WINDOWS extern void abort (); @@ -165,6 +186,9 @@ extern Atom Xatom_font_pixel_size; extern Atom Xatom_font_baseline_offset; extern Atom Xatom_font_relative_compose; +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ +extern XIM im ; +#endif /* XIMMULE */ #endif /* MULE */ #else /* X10 */ @@ -310,6 +334,10 @@ || f->display.x->icon_desc == wdesc) return f; #else /* not USE_X_TOOLKIT */ +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + if (f->display.nothing == 1) + return 0; +#endif if (FRAME_X_WINDOW (f) == wdesc || f->display.x->icon_desc == wdesc) return f; @@ -1990,6 +2018,294 @@ } #endif +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ +/* + * Fallback default + */ +#define DEFAULTStyle (XIMPreeditNothing|XIMStatusNothing) + +typedef struct _style_cache { + struct _style_cache *next ; + char *locale ; + XIM im ; + XrmDatabase rdb; + char *res_name ; + char *res_class ; + XIMStyle best_style ; + XIMStyles *user_styles ; + XIMStyles *im_dep_styles ; + XIMStyles *lc_dep_styles ; +} style_cache_t ; + +static XIMStyles *str_to_im_styles(); +static XIMStyle best_style(); + +static XIMStyle +determine_style(im, rdb, res_name, res_class, supported_styles) + XIM im; + XrmDatabase rdb; + char *res_name ; + char *res_class ; + XIMStyles *supported_styles ; +{ + static style_cache_t *p = 0 ; + static XIMStyles *lc_dep_styles = 0 ; + char *res_style; + + if(!p){ + if((p = (style_cache_t *)calloc(sizeof(style_cache_t),1))==NULL) { + return DEFAULTStyle; + } + } else { + /* + * check the cache first + */ + XIMStyles *lc_dep_styles = 0 ; + char *locale = setlocale(LC_CTYPE, NULL); + for(;;) { + if(!strcmp(p->locale, locale)){ + if(p->im == im && + p->rdb == rdb && + !strcmp(p->res_name, res_name) && + !strcmp(p->res_class, res_class)) { + return p->best_style; + } + lc_dep_styles = p->lc_dep_styles ; + } + if (p->next){ + p = p->next ; + } else { + break ; + } + } + if((p->next = (style_cache_t *)calloc(sizeof(style_cache_t),1))==NULL) { + return DEFAULTStyle; + } + p = p->next ; + if(lc_dep_styles){ + p->lc_dep_styles = lc_dep_styles ; + } + } + /* + * first time for this combination + */ + p->locale = strdup(setlocale(LC_CTYPE, NULL)); + p->im = im ; + p->rdb = rdb ; + p->res_name = strdup(res_name); + p->res_class = strdup(res_class); + XGetIMValues(im, XNQueryInputStyle, &p->im_dep_styles, NULL); + + if((res_style = x_get_string_resource(rdb, res_name, res_class)) != NULL){ + /* + * We should use user's priority list + */ + int size = strlen(res_style); + p->user_styles = str_to_im_styles(size, res_style); + p->best_style = best_style(p->user_styles, p->im_dep_styles, supported_styles) ; + xfree(p->user_styles->supported_styles); + xfree(p->user_styles); + } else { + /* + * + */ + if(!p->lc_dep_styles){ + /* + * Ideally, it should use the system's per-locale priority list + * if avairable, but non of the systems provides it at + * this moment, use preferable order listed in supported_styles. + */ + p->lc_dep_styles = supported_styles ; + p->best_style= best_style(p->lc_dep_styles, p->im_dep_styles, supported_styles) ; + } + } + return p->best_style; +} + +#define MAXSTYLES 20 +/* + * This structure maps the input style name that a user or a system + * specifiy to the XIMStyle value. + */ +static +struct _XIMStyleRec { + XIMStyle style ; + char *name ; + int namelen ; +} XIMStyleRec[] = { +XIMPreeditCallbacks|XIMStatusArea,"XIMPreeditCallbacks|XIMStatusArea",33, +XIMPreeditCallbacks|XIMStatusNothing,"XIMPreeditCallbacks|XIMStatusNothing",36, +XIMPreeditCallbacks|XIMStatusNone,"XIMPreeditCallbacks|XIMStatusNone",33, +XIMPreeditCallbacks|XIMStatusCallbacks,"XIMPreeditCallbacks|XIMStatusCallbacks",38, +XIMPreeditPosition|XIMStatusArea,"XIMPreeditPosition|XIMStatusArea",32, +XIMPreeditPosition|XIMStatusNothing,"XIMPreeditPosition|XIMStatusNothing",35, +XIMPreeditPosition|XIMStatusNone,"XIMPreeditPosition|XIMStatusNone",32, +XIMPreeditPosition|XIMStatusCallbacks,"XIMPreeditPosition|XIMStatusCallbacks",37, +XIMPreeditArea|XIMStatusArea,"XIMPreeditArea|XIMStatusArea",28, +XIMPreeditArea|XIMStatusNothing,"XIMPreeditArea|XIMStatusNothing",31, +XIMPreeditArea|XIMStatusNone,"XIMPreeditArea|XIMStatusNone",28, +XIMPreeditArea|XIMStatusCallbacks,"XIMPreeditArea|XIMStatusCallbacks",33, +XIMPreeditNothing|XIMStatusArea,"XIMPreeditNothing|XIMStatusArea",31, +XIMPreeditNothing|XIMStatusNothing,"XIMPreeditNothing|XIMStatusNothing",34, +XIMPreeditNothing|XIMStatusNone,"XIMPreeditNothing|XIMStatusNone",31, +XIMPreeditNothing|XIMStatusCallbacks,"XIMPreeditNothing|XIMStatusCallbacks",36, +XIMPreeditNone|XIMStatusArea,"XIMPreeditNone|XIMStatusArea",28, +XIMPreeditNone|XIMStatusNothing,"XIMPreeditNone|XIMStatusNothing",31, +XIMPreeditNone|XIMStatusNone,"XIMPreeditNone|XIMStatusNone",28, +XIMPreeditNone|XIMStatusCallbacks,"XIMPreeditNone|XIMStatusCallbacks",33, +} ; + +/* + * Convert the string containing the input style priority list + * in the format like + * +XIMPreeditPosition|XIMStatusArea +XIMPreeditPosition|XIMStatusNothing +XIMPreeditArea|XIMStatusArea +XIMPreeditArea|XIMStatusNothing +XIMPreeditNothing|XIMStatusArea +XIMPreeditNothing|XIMStatusNothing + * + * to the XIMStyles structure. + * + */ +static XIMStyles * +str_to_im_styles(size, s) + int size ; + char *s ; +{ + XIMStyles *p = (XIMStyles *)xmalloc(sizeof(XIMStyles),1); + char *delimiter = " \t\n\r:;," ; + register int i ; + register char *c ; + register char *end = s + size ; + + p->count_styles = 0 ; + p->supported_styles = (XIMStyle *)xmalloc(sizeof(XIMStyle), MAXSTYLES); + /* + * The following routine assumes that the style name listed in InputStyle + * file is identical with the programatic name of style. + * for example, "XIMPreeditPosition|XIMStatusArea" means the + * XIMPreeditPosition|XIMStatusArea value is specified. + * If the style name is changed, such as "OverTheSpot|imDisplaysInClient", + * the parsing logic below should be modified as well. + */ + for(c = strtok(s, delimiter) ; c < end ;){ + for(i=0;icount_styles++ ; + p->supported_styles[p->count_styles-1] = XIMStyleRec[i].style ; + break ; + } + } + if(!(c = strtok(NULL, delimiter))){ + break ; + } + } + return p; +} +/* + * Choose the best style + */ +static XIMStyle +best_style(prio_order, im_support, client_support) + XIMStyles *prio_order ; + XIMStyles *im_support ; + XIMStyles *client_support ; +{ + register unsigned short i, j, k ; + register XIMStyle best_style = DEFAULTStyle ; + for (i = 0 ; icount_styles ; i++){ + best_style = prio_order->supported_styles[i]; + for (j = 0 ; jcount_styles ; j++){ + if(im_support->supported_styles[j] == best_style ){ + for (k = 0 ; kcount_styles ; k++){ + if(client_support->supported_styles[k] == best_style ){ + return best_style; + } + } + } + } + } + return DEFAULTStyle ; +} + +static XIMStyle supported_styles[] = { + XIMPreeditPosition|XIMStatusNothing, + XIMPreeditPosition|XIMStatusNone, + XIMPreeditNothing|XIMStatusNothing, + XIMPreeditNothing|XIMStatusNone, + XIMPreeditNone|XIMStatusNothing, + XIMPreeditNone|XIMStatusNone, + 0 +} ; + +XIC +create_ic(im, client_window, rdb, res_name, res_class, + pixel_width, pixel_height) +XIM im; +Window client_window ; +XrmDatabase rdb; +char *res_name ; +char *res_class ; +int pixel_width ; +int pixel_height ; +{ + XIC ic ; + static XIMStyle style=0 ; + XPoint xp; + XFontSet xfs; + XRectangle p_rect; + XVaNestedList preedit_a; + char *style_res_name = "ximStyle"; + char *style_res_class = "XimStyle"; + char *xfs_string = /* This is dummy */ + "-*-Fixed-Medium-R-Normal--14-*-ISO8859-1"; + char **dm1, *dm3; + int dm2; + /* + * The input styles supported by this application. + */ + XIMStyles supported_list ; + + if (!im) return NULL; + supported_list.count_styles = 6 ; + supported_list.supported_styles = supported_styles ; + + if(!style){ + char *full_name, *full_class; + full_name = alloca(strlen(res_name) +strlen(style_res_name) +3); + full_class = alloca(strlen(res_class)+strlen(style_res_class)+3); + sprintf(full_name, "%s.%s", res_name, style_res_name); + sprintf(full_class, "%s.%s", res_class, style_res_class); + style = determine_style(im, rdb, full_name, full_class, &supported_list); + } + xfs = XCreateFontSet(x_current_display, xfs_string, &dm1, &dm2, &dm3); + xp.x = xp.y = 0; + p_rect.x = p_rect.y = 0; + p_rect.width = pixel_width; + p_rect.height = pixel_height; + preedit_a = XVaCreateNestedList(NULL, + XNArea,&p_rect, + XNSpotLocation,&xp, + XNFontSet,xfs, + NULL); + + if((ic = XCreateIC(im, + XNInputStyle, style, + XNClientWindow, client_window, + XNFocusWindow, client_window, + XNPreeditAttributes, preedit_a, + NULL)) == NULL){ + error("Cannot create an IC"); + } + XFreeFontSet(x_current_display, xfs); + XFreeStringList(dm1); + XFree(preedit_a); + return ic; +} +#endif /* XIMMULE */ + #ifdef USE_X_TOOLKIT /* Create and set up the X widget for frame F. */ @@ -2154,6 +2470,13 @@ XDefineCursor (XDISPLAY FRAME_X_WINDOW (f), f->display.x->text_cursor); +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + f->display.x->ic = create_ic(im, FRAME_X_WINDOW (f) , xrdb, + class_hints.res_name, EMACS_CLASS, + PIXEL_WIDTH(f), PIXEL_HEIGHT(f)) ; + x_set_ic_fonts(f,f->fontset_id); +#endif /* XIMMULE */ + UNBLOCK_INPUT; if (FRAME_X_WINDOW (f) == 0) @@ -2235,6 +2558,13 @@ XDefineCursor (XDISPLAY FRAME_X_WINDOW (f), f->display.x->text_cursor); +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + f->display.x->ic = create_ic(im, FRAME_X_WINDOW (f) , xrdb, + class_hints.res_name, EMACS_CLASS, + PIXEL_WIDTH(f), PIXEL_HEIGHT(f)) ; + x_set_ic_fonts(f,f->fontset_id); +#endif /* XIMMULE */ + UNBLOCK_INPUT; if (FRAME_X_WINDOW (f) == 0) @@ -2792,6 +3122,9 @@ change_frame_size (f, height, width, 1, 0); XSelectInput (FRAME_X_WINDOW (f), KeyPressed | ExposeWindow | ButtonPressed | ButtonReleased | ExposeRegion | ExposeCopy +#ifdef XIMMULE + | FocusChangeMask +#endif | EnterWindow | LeaveWindow | UnmapWindow ); x_set_resize_hint (f); diff -urN mule-2.3/src/xterm.c mule-2.3-xim/src/xterm.c --- mule-2.3/src/xterm.c Tue Jul 25 13:42:13 1995 +++ mule-2.3-xim/src/xterm.c Fri Oct 27 13:38:17 1995 @@ -137,6 +137,23 @@ #define min(a,b) ((a)<(b) ? (a) : (b)) #define max(a,b) ((a)>(b) ? (a) : (b)) + +/* Double check the pre-required defines for XIM */ +#ifdef XIMMULE +#ifndef MULE +#undef XIMMULE +#endif /* MULE */ +#ifdef XlibSpecificationRelease +#if XlibSpecificationRelease < 5 +#undef XIMMULE +#endif /* XlibSpecificationRelease < 5 */ +#else /* XlibSpecificationRelease */ +#undef XIMMULE +#endif /* XlibSpecificationRelease */ +#endif /* XIMMULE */ +#ifdef XIMMULE +#include +#endif /* XIMMULE */ /* Nonzero means we must reprint all windows because 1) we received an ExposeWindow event @@ -391,6 +408,17 @@ /* Defined in ccl.c */ extern CCL_PROGRAM *x_ccl_programs[128]; #endif /* MULE */ + +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ +#define EMACS_CLASS "Emacs" +#define EMACS_NAME "emacs" +XIM im = NULL; /* Allow only one IM per mule instance. */ +#if XlibSpecificationRelease > 5 +XIMValuesList im_values_list ; +XIMValuesList ic_values_list ; +#endif /* XlibSpecificationRelease > 5 */ +#endif /* XIMMULE */ + /* Starting and ending updates. @@ -3621,6 +3649,10 @@ Atom Xatom_font_baseline_offset; Atom Xatom_font_relative_compose; #endif /* MULE */ +#ifdef XIMMULE +static int copy_buffer_len = 256 ; +static char *copy_buffer=(char*)NULL ; +#endif /* XIMMULE */ /* Record the last 100 characters stored to help debug the loss-of-chars-during-GC problem. */ @@ -3692,6 +3724,10 @@ while (XStuffPending () != 0) { XNextEvent (XDISPLAY &event); +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + if (im && XFilterEvent(&event, None)) + continue; +#endif /* XIMMULE */ event_found = 1; switch (event.type) @@ -4019,10 +4055,16 @@ if (f != 0) { KeySym keysym, orig_keysym; + int modifiers; + +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + Status status = (Status)XLookupNone; + if(!copy_buffer) copy_buffer = (char*)xmalloc(copy_buffer_len); +#else /* XIMMULE */ /* al%imercury@uunet.uu.net says that making this 81 instead of 80 fixed a bug whereby meta chars made his Emacs hang. */ unsigned char copy_buffer[81]; - int modifiers; +#endif /* XIMMULE */ event.xkey.state |= x_emacs_to_x_modifiers (extra_keyboard_modifiers); @@ -4033,15 +4075,44 @@ /* make_lispy_event turns chars into control chars. Don't do it here because XLookupString is too eager. */ event.xkey.state &= ~ControlMask; +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + if(f->display.x->ic){ + nbytes = XmbLookupString(f->display.x->ic, &event.xkey, + copy_buffer, copy_buffer_len, + &keysym, &status); + if (status == XBufferOverflow) { + copy_buffer_len = nbytes; + copy_buffer = (char *)xrealloc((char *)copy_buffer, + copy_buffer_len); + nbytes = XmbLookupString(f->display.x->ic, &event.xkey, + copy_buffer, copy_buffer_len, + &keysym, &status); + } + if (status==XLookupChars) modifiers=0; + } else { + /* + * Until ic gets created, behave as non XIM client. + */ + nbytes = + XLookupString (&event.xkey, copy_buffer, 80, &keysym, + &compose_status); + status = XLookupBoth; + } +#else /* XIMMULE */ nbytes = XLookupString (&event.xkey, copy_buffer, 80, &keysym, &compose_status); - +#endif /* XIMMULE */ orig_keysym = keysym; if (numchars > 1) { +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + if((status == XLookupKeySym || status == XLookupBoth) + &&(( keysym >= XK_BackSpace && keysym <= XK_Escape) +#else /* XIMMULE */ if (((keysym >= XK_BackSpace && keysym <= XK_Escape) +#endif /* XIMMULE */ #ifdef XK_Kanji /* hir, 1994.5.23 */ || (keysym >= XK_Kanji && keysym <= XK_Eisu_toggle) #endif @@ -4129,19 +4200,24 @@ { register int i; - for (i = 0; i < nbytes; i++) - { - if (temp_index == sizeof temp_buffer / sizeof (short)) - temp_index = 0; - temp_buffer[temp_index++] = copy_buffer[i]; - bufp->kind = ascii_keystroke; - bufp->code = copy_buffer[i]; - XSET (bufp->frame_or_window, Lisp_Frame, f); - bufp->modifiers = x_x_to_emacs_modifiers (modifiers); - bufp->timestamp = event.xkey.time; - bufp++; - } +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + if(status == XLookupChars || status == XLookupBoth){ +#endif /* XIMMULE */ + for (i = 0; i < nbytes; i++){ + if (temp_index == sizeof temp_buffer / sizeof (short)) + temp_index = 0; + temp_buffer[temp_index++] = copy_buffer[i]; + bufp->kind = ascii_keystroke; + bufp->code = copy_buffer[i]; + XSET (bufp->frame_or_window, Lisp_Frame, f); + bufp->modifiers = x_x_to_emacs_modifiers (modifiers); + bufp->timestamp = event.xkey.time; + bufp++; + } +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + } +#endif /* XIMMULE */ count += nbytes; numchars -= nbytes; } @@ -4238,8 +4314,15 @@ f = x_any_window_to_frame (event.xfocus.window); if (event.xfocus.detail != NotifyPointer) x_focus_event_frame = f; - if (f) + if (f) { x_new_focus_frame (f); +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + if(f->display.x->ic){ + XSetICFocus(f->display.x->ic); + } +#endif /* XIMMULE */ + + } #ifdef USE_X_TOOLKIT goto OTHER; #endif /* USE_X_TOOLKIT */ @@ -4280,8 +4363,14 @@ if (event.xfocus.detail != NotifyPointer && f == x_focus_event_frame) x_focus_event_frame = 0; - if (f && f == x_focus_frame) + if (f && f == x_focus_frame) { x_new_focus_frame (0); +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + if(f->display.x->ic){ + XUnsetICFocus(f->display.x->ic); + } +#endif /* XIMMULE */ + } #ifdef USE_X_TOOLKIT goto OTHER; #endif /* USE_X_TOOLKIT */ @@ -4471,6 +4560,15 @@ } } #endif /* not USE_X_TOOLKIT */ +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + /* + * We have to re-negotiate the geometry here if the input + * style is something-Area, however, this revision of + * XIMMULE does not support any something-Area styles, + * I am going to skip this for now... + * 2/17/'95 2/1/95 Hideki Hiura + */ +#endif /* XIMMULE */ break; case ButtonPress: @@ -5021,6 +5119,18 @@ else /* Those are the only two we have implemented! */ abort (); +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + if(f->display.x->ic){ + XPoint spot ; + XVaNestedList pattr ; + spot.x = CHAR_TO_PIXEL_COL (f, curs_x); + spot.y = CHAR_TO_PIXEL_ROW (f, curs_y)+ f->display.x->line_height; + pattr = XVaCreateNestedList((int)NULL, XNSpotLocation, &spot, NULL); + + XSetICValues(f->display.x->ic, XNPreeditAttributes, pattr, NULL); + XFree(pattr); + } +#endif /* XIMMULE */ UNBLOCK_INPUT; } @@ -5475,6 +5585,48 @@ UNBLOCK_INPUT; } +#ifdef XIMMULE +void +x_set_ic_fonts(f, fsid) + struct frame *f; + register int fsid; +{ + Lisp_Object lc, lc_list; + char fontlist[4096], *p; + XFontSet xfs; + XVaNestedList pa; + char **dm1, *dm3; + int dm2, i; + + if (!f->display.x->ic) return; + lc_list = Feval(intern("xim-locale-lc-list")); + p = fontlist; + *p = 0; + while(!EQ((lc=Feval(Fcar(lc_list))),Qnil)){ + i = XINT(lc); + if (FS_FONT_ID(fsid, i)>0){ + if (FS_FONT_INFO(fsid,i).name) + strcpy(p,FS_FONT_INFO(fsid,i).name); + else + strcpy(p,FS_FONT_INFO(fsid,i).requested); + p += strlen(p); + *(p++) = ','; + } + lc_list = Fcdr(lc_list); + } + *p = 0; + + xfs = XCreateFontSet(x_current_display, fontlist, &dm1, &dm2, &dm3); + if (xfs){ + pa = XVaCreateNestedList(NULL, XNFontSet, xfs, NULL); + XSetICValues(f->display.x->ic, XNPreeditAttributes, pa, NULL); + XFreeFontSet(x_current_display, xfs); + XFreeStringList(dm1); + XFree(pa); + } +} +#endif /* XIMMULE */ + Lisp_Object x_new_font (f, fontname) struct frame *f; @@ -5496,6 +5648,9 @@ f->fontset_id = fsID; f->display.x->font = FS_FONT (fsID, LCASCII); +#ifdef XIMMULE + x_set_ic_fonts(f, fsID); +#endif /* XIMMULE */ /* Now make the frame display the given font. */ if (FRAME_X_WINDOW (f) != 0) { @@ -6316,6 +6471,10 @@ { BLOCK_INPUT; +#ifdef XIMMULE + if (f->display.x->ic != NULL) + XDestroyIC(f->display.x->ic); +#endif if (f->display.x->icon_desc != 0) XDestroyWindow (XDISPLAY f->display.x->icon_desc); XDestroyWindow (XDISPLAY f->display.x->window_desc); @@ -6623,6 +6782,80 @@ {"-cr", "*cursorColor", XrmoptionSepArg, (XtPointer) NULL} }; #endif /* USE_X_TOOLKIT */ +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ +#if 0 /*XlibSpecificationRelease > 5*/ +static int +is_supported(res, im_list) +char *res; +XIMValuesList *im_list; +{ + int i; + if (im_list->supported_values == NULL) + return 0; + for(i=0; icount_values; i++) { + if (!strcmp(res, im_list->supported_values[i])) { + return 1; + } + } + return 0; +} +void +destroy_callback() +{ + /* Not implemented yet. */ + fprintf(stderr, "IM died!\n"); +} +#endif /* XlibSpecificationRelease > 5 */ +void +xim_initialize(display) + Display *display; +{ +#if 0 /*XlibSpecificationRelease > 5*/ + XIMCallback destroy; +#endif /* XlibSpecificationRelease > 5 */ + +#ifdef HAVE_XRMSETDATABASE + XrmDatabase rdb = XrmGetDatabase (display); +#else /* HAVE_XRMSETDATABASE */ + XrmDatabase rdb = display->db; +#endif /* HAVE_XRMSETDATABASE */ + + if(!(im = XOpenIM(display, rdb, EMACS_NAME, EMACS_CLASS))){ + return; + } +#if 0 /*XlibSpecificationRelease > 5*/ + /* + * Retrieve supported XIM velues list and XIC values list + * for later usage. + */ + if(XGetIMValues(im, XNQueryIMValuesList, &im_values_list, NULL)){ + error("Warning: XNQueryIMValuesList failed"); + } + /* + * Check XNDestroyCallback is supported or not by using the + * just retrieved im values list + */ + if(is_supported(XNDestroyCallback, &im_values_list)){ + destroy.callback = destroy_callback; + destroy.client_data = NULL; + XSetIMValues(im, XNDestroyCallback, &destroy, NULL ); + } else { + error("Warning: Xlib does not support destroy callback"); + } + if(is_supported(XNQueryICValuesList, &im_values_list)){ + /* + * Retrieve supported XIC velues list and XIC values list + * for later usage. + */ + if(XGetIMValues(im, XNQueryICValuesList, &ic_values_list, NULL)){ + error("Warning: XNQueryICValuesList failed"); + } + } +#endif /* XlibSpecificationRelease > 5 */ + +} + +#endif /* XIMMULE */ void x_term_init (display_name, xrm_option, resource_name) @@ -6639,7 +6872,15 @@ extern int old_fcntl_owner; #endif /* ! defined (F_SETOWN) */ #endif /* F_SETOWN_BUG */ +#ifdef XIMMULE + char *modifiers=NULL; +#endif /* XIMMULE */ +#ifdef XIMMULE + if (setlocale(LC_ALL, "") == NULL) { + fatal ("Cannot set locale.\n"); + } +#endif /* XIMMULE */ x_noop_count = 0; x_focus_frame = x_highlight_frame = 0; @@ -6672,6 +6913,25 @@ fatal ("X server %s not responding.\n\ Check the DISPLAY environment variable or use \"-d\"\n", display_name); +#ifdef XIMMULE + if (!XSupportsLocale()) { + fatal("X does not support locale \"%s\".\n", + setlocale(LC_ALL, NULL)); + } + modifiers = XSetLocaleModifiers(""); +#if 0 + if (modifiers == NULL || *modifiers == 0) { + error("Warning: cannot set locale modifiers. trying fallback locale modifiers."); + /* + * Fall into..... + * Give an another try on the local IM as a fallback + */ + if (XSetLocaleModifiers("@im=none") == NULL) { + fatal("Warning: cannot set the fallback locale modifiers.\n"); + } + } +#endif /* 0 */ +#endif /* XIMMULE */ #ifdef HAVE_X11 { @@ -6775,6 +7035,10 @@ #endif /* ! defined (SIGWINCH) */ signal (SIGPIPE, x_connection_closed); +#ifdef XIMMULE + if (modifiers != NULL && *modifiers != 0) + xim_initialize(x_current_display); +#endif /* XIMMULE */ } void diff -urN mule-2.3/src/xterm.h mule-2.3-xim/src/xterm.h --- mule-2.3/src/xterm.h Wed Nov 2 11:05:49 1994 +++ mule-2.3-xim/src/xterm.h Mon Oct 23 13:00:21 1995 @@ -295,6 +295,9 @@ GC cursor_gc; /* cursor drawing */ #ifdef MULE /* 94.6.2 by K.Handa */ GC back_gc; /* GC for filling background */ +#ifdef XIMMULE /* 2/1/95 Hideki Hiura */ + XIC ic ; /* Input context */ +#endif /* XIMMULE */ #endif /* MULE */ #endif /* HAVE_X11 */ -- □□ 質問されていやがる者は誰もいな ‖小林 正興 masaoki@tky.hp.com □□ □□ い。よく調べて、自分で答えを見 ‖日本ヒューレット・パッカード(株) □□ □□ つけようと努力した後であればね ‖半導体計測事業部 製品開発部 □□