Reformatted.
[chise/xemacs-chise.git.1] / src / mule-wnnfns.c
1 /* -*- coding: iso-2022-jp -*-
2    Copyright (C) 1995 Free Software Foundation, Inc.
3    Copyright (C) 1995 Sun Microsystems, Inc.
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING.  If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* Synched up with: Mule 2.3.  Not in FSF. */
23
24 /*      Jserver Interface for Mule
25         Coded by Yutaka Ishikawa at ETL (yisikawa@etl.go.jp)
26                  Satoru Tomura   at ETL (tomura@etl.go.jp)
27         Modified for Wnn4 library by
28                  Toshiaki Shingu (shingu@cpr.canon.co.jp)
29                  Hiroshi Kuribayashi (kuri@nff.ncl.omron.co.jp) */
30
31 /*
32  *      Functions defined in this file are
33  *         (wnn-server-open wnn-host-name login-name)
34  *              wnn-host-name: STRING or NIL
35  *              login-name: STRING
36  *              RETURNS: BOOLEAN
37  *              DESCRIPTION:
38  *              jserver \e$B$H@\B3$7!"%5!<%P!<FbIt$K@5JQ49!?5UJQ49#2$D$N4D6-$r\e(B
39  *              \e$B:n$k!#%(%i!<$N;~$O\e(B nil \e$B$rJV$9!#\e(B
40  *
41  *         (wnn-server-close)
42  *              RETURNS: BOOLEAN
43  *              DESCRIPTION:
44  *              jserver \e$B$H$N@\B3$r@Z$k!#<-=q!"IQEY$O%;!<%V$5$l$J$$!#\e(B
45  *
46  *         (wnn-server-dict-add dict-file-name hindo-file-name priority
47  *              dict-file-mode hindo-file-mode pw1 pw2)
48  *              dict-file-name: STRING
49  *              hindo-file-name: STRING or NULL-STRING
50  *              priority: INTEGER
51  *              dict-file-mode: BOOLEAN
52  *              hindo-file-mode: BOOLEAN
53  *              pw1: STRING or NIL
54  *              pw2: STRING or NIL
55  *              DESCRIPTION:
56  *              \e$B<-=q%U%!%$%kL>!"IQEY%U%!%$%kL>!"M%@hEY!"<-=q%U%!%$%k%b!<%I\e(B
57  *              \e$BIQEY%U%!%$%k%b!<%I$G;XDj$7$?<-=q$r%P%C%U%!$KDI2C$9$k!#\e(B
58  *              pw1, pw2 \e$B$O<-=q%U%!%$%k!"IQEY%U%!%$%k$N%Q%9%o!<%I!#\e(B
59  *
60  *         (wnn-server-dict-delete dic-no)
61  *              dic-no: INTEGER
62  *              RETURNS: \e$B%(%i!<$N;~\e(B nil
63  *              DESCRIPTION: dic-no \e$B$N<-=qHV9f$N<-=q$r!"%P%C%U%!$+$i\e(B
64  *              \e$B:o=|$9$k!#\e(B
65  *
66  *         (wnn-server-dict-list)
67  *              RETURNS: ((dic-no1 file-name1 comment1 word-no1 nice1)
68  *                        (dic-no2 file-name2 comment2 word-no2 nice2)...)
69  *              DESCRIPTION: \e$B%P%C%U%!>e$N<-=q$N%j%9%H$rF@$k!#\e(B
70  *
71  *         (wnn-server-dict-comment dic-no comment)
72  *              RETURNS: \e$B%(%i!<$N;~\e(B nil
73  *              DESCRIPTION: dic-no \e$B$N<-=q$K%3%a%s%H$r$D$1$k!#\e(B
74  *
75  *         (wnn-server-set-rev rev)
76  *              rev: BOOLEAN
77  *              rev \e$B$,\e(B nil \e$B$N;~$O@5JQ49!"$=$l0J30$N;~$O5UJQ49\e(B
78  *
79  *         (wnn-server-henkan-begin henkan-string)
80  *              henkan-string: STRING
81  *              RETURNS: bunsetu-suu
82  *              DESCRIPTION:
83  *              \e$B2>L>4A;zJQ49$r$7!"Bh0l8uJd$NJ8@a?t$rJV$9!#\e(B
84  *
85  *         (wnn-server-zenkouho bunsetu-no dai)
86  *              bunsetu-no: INTEGER
87  *              dai: BOOLEAN
88  *              RETURNS: offset
89  *              DESCRIPTION:
90  *              \e$BJ8@aHV9f$G;XDj$5$l$?J8@a$NA48uJd$r$H$j$@$7\e(B
91  *              \e$B!"8=:_$N%*%U%;%C%H$rJV$9!#\e(B
92  *
93  *         (wnn-server-get-zenkouho offset)
94  *              bunsetu-no: INTEGER
95  *              dai: BOOLEAN
96  *              RETURNS: list of zenkouho
97  *              DESCRIPTION:
98  *              \e$B%*%U%;%C%H$G;XDj$5$l$?8uJd$rF@$k!#\e(B
99  *
100  *         (wnn-server-zenkouho-bun)
101  *              RETURNS: INTEGER
102  *              DESCRIPTION:
103  *              \e$BA48uJd$rI=<($7$F$$$kJ8@aHV9f$rF@$k!#\e(B
104  *
105  *         (wnn-server-zenkouho-suu)
106  *              RETURNS: INTEGER
107  *              DESCRIPTION:
108  *              \e$BA48uJd$rI=<($7$F$$$kJ8@a$NA48uJd?t$rF@$k!#\e(B
109  *
110  *         (wnn-server-dai-top bun-no)
111  *              bun-no: INTEGER
112  *              RETURNS: BOOLEAN
113  *              DESCRIPTION:
114  *              \e$BJ8@a$,BgJ8@a$N@hF,$J$i\e(B t
115  *
116  *         (wnn-server-dai-end bun-no)
117  *              bun-no: INTEGER
118  *              RETURNS: INTEGER
119  *              DESCRIPTION:
120  *              \e$B<!$NBgJ8@a$NJ8@aHV9f$rF@$k!#\e(B
121  *
122  *         (wnn-server-henkan-kakutei kouho-no dai)
123  *              kouho-no: INTEGER
124  *              dai: BOOLEAN
125  *              RETURNS: BOOLEAN
126  *              DESCRIPTION:
127  *              \e$B8uJdHV9f$G<($5$l$?8uJd$rA*Br$9$k!#\e(B
128  *              (wnn-server-zenkouho) \e$B$r8F$s$F$+$i$G$J$$$H$$$1$J$$!#\e(B
129  *
130  *         (wnn-server-bunsetu-henkou bunsetu-no bunsetu-length dai)
131  *              bunsetu-no: INTEGER
132  *              bunsetu-length: INTEGER
133  *              dai: BOOLEAN
134  *              RETURNS:
135  *              DESCRIPTION:
136  *              \e$BJ8@a$ND9$5$rJQ99$9$k!#\e(B
137  *
138  *         (wnn-bunsetu-kouho-inspect bunsetu-no)
139  *              bunsetu-no: INTEGER
140  *              RETURNS: (kanji yomi jisho-no serial-no hinsi hindo
141  *              ima hyoka daihyoka kangovect)
142  *              DESCRIPTION:
143  *              \e$BJ8@a$N?'!9$J>pJs$rJQ49%P%C%U%!$+$i$H$j=P$9!#\e(B
144  *
145  *         (wnn-server-henkan-quit)
146  *              RETURNS: BOOLEAN
147  *              DESCRIPTION:
148  *              \e$B2?$b$7$J$$!#\e(B
149  *
150  *         (wnn-server-bunsetu-kanji bun-no)
151  *              RETURNS: (bunsetu-kanji length)
152  *              DESCRIPTION:
153  *
154  *         (wnn-server-bunsetu-yomi bun-no)
155  *              RETURNS: (bunsetu-yomi length)
156  *              DESCRIPTION:
157  *
158  *         (wnn-server-bunsetu-suu)
159  *              RETURNS: bunsetu-suu
160  *              DESCRIPTION:
161  *
162  *         (wnn-server-hindo-update &optional bunsetu-no)
163  *              bunsetu-no: INTEGER
164  *              RETURNS: BOOLEAN
165  *              DESCRIPTION:
166  *              \e$BIQEY>pJs$r99?7$9$k!#\e(B
167  *
168  *         (wnn-server-word-add dic-no tango yomi comment hinsi)
169  *              dic-no: INTEGER
170  *              tango: STRING
171  *              yoni: STRING
172  *              comment: STRING
173  *              hinsi: INTEGER
174  *              RETURNS: BOOLEAN
175  *              DESCRIPTION:
176  *              \e$B<-=q$KC18l$rEPO?$9$k!#\e(B
177  *
178  *         (wnn-server-word-delete dic-no entry)
179  *              dic-no: INTEGER
180  *              entry: INTEGER
181  *              RETURNS: BOOLEAN
182  *              DESCRIPTION:
183  *              \e$B<-=q$+$i%(%s%H%jHV9f$G<($5$l$kC18l$r:o=|$9$k!#\e(B
184  *
185  *         (wnn-server-word-use dic-no entry)
186  *              dic-no: INTEGER
187  *              entry: INTEGER
188  *              RETURNS: BOOLEAN
189  *              DESCRIPTION:
190  *              \e$B<-=q$+$i%(%s%H%jHV9f$G<($5$l$kC18l$NM-8z!?L58z$r%H%0%k$9$k!#\e(B
191   *
192  *         (wnn-server-word-info dic-no entry)
193  *              dic-no: INTEGER
194  *              entry: INTEGER
195  *              RETURNS: (yomi kanji comment hindo hinsi)
196  *              DESCRIPTION:
197  *              \e$B<-=q$+$i%(%s%H%jHV9f$G<($5$l$kC18l$N>pJs$rF@$k!#\e(B
198  *
199  *         (wnn-server-word-hindo-set dic-no entry hindo)
200  *              dic-no: INTEGER
201  *              entry: INTEGER
202  *              hindo: INTEGER
203  *              RETURNS: BOOLEAN
204  *              DESCRIPTION:
205  *              \e$B<-=q$+$i%(%s%H%jHV9f$G<($5$l$kC18l$NIQEY$r@_Dj$9$k!#\e(B
206  *
207  *         (wnn-server-word-search yomi)
208  *              yomi: STRING
209  *              RETURNS: a LIST of dict-joho
210  *              DESCRIPTION:
211  *              \e$BA4$F$N<-=q$+$iC18l8!:w$r9T$J$&!#\e(B
212  *
213  *         (wnn-server-dict-save)
214  *              RETURNS: BOOLEAN
215  *              DESCRIPTION:
216  *              \e$BA4$F$N<-=q$HIQEY%U%!%$%k$r%;!<%V$9$k!#\e(B
217  *
218  *         (wnn-server-get-param)
219  *              RETURNS: (n nsho p1 p2 p3 ... p15)
220  *              DESCRIPTION: \e$BJQ49%Q%i%a!<%?$rF@$k!#\e(B
221  *
222  *         (wnn-server-set-param n sho p1 ... p15)
223  *              RETURNS: \e$B%(%i!<$N;~\e(B nil
224  *              DESCRIPTION: \e$BJQ49%Q%i%a!<%?$r@_Dj$9$k!#\e(B
225  *
226  *         (wnn-server-get-msg error-no)
227  *              RETURNS: \e$B%(%i!<%a225;!<%8\e(B
228  *              DESCRIPTION: \e$B%(%i!<HV9f$+$i%a%C%;!<%8$rF@$k!#\e(B
229  *
230  *         (wnn-server-fuzokugo-set fname)
231  *              RETURNS: \e$B%(%i!<$N;~\e(B nil
232  *              DESCRIPTION: \e$B%P%C%U%!$KImB08l%U%!%$%k$rFI$_9~$`!#\e(B
233  *
234  *         (wnn-server-fuzokugo-get)
235  *              RETURNS: \e$B%U%!%$%kL>\e(B
236  *              DESCRIPTION: \e$B%P%C%U%!$NImB08l%U%!%$%kL>$rF@$k!#\e(B
237  *
238  *         (wnn-server-isconnect)
239  *              RETURNS: \e$B%3%M%/%H$7$F$l$P\e(B t, \e$B$7$F$J$1$l$P\e(B nil
240  *              DESCRIPTION: \e$B%5!<%P$H7Q$C$F$$$k$+D4$Y$k!#\e(B
241  *
242  *         (wnn-server-hinsi-dicts hinsi-no)
243  *              RETURNS: (dic-no1 dic-no2 ...)
244  *              DESCRIPTION: hinsi-no \e$B$NIJ;l$,EPO?$G$-$k<-=q$N%j%9%H$rF@$k!#\e(B
245  *              hinsi-no = -1 \e$B$N$H$-$K$O!"EPO?2DG=$JA4<-=q$rF@$k!#\e(B
246  *
247  *         (wnn-server-hinsi-list dic-no name)
248  *              RETURNS: (name1 name2 ... )
249  *              DESCRIPTION: dic-no \e$B$N<-=q$G!"IJ;l%N!<%I$KB0$9$k\e(B
250  *              \e$BIJ;l%N!<%I!JL>!K$N%j%9%H$rF@$k!#\e(B
251  *              \e$BIJ;lL>$rM?$($?;~$O!"#0$rJV$9!#\e(B
252  *
253  *         (wnn-server-hinsi-name hinsi-no)
254  *              RETURNS: hinsi-name
255  *              DESCRIPTION: \e$BIJ;lHV9f$+$iL>A0$r<h$k!#\e(B
256  *
257  *         (wnn-server-hinsi-number hinsi-name)
258  *              RETURNS: hinsi-no
259  *              DESCRIPTION: \e$BIJ;lL>$rIJ;lHV9f$KJQ49$9$k!#\e(B
260  *
261  *         (wnn-server-version)
262  *              RETURNS: version ID(int)
263  *
264  */
265
266 #include <config.h>
267 #include "lisp.h"
268
269 #include "buffer.h"
270 #include "window.h"
271 #include "sysdep.h"
272
273 #include "wnn/commonhd.h"
274 #include "character.h"
275 #include "wnn/jllib.h"
276 #include "wnn/cplib.h"
277
278 /* UCHAR \e$B$,Fs=EDj5A$5$l$k$N$G\e(B */
279 #define _UCHAR_T
280
281 #define EGG_TIMEOUT 5
282 #define NSERVER 4
283 #define WNNSERVER_J 0
284 #define WNNSERVER_C 1
285 #define WNNSERVER_T 2
286 #define WNNSERVER_K 3
287
288 int check_wnn_server_type (void);
289 void w2m (w_char *wp, unsigned char *mp, unsigned char lb);
290 void m2w (unsigned char *mp, w_char *wp);
291 void w2y (w_char *w);
292 void c2m (unsigned char *cp, unsigned char *mp, unsigned char lb);
293 static void puts2 (char *s);
294 static int dai_end (int no, int server);
295 static int yes_or_no (unsigned char *s);
296
297  /* Why doesn't wnn have a prototype for these? */
298 typedef unsigned int letter;
299 int cwnn_yincod_pzy(w_char *, w_char, int);
300 int cwnn_pzy_yincod(letter *, letter *, int);
301
302 static struct wnn_buf *wnnfns_buf[NSERVER];
303 static struct wnn_env *wnnfns_env_norm[NSERVER];
304 static struct wnn_env *wnnfns_env_rev[NSERVER];
305 static int wnnfns_norm;
306 static unsigned char lb_wnn_server_type[NSERVER] =
307 {LEADING_BYTE_JAPANESE_JISX0208, LEADING_BYTE_CHINESE_GB2312, LEADING_BYTE_THAI_TIS620, LEADING_BYTE_KOREAN_KSC5601};
308
309 /* Lisp Variables and Constants Definition */
310 Lisp_Object     Qjserver;
311 Lisp_Object     Qcserver;
312 /*Lisp_Object   Qtserver;*/
313 Lisp_Object     Qkserver;
314 Lisp_Object     Qwnn_no_uniq;
315 Lisp_Object     Qwnn_uniq;
316 Lisp_Object     Qwnn_uniq_kanji;
317 Lisp_Object     Qwnn_n, Qwnn_nsho, Qwnn_hindo, Qwnn_len, Qwnn_jiri, Qwnn_flag;
318 Lisp_Object     Qwnn_jisho, Qwnn_sbn, Qwnn_dbn_len, Qwnn_sbn_cnt, Qwnn_suuji;
319 Lisp_Object     Qwnn_kana, Qwnn_eisuu, Qwnn_kigou, Qwnn_toji_kakko, Qwnn_fuzokogo, Qwnn_kaikakko;
320 Lisp_Object     Vwnn_server_type;
321 Lisp_Object     Vcwnn_zhuyin;
322 Lisp_Object     Vwnnenv_sticky;
323 Lisp_Object     Vwnn_uniq_level;
324 Fixnum          lb_sisheng;
325
326 /* Lisp functions definition */
327
328 DEFUN ("wnn-server-open", Fwnn_open, 2, 2, 0, /*
329 Connect to jserver of host HNAME, make an environment with
330 login name LNAME in the server.
331 Return nil if error occurs.
332 */
333      (hname, lname))
334 {
335   char *envname;
336   char *langname;
337   char *hostname;
338   int   snum;
339   int size;
340   CHECK_STRING (lname);
341
342   snum = check_wnn_server_type ();
343   switch (snum)
344     {
345     case WNNSERVER_J:
346       langname = "ja_JP";
347       break;
348     case WNNSERVER_C:
349       langname = "zh_CN";
350       break;
351 /*
352     case WNNSERVER_T:
353     strcpy (langname, "zh_TW");
354     break;
355     */
356     case WNNSERVER_K:
357       langname = "ko_KR";
358       break;
359     case -1:
360     default:
361       return Qnil;
362     }
363   size = XSTRING_LENGTH (lname) > 1024 ? 1026 : XSTRING_LENGTH (lname) + 2;
364   envname = alloca (size);
365   strncpy (envname, (char *) XSTRING_DATA (lname), size-2);
366   envname[size-2] = '\0';
367   if (NILP (hname)) hostname = "";
368   else
369     {
370       CHECK_STRING (hname);
371       size = XSTRING_LENGTH(hname) > 1024 ? 1025 : XSTRING_LENGTH(hname) + 1;
372
373       hostname = alloca (size);
374       strncpy (hostname, (char *) XSTRING_DATA (hname), size-1);
375       hostname[size-1] = '\0';
376     }
377   CHECK_STRING (lname);
378   /* 97/4/16 jhod@po.iijnet.or.jp
379    * libwnn uses SIGALRM, so we need to stop and start interrupts.
380    */
381   stop_interrupts();
382   if (!(wnnfns_buf[snum] = jl_open_lang (envname, hostname, langname,
383                                          0, 0, 0, EGG_TIMEOUT)))
384     {
385       start_interrupts();
386       return Qnil;
387     }
388   if (!jl_isconnect (wnnfns_buf[snum]))
389     {
390       start_interrupts();
391       return Qnil;
392     }
393   wnnfns_env_norm[snum] = jl_env_get (wnnfns_buf[snum]);
394 /*  if (Vwnnenv_sticky == Qt) jl_env_sticky_e (wnnfns_env_norm[snum]);
395     else jl_env_un_sticky_e (wnnfns_env_norm[snum]);*/
396   strcat (envname, "R");
397   if (!(wnnfns_env_rev[snum] = jl_connect_lang (envname, hostname, langname,
398                                                 0, 0, 0, EGG_TIMEOUT)))
399     {
400       start_interrupts();
401       return Qnil;
402     }
403 /*  if (Vwnnenv_sticky == Qt) jl_env_sticky_e (wnnfns_env_rev[snum]);
404     else jl_env_un_sticky_e (wnnfns_env_rev[snum]);*/
405   start_interrupts();
406   return Qt;
407 }
408
409
410 DEFUN ("wnn-server-close", Fwnn_close, 0, 0, 0, /*
411 Close the connection to jserver, Dictionary and frequency files
412 are not saved.
413 */
414      ())
415 {
416   int   snum;
417   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
418   if (!wnnfns_buf[snum]) return Qnil;
419   if (wnnfns_env_norm[snum])
420     {
421       if (NILP (Vwnnenv_sticky)) jl_env_un_sticky_e (wnnfns_env_norm[snum]);
422       else jl_env_sticky_e (wnnfns_env_norm[snum]);
423       jl_disconnect (wnnfns_env_norm[snum]);
424     }
425   if (wnnfns_env_rev[snum])
426     {
427       if (NILP (Vwnnenv_sticky)) jl_env_un_sticky_e (wnnfns_env_rev[snum]);
428       else jl_env_sticky_e (wnnfns_env_rev[snum]);
429       jl_disconnect (wnnfns_env_rev[snum]);
430     }
431   jl_env_set (wnnfns_buf[snum], 0);
432   jl_close (wnnfns_buf[snum]);
433   wnnfns_buf[snum] = (struct wnn_buf *) 0;
434   wnnfns_env_norm[snum] = wnnfns_env_rev[snum] = (struct wnn_env *) 0;
435   return Qt;
436 }
437
438 DEFUN ("wnn-server-dict-add", Fwnn_dict_add, 5, MANY, 0, /*
439 Add dictionary specified by DICT-FILE-NAME, FREQ-FILE-NAME,
440 PRIORITY, DICT-FILE-MODE, FREQ-FILE-MODE.
441 Specify password files of dictionary and frequency, PW1 and PW2, if needed.
442 */
443      (int nargs, Lisp_Object *args))
444 {
445   struct gcpro gcpro1;
446   int   snum;
447   CHECK_STRING (args[0]);
448   CHECK_STRING (args[1]);
449   CHECK_INT (args[2]);
450   if (! NILP (args[5])) CHECK_STRING (args[5]);
451   if (! NILP (args[6])) CHECK_STRING (args[6]);
452   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
453   if (!wnnfns_buf[snum]) return Qnil;
454   GCPRO1 (*args);
455   gcpro1.nvars = nargs;
456   if (jl_dic_add (wnnfns_buf[snum],
457                   XSTRING_DATA (args[0]),
458                   XSTRING_DATA (args[1]),
459                   wnnfns_norm ? WNN_DIC_ADD_NOR : WNN_DIC_ADD_REV,
460                   XINT (args[2]),
461                   NILP (args[3]) ? WNN_DIC_RDONLY : WNN_DIC_RW,
462                   NILP (args[4]) ? WNN_DIC_RDONLY : WNN_DIC_RW,
463                   NILP (args[5]) ? 0 : XSTRING_DATA (args[5]),
464                   NILP (args[6]) ? 0 : XSTRING_DATA (args[6]),
465                   yes_or_no,
466                   puts2 ) < 0)
467     {
468       UNGCPRO;
469       return Qnil;
470     }
471   UNGCPRO;
472   return Qt;
473 }
474
475 DEFUN ("wnn-server-dict-delete", Fwnn_dict_delete, 1, 1, 0, /*
476 Remove dictionary specified by DIC-NUMBER from buffer.
477 */
478      (dicno))
479 {
480   int   no;
481   int   snum;
482   CHECK_INT (dicno);
483   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
484   no = XINT (dicno);
485   if (!wnnfns_buf[snum]) return Qnil;
486   if (jl_dic_delete (wnnfns_buf[snum], no) < 0) return Qnil;
487   return Qt;
488 }
489
490 DEFUN ("wnn-server-dict-list", Fwnn_dict_list, 0, 0, 0, /*
491 Return information of dictionaries.
492 */
493      ())
494 {
495   WNN_DIC_INFO  *dicinfo;
496   int           cnt, i;
497   unsigned char comment[1024];
498   Lisp_Object   val;
499   int   snum;
500   unsigned char lb;
501
502   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
503   lb = lb_wnn_server_type[snum];
504   if (!wnnfns_buf[snum]) return Qnil;
505 #ifdef  WNN6
506   if((cnt = jl_fi_dic_list (wnnfns_buf[snum], 0x3f, &dicinfo)) < 0)
507     return Qnil;
508 #else
509   if((cnt = jl_dic_list (wnnfns_buf[snum], &dicinfo)) < 0) return Qnil;
510 #endif
511   val = Qnil;
512   for (i = 0, dicinfo += cnt; i < cnt; i++)
513     {
514       dicinfo--;
515       w2m (dicinfo->comment, comment, lb);
516       /* #### The following has not been Mule-ized!!
517          fname and comment must be ASCII strings! */
518       val =
519         Fcons (Fcons (make_int (dicinfo->dic_no),
520                       list4 (make_string ((Bufbyte *) (dicinfo->fname),
521                                           strlen (dicinfo->fname)),
522                              make_string (comment, strlen ((char *) comment)),
523                              make_int (dicinfo->gosuu),
524                              make_int (dicinfo->nice))), val);
525     }
526   return val;
527 }
528
529 DEFUN ("wnn-server-dict-comment", Fwnn_dict_comment, 2, 2, 0, /*
530 Set comment to dictionary specified by DIC-NUMBER.
531 Comment string COMMENT.
532 */
533      (dicno, comment))
534 {
535   w_char wbuf[512];
536   int snum;
537   CHECK_INT (dicno);
538   CHECK_STRING (comment);
539   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
540   if (!wnnfns_buf[snum]) return Qnil;
541   m2w (XSTRING_DATA (comment), wbuf);
542   if (jl_dic_comment_set (wnnfns_buf[snum], XINT (dicno), wbuf) < 0)
543     return Qnil;
544   return Qt;
545 }
546
547
548 DEFUN ("wnn-server-set-rev", Fwnn_set_rev, 1, 1, 0, /*
549 Switch the translation mode to normal if T, or reverse if NIL.
550 */
551      (rev))
552 {
553   int   snum;
554   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
555   if (NILP (rev))
556     {
557       if ((!wnnfns_buf[snum]) || (!wnnfns_env_norm[snum])) return Qnil;
558       jl_env_set (wnnfns_buf[snum], wnnfns_env_norm[snum]);
559       wnnfns_norm = 1;
560     }
561   else
562     {
563       if ((!wnnfns_buf[snum]) || (!wnnfns_env_rev[snum])) return Qnil;
564       jl_env_set (wnnfns_buf[snum], wnnfns_env_rev[snum]);
565       wnnfns_norm = 0;
566     }
567   return Qt;
568 }
569
570 DEFUN ("wnn-server-henkan-begin", Fwnn_begin_henkan, 1, 1, 0, /*
571 Translate YOMI string to kanji. Retuen the number of bunsetsu.
572 */
573      (hstring))
574 {
575   int                   cnt;
576   w_char                wbuf[5000];
577   int   snum;
578   CHECK_STRING (hstring);
579   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
580   if (!wnnfns_buf[snum]) return Qnil;
581   m2w (XSTRING_DATA (hstring), wbuf);
582   if (snum == WNNSERVER_C)
583     w2y (wbuf);
584
585 #ifdef  WNN6
586   if ((cnt = jl_fi_ren_conv (wnnfns_buf[snum], wbuf,    0, -1, WNN_USE_MAE)) < 0)
587     return Qnil;
588 #else
589   if ((cnt = jl_ren_conv (wnnfns_buf[snum], wbuf,       0, -1, WNN_USE_MAE)) < 0)
590     return Qnil;
591 #endif
592   return make_int (cnt);
593 }
594
595 DEFUN ("wnn-server-zenkouho", Fwnn_zenkouho, 2, 2, 0, /*
596 Get zenkouho at BUNSETSU-NUMBER. Second argument DAI is t.
597 if dai-bunsetsu, NIL if sho-bunsetsu. Return the current offset of zenkouho.
598 */
599      (bunNo, dai))
600 {
601   int   no, offset;
602   int   snum;
603   int   uniq_level;
604   CHECK_INT (bunNo);
605   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
606   if (!wnnfns_buf[snum]) return Qnil;
607   no = XINT (bunNo);
608   if (EQ(Vwnn_uniq_level, Qwnn_no_uniq)) uniq_level = WNN_NO_UNIQ;
609   else if (EQ(Vwnn_uniq_level, Qwnn_uniq)) uniq_level = WNN_UNIQ;
610   else uniq_level = WNN_UNIQ_KNJ;
611   if (NILP (dai))
612     {
613       if ((offset = jl_zenkouho (wnnfns_buf[snum],no,WNN_USE_MAE,
614                                  uniq_level)) < 0)
615         return Qnil;
616     }
617   else
618     {
619       if ((offset = jl_zenkouho_dai (wnnfns_buf[snum], no, dai_end (no, snum),
620                                      WNN_USE_MAE, uniq_level)) < 0)
621         return Qnil;
622     }
623   return make_int (offset);
624 }
625
626
627 DEFUN ("wnn-server-get-zenkouho", Fwnn_get_zenkouho, 1, 1, 0, /*
628 Get kanji string of KOUHO-NUMBER.
629 */
630      (kouhoNo))
631 {
632   unsigned char kanji_buf[256];
633   w_char        wbuf[256];
634   int   snum;
635   unsigned char lb;
636   CHECK_INT (kouhoNo);
637   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
638   lb = lb_wnn_server_type[snum];
639   if (!wnnfns_buf[snum]) return Qnil;
640   jl_get_zenkouho_kanji (wnnfns_buf[snum], XINT (kouhoNo), wbuf);
641   w2m (wbuf, kanji_buf, lb);
642   return make_string (kanji_buf, strlen ((char *) kanji_buf));
643 }
644
645 DEFUN ("wnn-server-zenkouho-bun", Fwnn_zenkouho_bun, 0, 0, 0, /*
646 For Wnn.
647 */
648      ())
649 {
650   int   snum;
651   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
652   return make_int (jl_zenkouho_bun (wnnfns_buf[snum]));
653 }
654
655 DEFUN ("wnn-server-zenkouho-suu", Fwnn_zenkouho_suu, 0, 0, 0, /*
656 Return the number of zen kouho.
657 */
658      ())
659 {
660   int   snum;
661   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
662   return make_int (jl_zenkouho_suu (wnnfns_buf[snum]));
663 }
664
665 DEFUN ("wnn-server-dai-top", Fwnn_dai_top, 1, 1, 0, /*
666 Return t if bunsetsu BUN-NUMBER is dai-bunsetsu.
667 */
668      (bunNo))
669 {
670   int   snum;
671   CHECK_INT (bunNo);
672   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
673   if (!wnnfns_buf[snum]) return Qnil;
674   if (jl_dai_top (wnnfns_buf[snum], XINT (bunNo)) == 1) return Qt;
675   else return Qnil;
676 }
677
678 DEFUN ("wnn-server-dai-end", Fwnn_dai_end, 1, 1, 0, /*
679 Return the bunsetu number of the next dai-bunsetsu after BUN-NUMBER.
680 */
681      (bunNo))
682 {
683   int   snum;
684   CHECK_INT (bunNo);
685   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
686   if (!wnnfns_buf[snum]) return Qnil;
687   return make_int (dai_end (XINT (bunNo), snum));
688 }
689
690 DEFUN ("wnn-server-henkan-kakutei", Fwnn_kakutei, 2, 2, 0, /*
691 Set candidate with OFFSET, DAI. DAI is T if dai-bunsetsu.
692 */
693      (offset, dai))
694 {
695   int   snum;
696   CHECK_INT (offset);
697   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
698   if (!wnnfns_buf[snum]) return Qnil;
699   if (NILP (dai))
700     {
701       if (jl_set_jikouho (wnnfns_buf[snum], XINT (offset)) < 0) return Qnil;
702     }
703   else
704     {
705       if (jl_set_jikouho_dai (wnnfns_buf[snum], XINT (offset)) < 0)
706         return Qnil;
707     }
708   return Qt;
709 }
710
711 DEFUN ("wnn-server-bunsetu-henkou", Fwnn_bunsetu_henkou, 3, 3, 0, /*
712 Change length of BUN-NUMBER bunsetu to LEN. DAI is T if dai-bunsetsu.
713 */
714      (bunNo, len, dai))
715 {
716   int           cnt, no;
717   int   snum;
718   CHECK_INT (bunNo);
719   CHECK_INT (len);
720   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
721   if (!wnnfns_buf[snum]) return Qnil;
722   no = XINT (bunNo);
723 #ifdef  WNN6
724   if ((cnt = jl_fi_nobi_conv (wnnfns_buf[snum], no, XINT(len), -1, WNN_USE_MAE,
725                               NILP (dai) ? WNN_SHO : WNN_DAI)) < 0)
726     return Qnil;
727 #else
728   if ((cnt = jl_nobi_conv (wnnfns_buf[snum], no, XINT(len), -1, WNN_USE_MAE,
729                            NILP (dai) ? WNN_SHO : WNN_DAI)) < 0)
730     return Qnil;
731 #endif
732   return make_int (cnt);
733 }
734
735 DEFUN ("wnn-server-inspect", Fwnn_inspect, 1, 1, 0, /*
736 Get bunsetsu information specified by BUN-NUMBER.
737 */
738      (bunNo))
739 {
740   Lisp_Object           val;
741   unsigned char         cbuf[512];
742   w_char                wbuf[256];
743   int                   bun_no, yomilen, jirilen, i;
744   int   snum;
745   unsigned char         lb;
746   CHECK_INT (bunNo);
747   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
748   lb = lb_wnn_server_type[snum];
749   if (!wnnfns_buf[snum]) return Qnil;
750   bun_no = XINT (bunNo);
751   val = Qnil;
752   val = Fcons (make_int (wnnfns_buf[snum]->bun[bun_no]->kangovect), val);
753   val = Fcons (make_int (wnnfns_buf[snum]->bun[bun_no]->daihyoka), val);
754   val = Fcons (make_int (wnnfns_buf[snum]->bun[bun_no]->hyoka), val);
755   val = Fcons (make_int (wnnfns_buf[snum]->bun[bun_no]->ima), val);
756   val = Fcons (make_int (wnnfns_buf[snum]->bun[bun_no]->hindo), val);
757   val = Fcons (make_int (wnnfns_buf[snum]->bun[bun_no]->hinsi), val);
758   val = Fcons (make_int (wnnfns_buf[snum]->bun[bun_no]->entry), val);
759   val = Fcons (make_int (wnnfns_buf[snum]->bun[bun_no]->dic_no), val);
760   yomilen = jl_get_yomi (wnnfns_buf[snum], bun_no, bun_no + 1, wbuf);
761   jirilen = wnnfns_buf[snum]->bun[bun_no]->jirilen;
762   for (i = yomilen; i >= jirilen; i--) wbuf[i+1] = wbuf[i];
763   wbuf[jirilen] = '+';
764   w2m (wbuf, cbuf, lb);
765   val = Fcons (make_string (cbuf, strlen ((char *) cbuf)), val);
766   jl_get_kanji (wnnfns_buf[snum], bun_no, bun_no + 1, wbuf);
767   w2m (wbuf, cbuf, lb);
768   val = Fcons (make_string (cbuf, strlen ((char *) cbuf)), val);
769   return val;
770 }
771
772
773 DEFUN ("wnn-server-henkan-quit", Fwnn_quit_henkan, 0, 0, 0, /*
774 do nothing.
775 */
776      ())
777 {
778   int   snum;
779   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
780   if (!wnnfns_buf[snum]) return Qnil;
781   return Qt;
782 }
783
784 DEFUN ("wnn-server-bunsetu-kanji", Fwnn_bunsetu_kanji, 1, 1, 0, /*
785 Get the pair of kanji and length of bunsetsu specified by BUN-NUMBER.
786 */
787      (bunNo))
788 {
789   int           no;
790   unsigned char         kanji_buf[256];
791   w_char                wbuf[256];
792   int                   kanji_len;
793   int                   snum;
794   unsigned char         lb;
795   CHECK_INT (bunNo);
796   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
797   lb = lb_wnn_server_type[snum];
798   if (!wnnfns_buf[snum]) return Qnil;
799   no = XINT (bunNo);
800   kanji_len = jl_get_kanji (wnnfns_buf[snum], no, no + 1, wbuf);
801   w2m (wbuf, kanji_buf, lb);
802   return Fcons (make_string (kanji_buf, strlen ((char *) kanji_buf)),
803                 make_int (kanji_len));
804 }
805
806 DEFUN ("wnn-server-bunsetu-yomi", Fwnn_bunsetu_yomi, 1, 1, 0, /*
807 Get the pair of yomi and length of bunsetsu specified by BUN-NUMBER.
808 */
809      (bunNo))
810 {
811   int           no;
812   unsigned char         yomi_buf[256];
813   w_char                wbuf[256];
814   int                   yomi_len;
815   int                   snum;
816   unsigned char         lb;
817   CHECK_INT (bunNo);
818   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
819   lb = lb_wnn_server_type[snum];
820   if (!wnnfns_buf[snum]) return Qnil;
821   no = XINT (bunNo);
822   yomi_len = jl_get_yomi (wnnfns_buf[snum], no, no + 1, wbuf);
823   w2m (wbuf, yomi_buf, lb);
824   return Fcons (make_string (yomi_buf, strlen ((char *) yomi_buf)),
825                 make_int (yomi_len));
826 }
827
828 DEFUN ("wnn-server-bunsetu-suu", Fwnn_bunsetu_suu, 0, 0, 0, /*
829 Get the number of bunsetsu.
830 */
831      ())
832 {
833   int   snum;
834   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
835   if (!wnnfns_buf[snum]) return Qnil;
836   return make_int (jl_bun_suu (wnnfns_buf[snum]));
837 }
838
839 DEFUN ("wnn-server-hindo-update", Fwnn_hindo_update, 0, 1, 0, /*
840 Update frequency of bunsetsu specified by NUM-NUMBER.
841 */
842      (bunNo))
843 {
844   int           no;
845   int   snum;
846   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
847   if (NILP (bunNo)) no = -1;
848   else
849     {
850       CHECK_INT (bunNo);
851       no = XINT (bunNo);
852     }
853   if (!wnnfns_buf[snum]) return Qnil;
854 #ifdef  WNN6
855   if (jl_optimize_fi (wnnfns_buf[snum], 0, no) < 0) return Qnil;
856 #else
857   if (jl_update_hindo (wnnfns_buf[snum], 0, no) < 0) return Qnil;
858 #endif
859   return Qt;
860 }
861
862
863 DEFUN ("wnn-server-word-add", Fwnn_word_toroku, 5, 5, 0, /*
864 Add a word to dictionary. Arguments are
865 DIC-NUMBER, KANJI, YOMI, COMMENT, HINSI-NUMBER.
866 */
867      (dicno, kanji, yomi, comment, hinsi))
868 {
869   w_char                yomi_buf[256], kanji_buf[256], comment_buf[256];
870   int   snum;
871   CHECK_INT (dicno);
872   CHECK_STRING (kanji);
873   CHECK_STRING (yomi);
874   CHECK_STRING (comment);
875   CHECK_INT (hinsi);
876   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
877   if (!wnnfns_buf[snum]) return Qnil;
878   m2w (XSTRING_DATA (yomi), yomi_buf);
879   if (snum == WNNSERVER_C)
880     w2y (yomi_buf);
881   m2w (XSTRING_DATA (kanji), kanji_buf);
882   m2w (XSTRING_DATA (comment), comment_buf);
883   if (jl_word_add (wnnfns_buf[snum], XINT (dicno), yomi_buf, kanji_buf,
884                    comment_buf, XINT (hinsi), 0) < 0)
885     return Qnil;
886   else return Qt;
887 }
888
889
890 DEFUN ("wnn-server-word-delete", Fwnn_word_sakujo, 2, 2, 0, /*
891 Delete a word from dictionary, specified by DIC-NUMBER, SERIAL-NUMBER.
892 */
893      (no, serial))
894 {
895   int   snum;
896   CHECK_INT (no);
897   CHECK_INT (serial);
898   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
899   if (!wnnfns_buf[snum]) return Qnil;
900   if (jl_word_delete (wnnfns_buf[snum], XINT (no), XINT (serial)) < 0)
901     return Qnil;
902   else return Qt;
903 }
904
905
906 DEFUN ("wnn-server-word-use", Fwnn_word_use, 2, 2, 0, /*
907 Toggle on/off word, specified by DIC-NUMBER and SERIAL-NUMBER.
908 */
909      (no, serial))
910 {
911   int   snum;
912   CHECK_INT (no);
913   CHECK_INT (serial);
914   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
915   if (!wnnfns_buf[snum]) return Qnil;
916   if (jl_word_use (wnnfns_buf[snum], XINT (no), XINT (serial)) < 0)
917     return Qnil;
918   else return Qt;
919 }
920
921 DEFUN ("wnn-server-word-info", Fwnn_word_info, 2, 2, 0, /*
922 Return list of yomi, kanji, comment, hindo, hinshi.
923 */
924      (no, serial))
925 {
926   Lisp_Object           val;
927   struct wnn_jdata      *info_buf;
928   unsigned char         cbuf[512];
929   int                   snum;
930   unsigned char         lb;
931   CHECK_INT (no);
932   CHECK_INT (serial);
933   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
934   lb = lb_wnn_server_type[snum];
935   if (!wnnfns_buf[snum]) return Qnil;
936   if ((info_buf =  jl_word_info (wnnfns_buf[snum],
937                                  XINT (no), XINT (serial))) != NULL)
938     {
939       return Qnil;
940     }
941   else
942     {
943       val = Qnil;
944       val = Fcons (make_int (info_buf->hinshi), val);
945       val = Fcons (make_int (info_buf->hindo), val);
946       w2m (info_buf->com, cbuf, lb);
947       val = Fcons (make_string (cbuf, strlen ((char *) cbuf)), val);
948       w2m (info_buf->kanji, cbuf, lb);
949       val = Fcons (make_string (cbuf, strlen ((char *) cbuf)), val);
950       w2m (info_buf->yomi, cbuf, lb);
951       val = Fcons (make_string (cbuf, strlen ((char *) cbuf)), val);
952       return val;
953     }
954 }
955
956 DEFUN ("wnn-server-word-hindo-set", Fwnn_hindo_set, 3, 3, 0, /*
957 Set frequency to arbitrary value. Specified by DIC-NUMBER,
958 SERIAL-NUMBER, FREQUENCY.
959 */
960      (no, serial, hindo))
961 {
962   int   snum;
963   CHECK_INT (no);
964   CHECK_INT (serial);
965   CHECK_INT (hindo);
966   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
967   if (!wnnfns_buf[snum]) return Qnil;
968   if (js_hindo_set (jl_env_get (wnnfns_buf[snum]),
969                     XINT (no),
970                     XINT (serial),
971                     WNN_HINDO_NOP,
972                     XINT (hindo)) < 0)
973     return Qnil;
974   else return Qt;
975 }
976
977
978 DEFUN ("wnn-server-word-search", Fwnn_dict_search, 1, 1, 0, /*
979 Search a word YOMI from buffer.
980 Return list of (kanji hinshi freq dic_no serial).
981 */
982      (yomi))
983 {
984   Lisp_Object           val;
985   struct wnn_jdata      *wordinfo;
986   int                   i, count;
987   w_char                        wbuf[256];
988   unsigned char         kanji_buf[256];
989   int                   snum;
990   unsigned char         lb;
991   CHECK_STRING (yomi);
992   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
993   lb = lb_wnn_server_type[snum];
994   if (!wnnfns_buf[snum]) return Qnil;
995   m2w (XSTRING_DATA (yomi), wbuf);
996   if (snum == WNNSERVER_C)
997     w2y (wbuf);
998   if ((count = jl_word_search_by_env (wnnfns_buf[snum],
999                                       wbuf, &wordinfo)) < 0)
1000     return Qnil;
1001   val = Qnil;
1002   for (i = 0, wordinfo += count; i < count; i++)
1003     {
1004       wordinfo--;
1005       w2m (wordinfo->kanji, kanji_buf, lb);
1006       val = Fcons (Fcons (make_string (kanji_buf, strlen ((char *) kanji_buf)),
1007                           list4 (make_int (wordinfo->hinshi),
1008                                  make_int (wordinfo->hindo),
1009                                  make_int (wordinfo->dic_no),
1010                                  make_int (wordinfo->serial))),
1011                    val);
1012     }
1013   return val;
1014 }
1015
1016 DEFUN ("wnn-server-dict-save", Fwnn_dict_save, 0, 0, 0, /*
1017 Save all dictionaries and frequency files.
1018 */
1019      ())
1020 {
1021   int   snum;
1022   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
1023   if (!wnnfns_buf[snum]) return Qnil;
1024   if (jl_dic_save_all (wnnfns_buf[snum]) < 0) return Qnil;
1025   else return Qt;
1026 }
1027
1028 DEFUN ("wnn-server-get-param", Fwnn_get_param, 0, 0, 0, /*
1029 Returns (n nsho hindo len jiri flag jisho sbn dbn_len sbn_cnt
1030 suuji kana eisuu kigou toji_kakko fuzokogo kaikakko)
1031 */
1032      ())
1033 {
1034   struct wnn_param      param;
1035   int   snum;
1036   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
1037   if (!wnnfns_buf[snum]) return Qnil;
1038   if (jl_param_get (wnnfns_buf[snum], &param) < 0) return Qnil;
1039   return Fcons (make_int (param.n),
1040          Fcons (make_int (param.nsho),
1041          Fcons (make_int (param.p1),
1042          Fcons (make_int (param.p2),
1043          Fcons (make_int (param.p3),
1044          Fcons (make_int (param.p4),
1045          Fcons (make_int (param.p5),
1046          Fcons (make_int (param.p6),
1047          Fcons (make_int (param.p7),
1048          Fcons (make_int (param.p8),
1049          Fcons (make_int (param.p9),
1050          Fcons (make_int (param.p10),
1051          Fcons (make_int (param.p11),
1052          Fcons (make_int (param.p12),
1053          Fcons (make_int (param.p13),
1054          Fcons (make_int (param.p14),
1055          Fcons (make_int (param.p15),Qnil)))))))))))))))));
1056 }
1057
1058 DEFUN ("wnn-server-set-param", Fwnn_set_param, 1, 1, 0, /*
1059 Set parameters using an alist, where the CAR contains one of
1060 wnn_n, wnn_nsho, wnn_hindo, wnn_len, wnn_jiri, wnn_flag,
1061 wnn_jisho, wnn_sbn, wnn_dbn_len, wnn_sbn_cnt, wnn_suuji,
1062 wnn_kana, wnn_eisuu, wnn_kigou, wnn_toji_kakko, wnn_fuzokogo,
1063 or wnn_kaikakko and the CDR contains the value.
1064 */
1065      (Vsetvalues_alist))
1066 {
1067   int             rc;
1068   struct wnn_param      param;
1069   int   snum;
1070
1071   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
1072   if (!wnnfns_buf[snum]) return Qnil;
1073   rc = jl_param_get (wnnfns_buf[snum], &param);
1074   if (rc < 0) return Qnil;
1075
1076   {
1077     EXTERNAL_PROPERTY_LIST_LOOP_3 (key, val, Vsetvalues_alist)
1078       {
1079         int setval;
1080         CHECK_INT (val);
1081         setval = XINT (val);
1082         if (EQ (key, Qwnn_n)) param.n = setval;
1083         else if (EQ (key, Qwnn_nsho)) param.nsho = setval;
1084         else if (EQ (key, Qwnn_hindo)) param.p1 = setval;
1085         else if (EQ (key, Qwnn_len)) param.p2 = setval;
1086         else if (EQ (key, Qwnn_jiri)) param.p3 = setval;
1087         else if (EQ (key, Qwnn_flag)) param.p4 = setval;
1088         else if (EQ (key, Qwnn_jisho)) param.p5 = setval;
1089         else if (EQ (key, Qwnn_sbn)) param.p6 = setval;
1090         else if (EQ (key, Qwnn_dbn_len)) param.p7 = setval;
1091         else if (EQ (key, Qwnn_sbn_cnt)) param.p8 = setval;
1092         else if (EQ (key, Qwnn_suuji)) param.p9 = setval;
1093         else if (EQ (key, Qwnn_kana)) param.p10 = setval;
1094         else if (EQ (key, Qwnn_eisuu)) param.p11 = setval;
1095         else if (EQ (key, Qwnn_kigou)) param.p12 = setval;
1096         else if (EQ (key, Qwnn_toji_kakko)) param.p13 = setval;
1097         else if (EQ (key, Qwnn_fuzokogo)) param.p14 = setval;
1098         else if (EQ (key, Qwnn_kaikakko)) param.p15 = setval;
1099         else
1100           {
1101             signal_simple_error ("Invalid wnn keyword", key);
1102             return Qnil;
1103           }
1104       }
1105   }
1106
1107 #if 0
1108   printf("wnn_n = %d\n",param.n);
1109   printf("wnn_nsho = %d\n",param.nsho);
1110   printf("wnn_hindo = %d\n",param.p1);
1111   printf("wnn_len = %d\n",param.p2);
1112   printf("wnn_jiri = %d\n",param.p3);
1113   printf("wnn_flag = %d\n",param.p4);
1114   printf("wnn_jisho = %d\n",param.p5);
1115   printf("wnn_sbn = %d\n",param.p6);
1116   printf("wnn_dbn_len = %d\n",param.p7);
1117   printf("wnn_sbn_cnt = %d\n",param.p8);
1118   printf("wnn_suuji = %d\n",param.p9);
1119   printf("wnn_kana = %d\n",param.p10);
1120   printf("wnn_eisuu = %d\n",param.p11);
1121   printf("wnn_kigou = %d\n",param.p12);
1122   printf("wnn_toji_kakko = %d\n",param.p13);
1123   printf("wnn_fuzokogo = %d\n",param.p14);
1124   printf("wnn_kaikakko = %d\n",param.p15);
1125 #endif
1126
1127   rc = jl_param_set (wnnfns_buf[snum], &param);
1128   if (rc < 0) return Qnil;
1129   return Qt;
1130 }
1131
1132 DEFUN ("wnn-server-get-msg", Fwnn_get_msg, 0, 0, 0, /*
1133 Get message string from wnn_perror.
1134 */
1135      ())
1136 {
1137   unsigned char mbuf[256];
1138   char                  *msgp;
1139   int                   snum;
1140   unsigned char         lb;
1141   char  langname[32];
1142 /*  CHECK_INT (errno);*/
1143   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
1144   lb = lb_wnn_server_type[snum];
1145   switch (snum)
1146     {
1147     case WNNSERVER_J:
1148       strcpy (langname, "ja_JP");
1149       break;
1150     case WNNSERVER_C:
1151       strcpy (langname, "zh_CN");
1152       break;
1153 /*
1154   case WNNSERVER_T:
1155   strcpy (langname, "zh_TW");
1156   break;
1157   */
1158     case WNNSERVER_K:
1159       strcpy (langname, "ko_KR");
1160       break;
1161     }
1162   if (!wnnfns_buf[snum]) return Qnil;
1163 /*  msgp = msg_get (wnn_msg_cat, XINT (errno), 0, 0);*/
1164   msgp = wnn_perror_lang (langname);
1165   c2m ((unsigned char *) msgp, mbuf, lb);
1166   return make_string (mbuf, strlen ((char *) mbuf));
1167 }
1168
1169
1170 DEFUN ("wnn-server-fuzokugo-set", Fwnn_fuzokugo_set, 1, 1, 0, /*
1171 For Wnn.
1172 */
1173      (file))
1174 {
1175   int   snum;
1176   CHECK_STRING (file);
1177   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
1178   if (!wnnfns_buf[snum]) return Qnil;
1179   if (jl_fuzokugo_set (wnnfns_buf[snum], XSTRING_DATA (file)) < 0)
1180     return Qnil;
1181   return Qt;
1182 }
1183
1184 DEFUN ("wnn-server-fuzokugo-get", Fwnn_fuzokugo_get, 0, 0, 0, /*
1185 For Wnn.
1186 */
1187      ())
1188 {
1189   char  fname[256];
1190   int   snum;
1191   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
1192   if (!wnnfns_buf[snum]) return Qnil;
1193   if (jl_fuzokugo_get (wnnfns_buf[snum], fname) < 0) return Qnil;
1194   return make_string ((Bufbyte *) fname, strlen (fname));
1195 }
1196
1197
1198 DEFUN ("wnn-server-isconnect", Fwnn_isconnect, 0, 0, 0, /*
1199 For Wnn.
1200 */
1201      ())
1202 {
1203   int   snum;
1204   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
1205   if (!wnnfns_buf[snum]) return Qnil;
1206   if (jl_isconnect (wnnfns_buf[snum])) return Qt;
1207   else return Qnil;
1208 }
1209
1210 DEFUN ("wnn-server-hinsi-dicts", Fwnn_hinsi_dicts, 1, 1, 0, /*
1211 For Wnn.
1212 */
1213      (hinsi))
1214 {
1215   int           *area;
1216   int           cnt;
1217   Lisp_Object   val;
1218   int   snum;
1219   CHECK_INT (hinsi);
1220   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
1221   if (!wnnfns_buf[snum]) return Qnil;
1222   if ((cnt = jl_hinsi_dicts (wnnfns_buf[snum], XINT (hinsi), &area)) < 0)
1223     return Qnil;
1224   val = Qnil;
1225   for (area += cnt; cnt > 0; cnt--)
1226     {
1227       area--;
1228       val = Fcons (make_int (*area), val);
1229     }
1230   return val;
1231 }
1232
1233 DEFUN ("wnn-server-hinsi-list", Fwnn_hinsi_list, 2, 2, 0, /*
1234 For Wnn.
1235 */
1236      (dicno, name))
1237 {
1238   int           cnt;
1239   Lisp_Object   val;
1240   w_char                wbuf[256];
1241   w_char                **area;
1242   unsigned char cbuf[512];
1243   int           snum;
1244   unsigned char lb;
1245   CHECK_INT (dicno);
1246   CHECK_STRING (name);
1247   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
1248   lb = lb_wnn_server_type[snum];
1249   if (!wnnfns_buf[snum]) return Qnil;
1250   m2w (XSTRING_DATA (name), wbuf);
1251   if ((cnt = jl_hinsi_list (wnnfns_buf[snum], XINT (dicno), wbuf, &area)) < 0)
1252     return Qnil;
1253   if (cnt == 0) return make_int (0);
1254   val = Qnil;
1255   for (area += cnt; cnt > 0; cnt--)
1256     {
1257       area--;
1258       w2m (*area, cbuf, lb);
1259       val = Fcons (make_string (cbuf, strlen ((char *) cbuf)), val);
1260     }
1261   return val;
1262 }
1263
1264 DEFUN ("wnn-server-hinsi-name", Fwnn_hinsi_name, 1, 1, 0, /*
1265 For Wnn.
1266 */
1267      (no))
1268 {
1269   unsigned char name[256];
1270   w_char                *wname;
1271   int                   snum;
1272   unsigned char         lb;
1273   CHECK_INT (no);
1274   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
1275   lb = lb_wnn_server_type[snum];
1276   if (!wnnfns_buf[snum]) return Qnil;
1277   if ((wname = jl_hinsi_name (wnnfns_buf[snum], XINT (no))) == 0) return Qnil;
1278   w2m (wname, name, lb);
1279   return make_string (name, strlen ((char *) name));
1280 }
1281 #ifdef  WNN6
1282 DEFUN ("wnn-server-fisys-dict-add", Fwnn_fisys_dict_add, 3, MANY, 0, /*
1283 Add dictionary specified by FISYS-DICT-FILE-NAME, FISYS-FREQ-FILE-NAME,
1284 FISYS-FREQ-FILE-MODE.
1285 Specify password files of dictionary and frequency, PW1 and PW2, if needed.
1286 */
1287      (int nargs, Lisp_Object *args))
1288 {
1289   struct gcpro gcpro1;
1290   int   snum;
1291   CHECK_STRING (args[0]);
1292   CHECK_STRING (args[1]);
1293   if (! NILP (args[3])) CHECK_STRING (args[3]);
1294   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1295   if(!wnnfns_buf[snum]) return Qnil;
1296   GCPRO1 (*args);
1297   gcpro1.nvars = nargs;
1298   if(jl_fi_dic_add(wnnfns_buf[snum],
1299                    XSTRING_DATA (args[0]),
1300                    XSTRING_DATA (args[1]),
1301                    WNN_FI_SYSTEM_DICT,
1302                    WNN_DIC_RDONLY,
1303                    NILP (args[2]) ? WNN_DIC_RDONLY : WNN_DIC_RW,
1304                    0,
1305                    NILP (args[3]) ? 0 : XSTRING_DATA (args[3]),
1306                    yes_or_no,
1307                    puts2 ) < 0) {
1308     UNGCPRO;
1309     return Qnil;
1310   }
1311   UNGCPRO;
1312   return Qt;
1313 }
1314
1315 DEFUN ("wnn-server-fiusr-dict-add", Fwnn_fiusr_dict_add, 4, MANY, 0, /*
1316 Add dictionary specified by FIUSR-DICT-FILE-NAME, FIUSR-FREQ-FILE-NAME,
1317 FIUSR-DICT-FILE-MODE, FIUSR-FREQ-FILE-MODE.
1318 Specify password files of dictionary and frequency, PW1 and PW2, if needed.
1319 */
1320      (int nargs, Lisp_Object *args))
1321 {
1322   struct gcpro gcpro1;
1323   int   snum;
1324   CHECK_STRING (args[0]);
1325   CHECK_STRING (args[1]);
1326   if (! NILP (args[4])) CHECK_STRING (args[4]);
1327   if (! NILP (args[5])) CHECK_STRING (args[5]);
1328   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1329   if(!wnnfns_buf[snum]) return Qnil;
1330   GCPRO1 (*args);
1331   gcpro1.nvars = nargs;
1332   if(jl_fi_dic_add(wnnfns_buf[snum],
1333                    XSTRING_DATA (args[0]),
1334                    XSTRING_DATA (args[1]),
1335                    WNN_FI_USER_DICT,
1336                    NILP (args[2]) ? WNN_DIC_RDONLY : WNN_DIC_RW,
1337                    NILP (args[3]) ? WNN_DIC_RDONLY : WNN_DIC_RW,
1338                    NILP (args[4]) ? 0 : XSTRING_DATA (args[4]),
1339                    NILP (args[5]) ? 0 : XSTRING_DATA (args[5]),
1340                    yes_or_no,
1341                    puts2 ) < 0) {
1342     UNGCPRO;
1343     return Qnil;
1344   }
1345   UNGCPRO;
1346   return Qt;
1347 }
1348
1349 DEFUN ("wnn-server-notrans-dict-add", Fwnn_notrans_dict_add, 3, MANY, 0, /*
1350 Add dictionary specified by NOTRANS-DICT-FILE-NAME, PRIORITY, DICT-FILE-MODE.
1351 Specify password files of dictionary and frequency PW1 if needed.
1352 */
1353      (int nargs, Lisp_Object *args))
1354 {
1355   struct gcpro gcpro1;
1356   int   snum;
1357   int   dic_no;
1358   struct wnn_env *cur_env;
1359   unsigned long vmask = 0;
1360   struct wnn_henkan_env henv;
1361   CHECK_STRING (args[0]);
1362   CHECK_INT (args[1]);
1363   if (! NILP (args[3])) CHECK_STRING (args[3]);
1364   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1365   if(!wnnfns_buf[snum]) return Qnil;
1366   GCPRO1 (*args);
1367   gcpro1.nvars = nargs;
1368   if(wnnfns_norm)
1369       cur_env = wnnfns_env_norm[snum];
1370   else
1371       cur_env = wnnfns_env_rev[snum];
1372   dic_no = js_get_autolearning_dic(cur_env, WNN_MUHENKAN_LEARNING);
1373   if (dic_no == WNN_NO_LEARNING) {
1374       if((dic_no = jl_dic_add(wnnfns_buf[snum],
1375                               XSTRING_DATA (args[0]),
1376                               0,
1377                               wnnfns_norm ? WNN_DIC_ADD_NOR : WNN_DIC_ADD_REV,
1378                               XINT(args[1]),
1379                               WNN_DIC_RW, WNN_DIC_RW,
1380                               NILP (args[3]) ? 0 : XSTRING_DATA (args[3]),
1381                               0,
1382                               yes_or_no,
1383                               puts2)) < 0) {
1384           UNGCPRO;
1385           return Qnil;
1386       }
1387       js_set_autolearning_dic(cur_env, WNN_MUHENKAN_LEARNING, dic_no);
1388   }
1389   if(!js_is_loaded_temporary_dic(cur_env)) {
1390       if(js_temporary_dic_add(cur_env,
1391                               wnnfns_norm ? WNN_DIC_ADD_NOR : WNN_DIC_ADD_REV) < 0) {
1392           UNGCPRO;
1393           return Qnil;
1394       }
1395   }
1396   vmask |= WNN_ENV_MUHENKAN_LEARN_MASK;
1397   henv.muhenkan_flag = NILP (args[2]) ? WNN_DIC_RDONLY : WNN_DIC_RW;
1398   if(jl_set_henkan_env(wnnfns_buf[snum],
1399                        vmask,
1400                        &henv) < 0) {
1401       UNGCPRO;
1402       return Qnil;
1403   }
1404   UNGCPRO;
1405   return Qt;
1406 }
1407
1408 DEFUN ("wnn-server-bmodify-dict-add", Fwnn_bmodify_dict_add, 3, MANY, 0, /*
1409 Add dictionary specified by BMODIFY-DICT-FILE-NAME, PRIORITY, DICT-FILE-MODE.
1410 Specify password files of dictionary and frequency PW1 if needed.
1411 */
1412      (int nargs, Lisp_Object *args))
1413 {
1414   struct gcpro gcpro1;
1415   int   snum;
1416   int   dic_no;
1417   struct wnn_env *cur_env;
1418   unsigned long vmask = 0;
1419   struct wnn_henkan_env henv;
1420   CHECK_STRING (args[0]);
1421   CHECK_INT (args[1]);
1422   if (! NILP (args[3])) CHECK_STRING (args[3]);
1423   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1424   if(!wnnfns_buf[snum]) return Qnil;
1425   GCPRO1 (*args);
1426   gcpro1.nvars = nargs;
1427   if(wnnfns_norm)
1428       cur_env = wnnfns_env_norm[snum];
1429   else
1430       cur_env = wnnfns_env_rev[snum];
1431   dic_no = js_get_autolearning_dic(cur_env, WNN_BUNSETSUGIRI_LEARNING);
1432   if (dic_no == WNN_NO_LEARNING) {
1433       if((dic_no = jl_dic_add(wnnfns_buf[snum],
1434                               XSTRING_DATA (args[0]),
1435                               0,
1436                               wnnfns_norm ? WNN_DIC_ADD_NOR : WNN_DIC_ADD_REV,
1437                               XINT(args[1]),
1438                               WNN_DIC_RW, WNN_DIC_RW,
1439                               NILP (args[3]) ? 0 : XSTRING_DATA (args[3]),
1440                               0,
1441                               yes_or_no,
1442                               puts2)) < 0) {
1443           UNGCPRO;
1444           return Qnil;
1445       }
1446       js_set_autolearning_dic(cur_env, WNN_BUNSETSUGIRI_LEARNING, dic_no);
1447   }
1448   if(!js_is_loaded_temporary_dic(cur_env)) {
1449       if(js_temporary_dic_add(cur_env,
1450                               wnnfns_norm ? WNN_DIC_ADD_NOR : WNN_DIC_ADD_REV) < 0) {
1451           UNGCPRO;
1452           return Qnil;
1453       }
1454   }
1455   vmask |= WNN_ENV_BUNSETSUGIRI_LEARN_MASK;
1456   henv.bunsetsugiri_flag = NILP (args[2]) ? WNN_DIC_RDONLY : WNN_DIC_RW;
1457   if(jl_set_henkan_env(wnnfns_buf[snum],
1458                        vmask,
1459                        &henv) < 0) {
1460       UNGCPRO;
1461       return Qnil;
1462   }
1463   UNGCPRO;
1464   return Qt;
1465 }
1466
1467 DEFUN ("wnn-server-set-last-is-first", Fwnn_last_is_first, 1, 1, 0, /*
1468 For FI-Wnn.
1469 */
1470      (mode))
1471 {
1472   int   snum;
1473   unsigned long vmask = 0;
1474   struct wnn_henkan_env henv;
1475   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1476   if(!wnnfns_buf[snum]) return Qnil;
1477   vmask |= WNN_ENV_LAST_IS_FIRST_MASK;
1478   henv.last_is_first_flag = NILP (mode) ? False : True;
1479   if(jl_set_henkan_env(wnnfns_buf[snum],
1480                        vmask,
1481                        &henv) < 0) return Qnil;
1482   return Qt;
1483 }
1484
1485 DEFUN ("wnn-server-set-complex-conv-mode", Fwnn_complex_conv, 1, 1, 0, /*
1486 For FI-Wnn.
1487 */
1488      (mode))
1489 {
1490   int   snum;
1491   unsigned long vmask = 0;
1492   struct wnn_henkan_env henv;
1493   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1494   if(!wnnfns_buf[snum]) return Qnil;
1495   vmask |= WNN_ENV_COMPLEX_CONV_MASK;
1496   henv.complex_flag = NILP (mode) ? False : True;
1497   if(jl_set_henkan_env(wnnfns_buf[snum],
1498                        vmask,
1499                        &henv) < 0) return Qnil;
1500   return Qt;
1501 }
1502
1503 DEFUN ("wnn-server-set-okuri-learn-mode", Fwnn_okuri_learn, 1, 1, 0, /*
1504 For FI-Wnn.
1505 */
1506      (mode))
1507 {
1508   int   snum;
1509   unsigned long vmask = 0;
1510   struct wnn_henkan_env henv;
1511   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1512   if(!wnnfns_buf[snum]) return Qnil;
1513   vmask |= WNN_ENV_OKURI_LEARN_MASK;
1514   henv.okuri_learn_flag = NILP (mode) ? False : True;
1515   if(jl_set_henkan_env(wnnfns_buf[snum],
1516                        vmask,
1517                        &henv) < 0) return Qnil;
1518   return Qt;
1519 }
1520
1521 DEFUN ("wnn-server-set-okuri-flag", Fwnn_okuri_flag, 1, 1, 0, /*
1522 For FI-Wnn.
1523 */
1524      (lmode))
1525 {
1526   int   snum, mode;
1527   unsigned long vmask = 0;
1528   struct wnn_henkan_env henv;
1529   CHECK_INT (lmode);
1530   mode = XINT (lmode);
1531   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1532   if(!wnnfns_buf[snum]) return Qnil;
1533   if(mode != WNN_OKURI_REGULATION &&
1534      mode != WNN_OKURI_NO &&
1535      mode != WNN_OKURI_YES)
1536       return Qnil;
1537   else
1538       henv.okuri_flag = mode;
1539   vmask |= WNN_ENV_OKURI_MASK;
1540   if(jl_set_henkan_env(wnnfns_buf[snum],
1541                        vmask,
1542                        &henv) < 0) return Qnil;
1543   return Qt;
1544 }
1545
1546 DEFUN ("wnn-server-set-prefix-learn-mode", Fwnn_prefix_learn, 1, 1, 0, /*
1547 For FI-Wnn.
1548 */
1549      (mode))
1550 {
1551   int   snum;
1552   unsigned long vmask = 0;
1553   struct wnn_henkan_env henv;
1554   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1555   if(!wnnfns_buf[snum]) return Qnil;
1556   vmask |= WNN_ENV_PREFIX_LEARN_MASK;
1557   henv.prefix_learn_flag = NILP (mode) ? False : True;
1558   if(jl_set_henkan_env(wnnfns_buf[snum],
1559                        vmask,
1560                        &henv) < 0) return Qnil;
1561   return Qt;
1562 }
1563
1564 DEFUN ("wnn-server-set-prefix-flag", Fwnn_prefix_flag, 1, 1, 0, /*
1565 For FI-Wnn.
1566 */
1567      (lmode))
1568 {
1569   int   snum, mode;
1570   unsigned long vmask = 0;
1571   struct wnn_henkan_env henv;
1572   CHECK_INT (lmode);
1573   mode = XINT (lmode);
1574   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1575   if(!wnnfns_buf[snum]) return Qnil;
1576   if(mode != WNN_KANA_KOUHO && mode != WNN_KANJI_KOUHO)
1577       return Qnil;
1578   else
1579       henv.prefix_flag = mode;
1580   vmask |= WNN_ENV_PREFIX_MASK;
1581   if(jl_set_henkan_env(wnnfns_buf[snum],
1582                        vmask,
1583                        &henv) < 0) return Qnil;
1584   return Qt;
1585 }
1586
1587 DEFUN ("wnn-server-set-suffix-learn-mode", Fwnn_suffix_learn, 1, 1, 0, /*
1588 For FI-Wnn.
1589 */
1590      (mode))
1591 {
1592   int   snum;
1593   unsigned long vmask = 0;
1594   struct wnn_henkan_env henv;
1595   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1596   if(!wnnfns_buf[snum]) return Qnil;
1597   vmask |= WNN_ENV_SUFFIX_LEARN_MASK;
1598   henv.suffix_learn_flag = NILP (mode) ? False : True;
1599   if(jl_set_henkan_env(wnnfns_buf[snum],
1600                        vmask,
1601                        &henv) < 0) return Qnil;
1602   return Qt;
1603 }
1604
1605 DEFUN ("wnn-server-set-common-learn-mode", Fwnn_common_learn, 1, 1, 0, /*
1606 For FI-Wnn.
1607 */
1608      (mode))
1609 {
1610   int   snum;
1611   unsigned long vmask = 0;
1612   struct wnn_henkan_env henv;
1613   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1614   if(!wnnfns_buf[snum]) return Qnil;
1615   vmask |= WNN_ENV_COMMON_LAERN_MASK;
1616   henv.common_learn_flag = NILP (mode) ? False : True;
1617   if(jl_set_henkan_env(wnnfns_buf[snum],
1618                        vmask,
1619                        &henv) < 0) return Qnil;
1620   return Qt;
1621 }
1622
1623 DEFUN ("wnn-server-set-freq-func-mode", Fwnn_freq_func, 1, 1, 0, /*
1624 For FI-Wnn.
1625 */
1626      (lmode))
1627 {
1628   int   snum, mode;
1629   unsigned long vmask = 0;
1630   struct wnn_henkan_env henv;
1631   CHECK_INT (lmode);
1632   mode = XINT (lmode);
1633   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1634   if(!wnnfns_buf[snum]) return Qnil;
1635   if(mode != 0 && mode != 1 && mode != 2 && mode != 3 && mode != 4)
1636       return Qnil;
1637   else
1638       henv.freq_func_flag = mode;
1639   vmask |= WNN_ENV_FREQ_FUNC_MASK;
1640   if(jl_set_henkan_env(wnnfns_buf[snum],
1641                        vmask,
1642                        &henv) < 0) return Qnil;
1643   return Qt;
1644 }
1645
1646 DEFUN ("wnn-server-set-numeric-mode", Fwnn_numeric, 1, 1, 0, /*
1647 For FI-Wnn.
1648 */
1649      (lmode))
1650 {
1651   int   snum, mode;
1652   unsigned long vmask = 0;
1653   struct wnn_henkan_env henv;
1654   CHECK_INT (lmode);
1655   mode = XINT (lmode);
1656   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1657   if(!wnnfns_buf[snum]) return Qnil;
1658   if(mode != WNN_NUM_KANSUUJI &&
1659      mode != WNN_NUM_KANOLD &&
1660      mode != WNN_NUM_HANCAN &&
1661      mode != WNN_NUM_ZENCAN &&
1662      mode != WNN_NUM_HAN &&
1663      mode != WNN_NUM_ZEN &&
1664      mode != WNN_NUM_KAN)
1665       return Qnil;
1666   else
1667       henv.numeric_flag = mode;
1668   vmask |= WNN_ENV_NUMERIC_MASK;
1669   if(jl_set_henkan_env(wnnfns_buf[snum],
1670                        vmask,
1671                        &henv) < 0) return Qnil;
1672   return Qt;
1673 }
1674
1675 DEFUN ("wnn-server-set-alphabet-mode", Fwnn_alphabet, 1, 1, 0, /*
1676 For FI-Wnn.
1677 */
1678      (lmode))
1679 {
1680   int   snum, mode;
1681   unsigned long vmask = 0;
1682   struct wnn_henkan_env henv;
1683   CHECK_INT (lmode);
1684   mode = XINT (lmode);
1685   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1686   if(!wnnfns_buf[snum]) return Qnil;
1687   if(mode != WNN_ALP_HAN && mode != WNN_ALP_ZEN)
1688       return Qnil;
1689   else
1690       henv.alphabet_flag = mode;
1691   vmask |= WNN_ENV_ALPHABET_MASK;
1692   if(jl_set_henkan_env(wnnfns_buf[snum],
1693                        vmask,
1694                        &henv) < 0) return Qnil;
1695   return Qt;
1696 }
1697
1698 DEFUN ("wnn-server-set-symbol-mode", Fwnn_symbol, 1, 1, 0, /*
1699 For FI-Wnn.
1700 */
1701      (lmode))
1702 {
1703   int   snum, mode;
1704   unsigned long vmask = 0;
1705   struct wnn_henkan_env henv;
1706   CHECK_INT (lmode);
1707   mode = XINT (lmode);
1708   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1709   if(!wnnfns_buf[snum]) return Qnil;
1710   if(mode != WNN_KIG_HAN && mode != WNN_KIG_JIS && mode != WNN_KIG_ASC)
1711       return Qnil;
1712   else
1713       henv.symbol_flag = mode;
1714   vmask |= WNN_ENV_SYMBOL_MASK;
1715   if(jl_set_henkan_env(wnnfns_buf[snum],
1716                        vmask,
1717                        &henv) < 0) return Qnil;
1718   return Qt;
1719 }
1720
1721 DEFUN ("wnn-server-set-yuragi-mode", Fwnn_yuragi, 1, 1, 0, /*
1722 For FI-Wnn.
1723 */
1724      (mode))
1725 {
1726   int   snum;
1727   unsigned long vmask = 0;
1728   struct wnn_henkan_env henv;
1729   if ((snum = check_wnn_server_type()) == -1) return Qnil;
1730   if(!wnnfns_buf[snum]) return Qnil;
1731   vmask |= WNN_ENV_YURAGI_MASK;
1732   henv.yuragi_flag = NILP (mode) ? False : True;
1733   if(jl_set_henkan_env(wnnfns_buf[snum],
1734                        vmask,
1735                        &henv) < 0) return Qnil;
1736   return Qt;
1737 }
1738
1739 DEFUN ("wnn-reset-previous-info", Fwnn_reset_prev, 0, 0, 0, /*
1740 For FI-Wnn.
1741 */
1742     ())
1743 {
1744     int   snum;
1745     if ((snum = check_wnn_server_type()) == -1) return Qnil;
1746     if(!wnnfns_buf[snum]) return Qnil;
1747     if(jl_reset_prev_bun(wnnfns_buf[snum]) < 0) return Qnil;
1748     return Qt;
1749 }
1750 #endif  /* Wnn6 */
1751
1752 DEFUN ("wnn-server-version", Fwnn_version, 0, 0, 0, /*
1753 Returns Wnn server version ID.
1754 */
1755     ())
1756 {
1757     int   snum;
1758     int   serv;
1759     int   libv;
1760     struct wnn_env *cur_env;
1761     if ((snum = check_wnn_server_type()) == -1) return Qnil;
1762     if(!wnnfns_buf[snum]) return Qnil;
1763     if(wnnfns_norm)
1764       cur_env = wnnfns_env_norm[snum];
1765     else
1766       cur_env = wnnfns_env_rev[snum];
1767     if(js_version (cur_env->js_id,&serv,&libv) < 0) return Qnil;
1768     return make_int (serv);
1769 }
1770
1771 DEFUN ("wnn-server-hinsi-number", Fwnn_hinsi_number, 1, 1, 0, /*
1772 For Wnn.
1773 */
1774      (name))
1775 {
1776   w_char                w_buf[256];
1777   int           no;
1778   int   snum;
1779   CHECK_STRING (name);
1780   if ((snum = check_wnn_server_type ()) == -1) return Qnil;
1781   if (!wnnfns_buf[snum]) return Qnil;
1782   m2w (XSTRING_DATA (name), w_buf);
1783   if ((no = jl_hinsi_number (wnnfns_buf[snum], w_buf)) < 0) return Qnil;
1784   return make_int (no);
1785 }
1786
1787 void
1788 syms_of_mule_wnn (void)
1789 {
1790   DEFSUBR (Fwnn_open);
1791   DEFSUBR (Fwnn_close);
1792   DEFSUBR (Fwnn_dict_add);
1793   DEFSUBR (Fwnn_dict_delete);
1794   DEFSUBR (Fwnn_dict_list);
1795   DEFSUBR (Fwnn_dict_comment);
1796   DEFSUBR (Fwnn_set_rev);
1797   DEFSUBR (Fwnn_begin_henkan);
1798   DEFSUBR (Fwnn_zenkouho);
1799   DEFSUBR (Fwnn_get_zenkouho);
1800   DEFSUBR (Fwnn_zenkouho_bun);
1801   DEFSUBR (Fwnn_zenkouho_suu);
1802   DEFSUBR (Fwnn_dai_top);
1803   DEFSUBR (Fwnn_dai_end);
1804   DEFSUBR (Fwnn_kakutei);
1805   DEFSUBR (Fwnn_bunsetu_henkou);
1806   DEFSUBR (Fwnn_inspect);
1807   DEFSUBR (Fwnn_quit_henkan);
1808   DEFSUBR (Fwnn_bunsetu_kanji);
1809   DEFSUBR (Fwnn_bunsetu_yomi);
1810   DEFSUBR (Fwnn_bunsetu_suu);
1811   DEFSUBR (Fwnn_hindo_update);
1812   DEFSUBR (Fwnn_word_toroku);
1813   DEFSUBR (Fwnn_word_sakujo);
1814   DEFSUBR (Fwnn_word_use);
1815   DEFSUBR (Fwnn_word_info);
1816   DEFSUBR (Fwnn_hindo_set);
1817   DEFSUBR (Fwnn_dict_search);
1818   DEFSUBR (Fwnn_dict_save);
1819   DEFSUBR (Fwnn_get_param);
1820   DEFSUBR (Fwnn_set_param);
1821   DEFSUBR (Fwnn_get_msg);
1822   DEFSUBR (Fwnn_fuzokugo_set);
1823   DEFSUBR (Fwnn_fuzokugo_get);
1824   DEFSUBR (Fwnn_isconnect);
1825   DEFSUBR (Fwnn_hinsi_dicts);
1826   DEFSUBR (Fwnn_hinsi_list);
1827   DEFSUBR (Fwnn_hinsi_name);
1828   DEFSUBR (Fwnn_hinsi_number);
1829 #ifdef  WNN6
1830   DEFSUBR (Fwnn_fisys_dict_add);
1831   DEFSUBR (Fwnn_fiusr_dict_add);
1832   DEFSUBR (Fwnn_notrans_dict_add);
1833   DEFSUBR (Fwnn_bmodify_dict_add);
1834   DEFSUBR (Fwnn_last_is_first);
1835   DEFSUBR (Fwnn_complex_conv);
1836   DEFSUBR (Fwnn_okuri_learn);
1837   DEFSUBR (Fwnn_okuri_flag);
1838   DEFSUBR (Fwnn_prefix_learn);
1839   DEFSUBR (Fwnn_prefix_flag);
1840   DEFSUBR (Fwnn_suffix_learn);
1841   DEFSUBR (Fwnn_common_learn);
1842   DEFSUBR (Fwnn_freq_func);
1843   DEFSUBR (Fwnn_numeric);
1844   DEFSUBR (Fwnn_alphabet);
1845   DEFSUBR (Fwnn_symbol);
1846   DEFSUBR (Fwnn_yuragi);
1847   DEFSUBR (Fwnn_reset_prev);
1848 #endif  /* Wnn6 */
1849   DEFSUBR (Fwnn_version);
1850
1851   defsymbol (&Qjserver, "jserver");
1852   defsymbol (&Qcserver, "cserver");
1853   /* defsymbol (&Qtserver, "tserver"); */
1854   defsymbol (&Qkserver, "kserver");
1855
1856   defsymbol (&Qwnn_no_uniq, "wnn-no-uniq");
1857   defsymbol (&Qwnn_uniq, "wnn-uniq");
1858   defsymbol (&Qwnn_uniq_kanji, "wnn-uniq-kanji");
1859   defsymbol (&Qwnn_n, "wnn_n");
1860   defsymbol (&Qwnn_nsho, "wnn_nsho");
1861   defsymbol (&Qwnn_hindo, "wnn_hindo");
1862   defsymbol (&Qwnn_len, "wnn_len");
1863   defsymbol (&Qwnn_jiri, "wnn_jiri");
1864   defsymbol (&Qwnn_flag, "wnn_flag");
1865   defsymbol (&Qwnn_jisho, "wnn_jisho");
1866   defsymbol (&Qwnn_sbn, "wnn_sbn");
1867   defsymbol (&Qwnn_dbn_len, "wnn_dbn_len");
1868   defsymbol (&Qwnn_sbn_cnt, "wnn_sbn_cnt");
1869   defsymbol (&Qwnn_suuji, "wnn_suuji");
1870   defsymbol (&Qwnn_kana, "wnn_kana");
1871   defsymbol (&Qwnn_eisuu, "wnn_eisuu");
1872   defsymbol (&Qwnn_kigou, "wnn_kigou");
1873   defsymbol (&Qwnn_toji_kakko, "wnn_toji_kakko");
1874   defsymbol (&Qwnn_fuzokogo, "wnn_fuzokogo");
1875   defsymbol (&Qwnn_kaikakko, "wnn_kaikakko");
1876 }
1877
1878 void
1879 reinit_vars_of_mule_wnn (void)
1880 {
1881   int i;
1882
1883   for (i = 0; i < NSERVER; i++)
1884     {
1885       wnnfns_buf[i] = (struct wnn_buf *) 0;
1886       wnnfns_env_norm[i] = (struct wnn_env *) 0;
1887       wnnfns_env_rev[i] = (struct wnn_env *) 0;
1888     }
1889 }
1890
1891 void
1892 vars_of_mule_wnn (void)
1893 {
1894   reinit_vars_of_mule_wnn ();
1895
1896   DEFVAR_INT ("lb-sisheng", &lb_sisheng /*
1897 Leading character for Sisheng.
1898 */ );
1899   DEFVAR_LISP ("wnn-server-type", &Vwnn_server_type /*
1900 *jserver, cserver ..
1901 */ );
1902   DEFVAR_LISP ("cwnn-zhuyin", &Vcwnn_zhuyin /*
1903 *pinyin or zhuyin
1904 */ );
1905   DEFVAR_LISP ("wnnenv-sticky", &Vwnnenv_sticky /*
1906 *If non-nil, make environment sticky
1907 */ );
1908   DEFVAR_LISP ("wnn-uniq-level", &Vwnn_uniq_level /*
1909 *Uniq level
1910 */ );
1911
1912   Vwnn_server_type = Qjserver;
1913   Vcwnn_zhuyin = Qnil;
1914   Vwnnenv_sticky = Qnil;
1915
1916   Vwnn_uniq_level = Qwnn_uniq;
1917
1918   Fprovide(intern("wnn"));
1919 }
1920
1921 void
1922 w2m (w_char *wp, unsigned char *mp, unsigned char lb)
1923 {
1924   w_char        wc;
1925   w_char        pzy[10];
1926   int           i, len;
1927
1928   while ((wc = *wp++) != 0)
1929     {
1930       switch (wc & 0x8080)
1931         {
1932         case 0x80:
1933           if (EQ(Vwnn_server_type, Qcserver))
1934             {
1935               len = cwnn_yincod_pzy (pzy, wc,
1936                                      NILP (Vcwnn_zhuyin)
1937                                      ? CWNN_PINYIN
1938                                      : CWNN_ZHUYIN);
1939               for (i = 0; i < len; i++)
1940                 {
1941                   if (pzy[i] & 0x80)
1942                     {
1943                       *mp++ = PRE_LEADING_BYTE_PRIVATE_1; /* #### Not sure about this one... */
1944                       *mp++ = lb_sisheng;
1945                     }
1946                   *mp++ = pzy[i];
1947                 }
1948             }
1949           else
1950             {
1951               *mp++ = LEADING_BYTE_KATAKANA_JISX0201;
1952               *mp++ = (wc & 0xff);
1953             }
1954           break;
1955         case 0x8080:
1956           *mp++ = lb;
1957           *mp++ = (wc & 0xff00) >> 8;
1958           *mp++ = wc & 0x00ff;
1959           break;
1960         case 0x8000:
1961           if (lb == LEADING_BYTE_JAPANESE_JISX0208)
1962             *mp++ = LEADING_BYTE_JAPANESE_JISX0212;
1963           else if (lb == LEADING_BYTE_CHINESE_BIG5_1)
1964             *mp++ = LEADING_BYTE_CHINESE_BIG5_2;
1965           else
1966             *mp++ = lb;
1967           *mp++ = (wc & 0xff00) >> 8;
1968           *mp++ = (wc & 0x00ff) | 0x80;
1969           break;
1970         default:
1971           *mp++ = wc & 0x00ff;
1972           break;
1973         }
1974     }
1975   *mp = 0;
1976 }
1977
1978 void
1979 m2w (unsigned char *mp, w_char *wp)
1980 {
1981   unsigned int ch;
1982
1983   while ((ch = *mp++) != 0)
1984     {
1985       if (BUFBYTE_LEADING_BYTE_P (ch))
1986         {
1987           switch (ch)
1988             {
1989             case LEADING_BYTE_KATAKANA_JISX0201:
1990               *wp++ = *mp++; break;
1991             case LEADING_BYTE_LATIN_JISX0201:
1992               *wp++ = *mp++ & 0x7F; break;
1993             case LEADING_BYTE_JAPANESE_JISX0208_1978:
1994             case LEADING_BYTE_CHINESE_GB2312:
1995             case LEADING_BYTE_JAPANESE_JISX0208:
1996             case LEADING_BYTE_KOREAN_KSC5601:
1997               /* case LEADING_BYTE_TW: */
1998               ch = *mp++;
1999               *wp++ = (ch << 8) | *mp++;
2000               break;
2001             case LEADING_BYTE_JAPANESE_JISX0212:
2002               ch = *mp++;
2003               *wp++ = (ch << 8) | (*mp++ & 0x7f);
2004               break;
2005             case PRE_LEADING_BYTE_PRIVATE_1: /* #### Not sure about this one... */
2006               ch = *mp++;
2007               if (ch == lb_sisheng)
2008                 *wp++ = 0x8e80 | *mp++;
2009               else
2010                 mp++;
2011               break;
2012             default:                    /* ignore this character */
2013               mp += REP_BYTES_BY_FIRST_BYTE(ch) - 1;
2014             }
2015         }
2016       else
2017         {
2018           *wp++ = ch;
2019         }
2020     }
2021   *wp = 0;
2022 }
2023
2024 void
2025 w2y (w_char *w)
2026 {
2027   letter                pbuf[5000], ybuf[5000];
2028   unsigned int          *pin;
2029   w_char *y;
2030   int len;
2031
2032   pin = pbuf;
2033   y = w;
2034   while (1)
2035     {
2036       if (*w == 0)
2037         {*pin =0; break;}
2038       else             *pin = *w;
2039       w++; pin++;
2040     }
2041   len = cwnn_pzy_yincod (ybuf, pbuf,
2042                          NILP (Vcwnn_zhuyin) ? CWNN_PINYIN : CWNN_ZHUYIN);
2043   if (len <= 0)
2044     return;
2045
2046   pin = ybuf;
2047   while (1)
2048     {
2049       if (*pin == 0 || len == 0)
2050         {*y = 0;break;}
2051       *y = *pin;
2052       y++; pin++; len--;
2053     }
2054 }
2055
2056 void
2057 c2m (unsigned char *cp, unsigned char *mp, unsigned char lb)
2058 {
2059   unsigned char ch;
2060   while ((ch = *cp) != 0)
2061     {
2062       if (ch & 0x80)
2063         {
2064           *mp++ = lb;
2065           *mp++ = *cp++;
2066         }
2067       *mp++ = *cp++;
2068     }
2069   *mp = 0;
2070 }
2071
2072 static int
2073 dai_end (int no, int server)
2074 {
2075   for (no++; no < jl_bun_suu (wnnfns_buf[server])
2076                && !jl_dai_top (wnnfns_buf[server], no); no++);
2077   return (no);
2078 }
2079
2080 static int
2081 yes_or_no (unsigned char *s)
2082 {
2083   unsigned char         mbuf[512];
2084   unsigned char         lb;
2085   int                   len;
2086   int                   snum;
2087   if ((snum  = check_wnn_server_type ()) == -1) return 0;
2088   lb = lb_wnn_server_type[snum];
2089   /* if no message found, create file without query */
2090   /* if (wnn_msg_cat->msg_bd == 0) return 1;*/
2091   if (*s == 0) return 1;
2092   c2m (s, mbuf, lb);
2093   /* truncate "(Y/N)" */
2094   for (len = 0; (mbuf[len]) && (len < 512); len++);
2095   for (; (mbuf[len] != '(') && (len > 0); len--);
2096   {
2097      Lisp_Object yes, str;
2098      struct gcpro gcpro1;
2099
2100      str = make_string (mbuf, len);
2101      GCPRO1 (str);
2102      yes = call1(Qyes_or_no_p, str);
2103      UNGCPRO;
2104      if (NILP (yes)) return 0;
2105      else return (1);
2106   }
2107 }
2108
2109 static void
2110 puts2 (char *s)
2111 {
2112 #if 0 /* jhod: We don't really need this echoed... */
2113 #if 0
2114   Lisp_Object           args[1];
2115   char                  mbuf[512];
2116   unsigned char         lb;
2117   extern Lisp_Object    Fmessage ();
2118   int                   snum;
2119   if ((snum = check_wnn_server_type ()) == -1) return;
2120   lb = lb_wnn_server_type[snum];
2121   c2m (s, mbuf, lb);
2122   args[0] = make_string (mbuf, strlen (mbuf));
2123   Fmessage (1, args);
2124 #else
2125   message("%s",s);
2126 #endif
2127 #endif
2128 }
2129
2130 int
2131 check_wnn_server_type (void)
2132 {
2133   if (EQ(Vwnn_server_type, Qjserver))
2134     {
2135       return WNNSERVER_J;
2136     }
2137   else if (EQ(Vwnn_server_type, Qcserver))
2138     {
2139       return WNNSERVER_C;
2140     }
2141   /* else if (Vwnn_server_type == Qtserver)
2142      {
2143      return WNNSERVER_T;
2144      } */
2145   else if (EQ(Vwnn_server_type, Qkserver))
2146     {
2147       return WNNSERVER_K;
2148     }
2149   else return -1;
2150 }