(mule_strlen): Fix problem in character-indexing emacsen.
[elisp/emacs-canna.git] / canna.c
1 /* CANNA interface for Emacs/mule and XEmacs/mule.
2
3    Copyright (C) 1995 Free Software Foundation, Inc.
4    Copyright (C) 1996,1997,1999 MORIOKA Tomohiko
5
6    This file is not part of GNU Emacs.
7    
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with GNU Emacs; see the file COPYING.  If not, write to the
20    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21    Boston, MA 02111-1307, USA.
22
23   Authors: Akira Kon (kon@d1.bs2.mt.nec.co.jp)
24            Ichiro Hirakura (hirakura@uxp.bs2.mt.nec.co.jp)
25            modified by MORIOKA Tomohiko <morioka@jaist.ac.jp>
26
27   Functions defined in this file are
28
29   (canna-key-proc key)
30                 key: single STRING
31                 RETURNS:
32                          Length of converted string if no error occurs.
33                          Error string if error occurs.
34                 DESCRIPTION:
35                          Convert a key input to a set of strings.  The
36                          strings contain both well-formed string and a
37                          intermediate result to show the translation
38                          information to a user.  converted strings are
39                          stored in specific variables.
40
41   (canna-initialize)
42                 RETURNS:
43                         List of the following things:
44                         - list of keys to toggle Japanese-mode
45                         - error message
46                         - list of warning messages
47                 DESCRIPTION:
48                         Initialize ``canna'', which is a kana-to-kanji
49                         converter for GNU Emacs.  The first arg
50                         specifies if inserting space character between
51                         BUNSETSU when candidates are displayed.  The
52                         second arg specifies server.  The third arg
53                         specifies a file which will be used as a
54                         customization description.  If nil is
55                         specified for each arg, the default value will
56                         be used.
57
58   (canna-finalize)
59                 RETURNS:
60                         list of warning messages
61                 DESCRIPTION:
62                         finalize ``canna'', which is a kana-to-kanji
63                         converter for GNU Emacs.  This cause to write
64                         miscellaneous informations to kana-to-kanji
65                         dictionary.
66
67   (canna-touroku-string string)
68                 string:
69                         String to register to a dictionary.
70                 RETURNS:
71                         The same thing returns as canna-key-proc does.
72                 DESCRIPTION:
73                         Register Kanji words into kana-to-kanji
74                         conversion dictionary.
75
76   (canna-set-width width)
77                 width:
78                         Column width of the place where the candidates
79                         of kana-to-kanji conversion will be shown.
80                 RETURNS:
81                         nil
82                 DESCRIPTION:
83                         Set status-line width information, which is
84                         used to display kanji candidates.
85
86   (canna-change-mode num)
87                 num:
88                         The mode number of Canna.
89                 RETURNS:
90                         The same thing returns as canna-key-proc does.
91                 DESCRIPTION:
92                         Change Japanese pre-edit mode.
93
94   (canna-store-yomi yomi roma)
95                 yomi:
96                         ``Yomi'' to be stored.
97                 roma:
98                         ``Romaji'' which corresponds to the ``Yomi''.
99                 RETURNS:
100                         The same thing returns as canna-key-proc does.
101                 DESCRIPTION:
102                         Store yomi characters as a YOMI of
103                         kana-to-kanji conversion.
104
105   (canna-do-function num ch)
106                 num:
107                         A function number to be called.
108                 ch:
109                         A character will be specified in order to feed
110                         the character to the function if the function
111                         needs a input character.
112                 RETURNS:
113                         The same thing returns as canna-key-proc does.
114                 DESCRIPTION:
115                         Do specified function at current mode.
116
117   (canna-parse string)
118                 string:
119                         To be parsed.
120                 RETURNS:
121                         List of warning messages.
122                 DESCRIPTION:
123                         Parse customize string.
124
125   (canna-query-mode)
126                 RETURNS:
127                         A string which indicate the current mode.
128                 DESCRIPTION:
129                         Get current mode string.
130
131   Functions below are used for KKCP compatible library.  These
132   functions provides a base kana-to-kanji conversion system for EGG.
133   These functions may be used when users want to change the engine
134   from Wnn to Canna without changing user interface of Japanese input.
135
136   (canna-henkan-begin)
137   (canna-henkan-next)
138   (canna-bunsetu-henkou)
139   (canna-henkan-kakutei)
140   (canna-henkan-end)
141   (canna-henkan-quit)
142
143  */
144
145 #ifndef lint
146 static char rcs_id[] = "$Id: canna.c,v 1.37 2000-02-01 02:36:25 tomo Exp $";
147 #endif
148
149 #include <stdio.h>
150
151 #include "config.h"
152 #include "lisp.h"
153 #include "buffer.h"
154 #ifndef CANNA_NEMACS
155 #include "charset.h"
156 #endif
157 #ifdef CANNA_EMACS
158 #include "coding.h"
159 #endif
160
161 #ifdef CANNA_EMACS
162 #define CHARSET_KATAKANA_JISX0201 137
163 #define CHARSET_JAPANESE_JISX0208 146
164 #define CHARSET_JAPANESE_JISX0212 148
165 #else
166 #ifdef CANNA_MULE
167 #define CHARSET_KATAKANA_JISX0201 LCKANA
168 #define CHARSET_JAPANESE_JISX0208 LCJP
169 #define CHARSET_JAPANESE_JISX0212 LCJP2
170 #define ISO_CODE_SS2 SS2
171 #define ISO_CODE_SS3 SS3
172 #endif /* CANNA_MULE */
173 #endif
174
175 #define IROHA_BC
176 #include "canna/jrkanji.h"
177 #include "canna/RK.h"
178
179 extern char *jrKanjiError;
180
181 #define KEYTOSTRSIZE 2048
182 static unsigned char buf[KEYTOSTRSIZE];
183 static char **warning;
184
185 static int Vcanna_empty_info, Vcanna_through_info;
186 static int Vcanna_underline;
187 static int Vcanna_inhibit_hankakukana;          /* hir, 1994.12.5 */
188
189 #ifndef CANNA_EMACS_DL
190 static Lisp_Object Vcanna_kakutei_string;
191 static Lisp_Object Vcanna_kakutei_yomi;
192 static Lisp_Object Vcanna_kakutei_romaji;
193 static Lisp_Object Vcanna_henkan_string;
194 #endif
195 static int         Vcanna_henkan_length;
196 static int         Vcanna_henkan_revPos;
197 static int         Vcanna_henkan_revLen;
198 #ifndef CANNA_EMACS_DL
199 static Lisp_Object Vcanna_ichiran_string;
200 #endif
201 static int         Vcanna_ichiran_length;
202 static int         Vcanna_ichiran_revPos;
203 static int         Vcanna_ichiran_revLen;
204 #ifndef CANNA_EMACS_DL
205 static Lisp_Object Vcanna_mode_string;
206 #endif
207
208 static int IRCP_context;
209
210 #if __STDC__
211 static Lisp_Object storeResults(unsigned char *, int, jrKanjiStatus *);
212 static Lisp_Object kanjiYomiList(int, int);
213 #else
214 static Lisp_Object storeResults();
215 static Lisp_Object kanjiYomiList();
216 #endif
217
218 #ifndef CANNA_NEMACS
219 #if __STDC__
220 static m2c(unsigned char *, int, unsigned char *);
221 static Lisp_Object mule_make_string(unsigned char *, int);
222 static mule_strlen(unsigned char *, int);
223 static count_char(unsigned char *,int, int, int, int *, int *, int *);
224 #else
225 static m2c();
226 static Lisp_Object mule_make_string();
227 static mule_strlen();
228 static count_char();
229 #endif
230 #define make_string mule_make_string
231 #endif
232
233 /* Lisp functions definition */
234
235 DEFUN ("canna-key-proc", Fcanna_key_proc, Scanna_key_proc,
236        1, 1, 0,
237 "Translate a key input to a set of strings.  The strings contain both\n\
238 well-formed string and intermediate result to show the translation\n\
239 information to a user.  Converted strings are stored in specific\n\
240 variables.")
241         (ch)
242 Lisp_Object ch;
243 {
244   jrKanjiStatus ks;
245   int len;
246
247   CHECK_NUMBER (ch, 0);
248   len = jrKanjiString(0, XINT (ch), buf, KEYTOSTRSIZE, &ks);
249   return storeResults(buf, len, &ks);
250 }
251
252 static
253 Lisp_Object
254 storeResults(buf, len, ks)
255 unsigned char *buf;
256 int len;
257 jrKanjiStatus *ks;
258 {
259   Lisp_Object val = Qnil;
260
261   if (len < 0) { /* Error detected */
262     val = make_string((unsigned char*)jrKanjiError, strlen(jrKanjiError));
263   }
264   else {
265     /* ³ÎÄꤷ¤¿Ê¸»úÎó */
266 #ifndef CANNA_EMACS_DL
267     Vcanna_kakutei_string = make_string(buf, len);
268 #else /* CANNA_EMACS_DL */
269     Fset(intern("canna-kakutei-string"), make_string(buf, len));
270 #endif
271     val = make_number(len);
272     /* ³ÎÄꤷ¤¿Ê¸»úÎó¤ÎÆɤߤξðÊó... */
273 #ifndef CANNA_EMACS_DL
274     Vcanna_kakutei_yomi = Vcanna_kakutei_romaji = Qnil;
275 #else /* CANNA_EMACS_DL */
276     Fset(intern("canna-kakutei-yomi"), Qnil);
277     Fset(intern("canna-kakutei-romaji"), Qnil);
278 #endif
279     if (ks->info & KanjiYomiInfo) {
280       unsigned char *p = buf + len + 1;
281       int yomilen = strlen(p);
282
283       if (len + yomilen + 1 < KEYTOSTRSIZE) {
284         int yomilen2;
285
286 #ifndef CANNA_EMACS_DL
287         Vcanna_kakutei_yomi = make_string(p, yomilen); /* Æɤߠ*/
288 #else /* CANNA_EMACS_DL */
289         Fset(intern("canna-kakutei-yomi"), make_string(p, yomilen));
290 #endif
291         p += yomilen + 1;
292         yomilen2 = strlen(p);
293         if (len + yomilen + yomilen2 + 2 < KEYTOSTRSIZE) {
294 #ifndef CANNA_EMACS_DL
295           Vcanna_kakutei_romaji = make_string(p, yomilen2); /* ¥í¡¼¥Þ»ú */
296 #else /* CANNA_EMACS_DL */
297           Fset(intern("canna-kakutei-romaji"), make_string(p, yomilen2));
298 #endif
299         }
300       }
301     }
302
303
304     /* ¸õÊäɽ¼¨¤Îʸ»úÎó¤Ç¤¹¡£*/
305 #ifndef CANNA_EMACS_DL
306     Vcanna_henkan_string = Qnil;
307 #else /* CANNA_EMACS_DL */
308     Fset(intern("canna-henkan-string"), Qnil);
309 #endif
310     if (ks->length >= 0) {
311 #ifndef CANNA_EMACS_DL
312       Vcanna_henkan_string = make_string(ks->echoStr, ks->length);
313 #else /* CANNA_EMACS_DL */
314       Fset(intern("canna-henkan-string"),
315            make_string(ks->echoStr, ks->length));
316 #endif
317 #ifdef CANNA_NEMACS
318       Vcanna_henkan_length = ks->length;
319       Vcanna_henkan_revPos = ks->revPos;
320       Vcanna_henkan_revLen = ks->revLen;
321 #else /* CANNA_MULE */
322       if (Vcanna_underline) {
323         Vcanna_henkan_length = mule_strlen(ks->echoStr,ks->length);
324         Vcanna_henkan_revPos = mule_strlen(ks->echoStr,ks->revPos);
325         Vcanna_henkan_revLen = mule_strlen(ks->echoStr+ks->revPos,ks->revLen);
326       }
327       else {
328         count_char(ks->echoStr, ks->length, ks->revPos, ks->revLen,
329                    &Vcanna_henkan_length, &Vcanna_henkan_revPos,
330                    &Vcanna_henkan_revLen);
331       }
332 #endif /* CANNA_MULE */
333     }
334
335     /* °ìÍ÷¤Î¾ðÊó */
336 #ifndef CANNA_EMACS_DL
337     Vcanna_ichiran_string = Qnil;
338 #else /* CANNA_EMACS_DL */
339     Fset(intern("canna-ichiran-string"), Qnil);
340 #endif
341     if (ks->info & KanjiGLineInfo && ks->gline.length >= 0) {
342 #ifndef CANNA_EMACS_DL
343       Vcanna_ichiran_string = make_string(ks->gline.line, ks->gline.length);
344 #else /* CANNA_EMACS_DL */
345       Fset(intern("canna-ichiran-string"),
346            make_string(ks->gline.line, ks->gline.length));
347 #endif
348 #ifdef CANNA_NEMACS
349       Vcanna_ichiran_length = ks->gline.length;
350       Vcanna_ichiran_revPos = ks->gline.revPos;
351       Vcanna_ichiran_revLen = ks->gline.revLen;
352 #else /* CANNA_MULE */
353       count_char(ks->gline.line, ks->gline.length,
354                  ks->gline.revPos, ks->gline.revLen, &Vcanna_ichiran_length,
355                  &Vcanna_ichiran_revPos, &Vcanna_ichiran_revLen);
356 #endif /* CANNA_MULE */
357     }
358
359     /* ¥â¡¼¥É¤Î¾ðÊó */
360 #ifndef CANNA_EMACS_DL
361     Vcanna_mode_string = Qnil;
362 #else /* CANNA_EMACS_DL */
363     Fset(intern("canna-mode-string"), Qnil);
364 #endif
365     if (ks->info & KanjiModeInfo) {
366 #ifndef CANNA_EMACS_DL
367       Vcanna_mode_string = make_string(ks->mode, strlen(ks->mode));
368 #else /* CANNA_EMACS_DL */
369       Fset(intern("canna-mode-string"),
370            make_string(ks->mode, strlen(ks->mode)));
371 #endif
372     }
373
374     /* ¤½¤Î¾¤Î¾ðÊó */
375     Vcanna_empty_info = (ks->info & KanjiEmptyInfo) ? 1 : 0;
376     Vcanna_through_info = (ks->info & KanjiThroughInfo) ? 1 : 0;
377   }
378
379   return val;
380 }
381
382 DEFUN ("canna-set-bunsetsu-kugiri", Fcanna_set_bunsetsu, Scanna_set_bunsetsu,
383        0, 1, 0,
384 "This function sets the clause separator.\n\
385 If non-nil value is specified, the white space separator will be used.\n\
386 No separator will be used otherwise.")
387      (num)
388      Lisp_Object num;
389 {
390   int kugiri; /* Ê¸Àá¶èÀÚ¤ê¤ò¤¹¤ë¤«¡© */
391
392   kugiri = NILP(num) ? 0 : 1;
393
394   jrKanjiControl(0, KC_SETBUNSETSUKUGIRI, (char *)kugiri);
395
396   return Qnil;
397 }
398
399 DEFUN ("canna-initialize", Fcanna_initialize, Scanna_initialize, 0, 3, 0,
400 "Initialize ``canna'', which is a kana-to-kanji converter for GNU Emacs.\n\
401 The first arg specifies if inserting space character between BUNSETSU when\n\
402 candidates are displayed.\n\
403 The second arg specifies server.\n\
404 The third arg specifies a file which will be used as a customization\n\
405 description.\n\
406 If nil is specified for each arg, the default value will be used.")
407 (num, server, rcfile)
408 Lisp_Object num, server, rcfile;
409 {
410   Lisp_Object val;
411   int res;
412   unsigned char **p, **q;
413
414   int kugiri; /* Ê¸Àá¶èÀÚ¤ê¤ò¤¹¤ë¤«¡© */
415
416   IRCP_context = -1;
417
418   if (NILP(num)) {
419     kugiri = 1;
420   }
421   else {
422     CHECK_NUMBER(num, 0);
423     kugiri = XINT(num);
424     kugiri = (kugiri == 1) ? 1 : 0;
425   }
426
427   if (NILP(server)) {
428     jrKanjiControl(0, KC_SETSERVERNAME, (char *)0);
429   }
430   else {
431     char servername[256];
432
433     CHECK_STRING(server, 0);
434     strncpy(servername, XSTRING(server)->data, XSTRING(server)->size);
435     servername[XSTRING(server)->size] = '\0';
436     jrKanjiControl(0, KC_SETSERVERNAME, servername);
437   }
438
439   if (NILP(rcfile)) {
440     jrKanjiControl(0, KC_SETINITFILENAME, (char *)0);
441   }
442   else {
443     char rcname[256];
444
445     CHECK_STRING(rcfile, 0);
446     strncpy(rcname, XSTRING(rcfile)->data, XSTRING(rcfile)->size);
447     rcname[XSTRING(rcfile)->size] = '\0';
448     jrKanjiControl(0, KC_SETINITFILENAME, rcname);
449   }
450
451   warning = (char **)0;
452 #ifdef nec_ews_svr4                             /* hir, 1994.2.24 */
453   stop_polling ();
454 #endif /* nec_ews_svr4 */
455   res = jrKanjiControl(0, KC_INITIALIZE, (char *)&warning);
456 #ifdef nec_ews_svr4                             /* hir, 1994.2.24 */
457   start_polling ();
458 #endif /* nec_ews_svr4 */
459   val = Qnil;
460   if (warning) {
461     for (p = q = (unsigned char **)warning ; *q ; q++)
462       ;
463     while (p < q) {
464       q--;
465       val = Fcons(make_string(*q, strlen(*q)), val);
466     }
467   }
468   val = Fcons(val, Qnil);
469
470   if (res == -1) {
471     val = Fcons(make_string((unsigned char*)jrKanjiError, 
472                             strlen(jrKanjiError)), val);
473     /* ¥¤¥Ë¥·¥ã¥é¥¤¥º¤Ç¼ºÇÔ¤·¤¿¾ì¹ç¡£ */
474     return Fcons(Qnil, val);
475   }
476   else {
477     extern (*jrBeepFunc)();
478     Lisp_Object Fding(), CANNA_mode_keys();
479
480     jrBeepFunc = Fding;
481
482 #ifdef KC_SETAPPNAME
483 #ifdef CANNA_NEMACS
484     wcKanjiControl(0, KC_SETAPPNAME, "nemacs");
485 #else /* CANNA_MULE */
486     wcKanjiControl(0, KC_SETAPPNAME, "mule");
487 #endif /* CANNA_MULE */
488 #endif /* KC_SETAPPNAME */
489
490     jrKanjiControl(0, KC_SETBUNSETSUKUGIRI, (char *)kugiri);
491     jrKanjiControl(0, KC_SETWIDTH, (char *)78);
492 #ifdef CANNA_NEMACS
493     jrKanjiControl(0, KC_INHIBITHANKAKUKANA, (char *)1);
494 #else                                   /* hir, 1994.12.5 */
495     /* mule ¤À¤Ã¤¿¤éȾ³Ñ¥«¥¿¥«¥Ê¤â»È¤¨¤ë */
496     if (Vcanna_inhibit_hankakukana)
497       jrKanjiControl(0, KC_INHIBITHANKAKUKANA, (char *)1);
498 #endif
499     jrKanjiControl(0, KC_YOMIINFO, (char *)2); /* ¢¨£²: ¥í¡¼¥Þ»ú¤Þ¤ÇÊÖ¤¹ */
500     val = Fcons(Qnil, val);
501     return Fcons(CANNA_mode_keys(), val);
502   }
503 }
504
505 DEFUN ("canna-finalize", Fcanna_finalize, Scanna_finalize, 0, 0, 0,
506 "finalize ``canna'', which is a kana-to-kanji converter for GNU Emacs.\n\
507 This cause to write miscellaneous informations to kana-to-kanji dictionary.")
508 ()
509 {
510   Lisp_Object val;
511   unsigned char **p;
512
513   jrKanjiControl(0, KC_FINALIZE, (char *)&warning);
514
515   val = Qnil;
516   if (warning) {
517     for (p = (unsigned char**)warning ; *p ; p++) {
518       val = Fcons(make_string(*p, strlen(*p)), val);
519     }
520   }
521   val = Fcons(val, Qnil);
522   IRCP_context = -1;
523   return val;
524 }
525
526 DEFUN ("canna-touroku-string", Fcanna_touroku_string, 
527        Scanna_touroku_string, 1, 1, 0,
528 "Register Kanji words into kana-to-kanji conversion dictionary.")
529         (str)
530 Lisp_Object str;
531 {
532   jrKanjiStatusWithValue ksv;
533   jrKanjiStatus ks;
534   int len;
535   Lisp_Object val;
536 #ifndef CANNA_NEMACS
537   unsigned char cbuf[4096];
538 #endif
539
540   CHECK_STRING(str, 0);
541   ksv.buffer = (unsigned char *)buf;
542   ksv.bytes_buffer = KEYTOSTRSIZE;
543 #ifdef CANNA_NEMACS
544   ks.echoStr = XSTRING (str)->data;
545   ks.length = XSTRING (str)->size;
546 #else /* CANNA_MULE */
547 #ifdef STRING_BYTES
548   m2c(XSTRING (str)->data, STRING_BYTES (XSTRING (str)), cbuf);
549 #else /* for byte indexing emacsen (Emacs 20.2) */
550   m2c(XSTRING (str)->data, XSTRING (str)->size, cbuf);
551 #endif /* STRING_BYTES */
552   ks.echoStr = cbuf;
553   ks.length = strlen(cbuf);
554 #endif /* CANNA_MULE */
555   ksv.ks = &ks;
556   len = jrKanjiControl(0, KC_DEFINEKANJI, (char *)&ksv);
557   val = storeResults(buf, ksv.val, ksv.ks);
558   return val;
559 }
560
561 DEFUN ("canna-set-width", Fcanna_set_width,
562        Scanna_set_width, 1, 1, 0,
563 "Set status-line width information, which is used to display \n\
564 kanji candidates.")
565         (num)
566 Lisp_Object num;
567 {
568   CHECK_NUMBER(num, 0);
569
570   jrKanjiControl(0, KC_SETWIDTH,  (char *)XINT (num));
571   return Qnil;
572 }
573
574 DEFUN ("canna-change-mode", Fcanna_change_mode,
575        Scanna_change_mode, 1, 1, 0,
576 "Change Japanese pre-edit mode.")
577         (num)
578 Lisp_Object num;
579 {
580   jrKanjiStatusWithValue ksv;
581   jrKanjiStatus ks;
582   Lisp_Object val;
583
584   CHECK_NUMBER(num, 0);
585
586   ksv.buffer = (unsigned char *)buf;
587   ksv.bytes_buffer = KEYTOSTRSIZE;
588   ksv.ks = &ks;
589   ksv.val = XINT (num);
590   jrKanjiControl(0, KC_CHANGEMODE,  (char *)&ksv);
591   val = storeResults(buf, ksv.val, ksv.ks);
592   return val;
593 }
594
595 Lisp_Object
596 CANNA_mode_keys()
597 {
598 #define CANNAWORKBUFSIZE 32
599   char xxx[CANNAWORKBUFSIZE];
600   Lisp_Object val;
601   int i, n;
602
603   n = jrKanjiControl(0, KC_MODEKEYS, xxx);
604   val = Qnil;
605   for (i = n ; i > 0 ;) {
606     --i;
607     val = Fcons(make_number((int)(0xFF & (unsigned char)xxx[i])), val);
608   }
609   return val;
610 }
611
612 DEFUN ("canna-store-yomi", Fcanna_store_yomi, Scanna_store_yomi, 
613        1, 2, 0,
614 "Store yomi characters as a YOMI of kana-to-kanji conversion.")
615         (yomi, roma)
616 Lisp_Object yomi, roma;
617 {
618   jrKanjiStatusWithValue ksv;
619   jrKanjiStatus ks;
620
621   CHECK_STRING(yomi, 0);
622 #ifdef CANNA_NEMACS
623   strncpy(buf, XSTRING(yomi)->data, XSTRING(yomi)->size);
624   ks.length = XSTRING (yomi)->size;
625   buf[ks.length] = '\0';
626 #else /* CANNA_MULE */
627 #ifdef STRING_BYTES
628   m2c(XSTRING(yomi)->data, STRING_BYTES (XSTRING(yomi)), buf);
629 #else /* for byte indexing emacsen (Emacs 20.2) */
630   m2c(XSTRING(yomi)->data, XSTRING(yomi)->size, buf);
631 #endif /* STRING_BYTES */
632   ks.length = strlen(buf);
633 #endif /* CANNA_MULE */
634
635   if (NILP(roma)) {
636     ks.mode = 0;
637   }
638   else {
639     CHECK_STRING(roma, 0);
640
641 #ifdef CANNA_NEMACS
642     strncpy(buf + XSTRING(yomi)->size + 1, XSTRING(roma)->data,
643             XSTRING(roma)->size);
644     buf[XSTRING(yomi)->size + 1 + XSTRING(roma)->size] = '\0';
645     ks.mode = (unsigned char *)(buf + XSTRING(yomi)->size + 1);
646 #else /* CANNA_MULE */
647     ks.mode = (unsigned char *)(buf + ks.length + 1);
648 #ifdef STRING_BYTES
649     m2c(XSTRING(roma)->data, STRING_BYTES (XSTRING(roma)), ks.mode);
650 #else /* for byte indexing emacsen (Emacs 20.2) */
651     m2c(XSTRING(roma)->data, XSTRING(roma)->size, ks.mode);
652 #endif /* STRING_BYTES */
653 #endif /* CANNA_MULE */
654   }
655
656   ks.echoStr = (unsigned char *)buf;
657   ksv.buffer = (unsigned char *)buf; /* ÊÖÃÍÍÑ */
658   ksv.bytes_buffer = KEYTOSTRSIZE;
659   ksv.ks = &ks;
660
661   jrKanjiControl(0, KC_STOREYOMI, (char *)&ksv);
662
663   return storeResults(buf, ksv.val, ksv.ks);
664 }
665
666 DEFUN ("canna-do-function", Fcanna_do_function, Scanna_do_function, 
667        1, 2, 0,
668 "Do specified function at current mode.")
669         (num, ch)
670 Lisp_Object num, ch;
671 {
672   jrKanjiStatusWithValue ksv;
673   jrKanjiStatus ks;
674   Lisp_Object val;
675
676   CHECK_NUMBER(num, 0);
677
678   if (NILP(ch)) {
679     *buf = '@';
680   }
681   else {
682     CHECK_NUMBER(ch, 0);
683     *buf = XINT (ch);
684   }
685
686   ksv.buffer = (unsigned char *)buf;
687   ksv.bytes_buffer = KEYTOSTRSIZE;
688   ksv.ks = &ks;
689   ksv.val = XINT (num);
690   jrKanjiControl(0, KC_DO,  (char *)&ksv);
691   val = storeResults(buf, ksv.val, ksv.ks);
692   return val;
693 }
694
695 DEFUN ("canna-parse", Fcanna_parse, Scanna_parse, 
696        1, 1, 0,
697 "Parse customize string.")
698         (str)
699 Lisp_Object str;
700 {
701   jrKanjiStatusWithValue ksv;
702   jrKanjiStatus ks;
703   Lisp_Object val;
704   unsigned char **p;
705   int n;
706
707   CHECK_STRING(str, 0);
708
709 #ifdef CANNA_NEMACS
710   strncpy(buf, XSTRING(str)->data, XSTRING(str)->size);
711   buf[XSTRING(str)->size] = '\0';
712 #else /* CANNA_MULE */
713 #ifdef STRING_BYTES
714   m2c(XSTRING(str)->data, STRING_BYTES (XSTRING(str)), buf);
715 #else /* for byte indexing emacsen (Emacs 20.2) */
716   m2c(XSTRING(str)->data, XSTRING(str)->size, buf);
717 #endif /* STRING_BYTES */
718 #endif /* CANNA_MULE */
719   p = (unsigned char**)buf;
720   n = jrKanjiControl(0, KC_PARSE,  (char *)&p);
721   val = Qnil;
722   while (n > 0) {
723     n--;
724     val = Fcons(make_string(p[n], strlen(p[n])), val);
725   }
726   return val;
727 }
728
729 DEFUN ("canna-query-mode", Fcanna_query_mode, Scanna_query_mode, 
730        0, 0, 0,
731 "Get current mode string.")
732         ()
733 {
734   unsigned char buf[256];
735
736   jrKanjiControl(0, KC_QUERYMODE, buf);
737   return make_string(buf, strlen(buf));
738 }
739
740 /*
741  * Functions following this line are for KKCP interface compatible
742  * library.  These functions may be used by MILK system.
743  */
744
745 #define RKBUFSIZE 1024
746
747 static unsigned char yomibuf[RKBUFSIZE];
748 static short kugiri[RKBUFSIZE / 2];
749
750 static confirmContext()
751 {
752   if (IRCP_context < 0) {
753     int context;
754
755     if ((context = jrKanjiControl(0, KC_GETCONTEXT, (char *)0)) == -1) {
756       return 0;
757     }
758     IRCP_context = context;
759   }
760   return 1;
761 }
762
763 static byteLen(bun, len)
764 int bun, len;
765 {
766   int i = 0, offset = 0, ch;
767
768   if (0 <= bun && bun < RKBUFSIZE) {
769     offset = kugiri[bun];
770   }
771
772   while (len-- > 0 && (ch = (int)yomibuf[offset + i])) {
773     i++;
774     if (ch & 0x80) {
775       i++;
776     }
777   }
778   return i;
779 }
780
781 DEFUN ("canna-henkan-begin", Fcanna_henkan_begin, Scanna_henkan_begin,
782        1, 1, 0,
783 "¤«¤Ê´Á»úÊÑ´¹¤·¤¿·ë²Ì¤òÊÖ´Ô¤¹¤ë¡£Ê¸ÀáÀڤ꤬¤·¤Æ¤¢¤ë¡£")
784         (yomi)
785     Lisp_Object yomi;
786 {
787   int nbun;
788   Lisp_Object res;
789
790   CHECK_STRING(yomi, 0);
791   if (confirmContext() == 0) {
792     return Qnil;
793   }
794 #ifdef CANNA_NEMACS
795   strncpy(yomibuf, XSTRING(yomi)->data, XSTRING(yomi)->size);
796   yomibuf[XSTRING(yomi)->size] = '\0';
797   nbun = RkBgnBun(IRCP_context, XSTRING(yomi)->data, XSTRING(yomi)->size,
798                   (RK_XFER << RK_XFERBITS) | RK_KFER);
799 #else /* CANNA_MULE */
800 #ifdef STRING_BYTES
801   m2c(XSTRING(yomi)->data, STRING_BYTES (XSTRING(yomi)), yomibuf);
802 #else /* for byte indexing emacsen (Emacs 20.2) */
803   m2c(XSTRING(yomi)->data, XSTRING(yomi)->size, yomibuf);
804 #endif /* STRING_BYTES */
805   nbun = RkBgnBun(IRCP_context, (char *)yomibuf, strlen(yomibuf),
806                   (RK_XFER << RK_XFERBITS) | RK_KFER);
807 #endif /* CANNA_MULE */
808
809   return kanjiYomiList(IRCP_context, nbun);
810 }
811
812 static Lisp_Object kanjiYomiList(context, nbun)
813 int context, nbun;
814 {
815   Lisp_Object val, res = Qnil;
816   unsigned char RkBuf[RKBUFSIZE];
817   int len, i, total;
818
819   for (i = nbun ; i > 0 ; ) {
820     i--;
821     RkGoTo(context, i);
822     len = RkGetKanji(context, RkBuf, RKBUFSIZE);
823     val = make_string(RkBuf, len);
824     len = RkGetYomi(context, RkBuf, RKBUFSIZE);
825     res = Fcons(Fcons(val, make_string(RkBuf, len)), res);
826     if (i < RKBUFSIZE / 2) {
827       kugiri[i] = len;
828     }
829   }
830   for (i = 0, total = 0 ; i < nbun ; i++) {
831     int temp = kugiri[i];
832     kugiri[i] = total;
833     total += temp;
834   }
835   return res;
836 }
837
838 DEFUN ("canna-henkan-next", Fcanna_henkan_next, Scanna_henkan_next,
839        1, 1, 0,
840 "¸õÊä°ìÍ÷¤òµá¤á¤ë¡£")
841         (bunsetsu)
842     Lisp_Object bunsetsu;
843 {
844   int i, nbun, slen, len;
845   unsigned char *p, RkBuf[RKBUFSIZE];
846   Lisp_Object res = Qnil, endp;
847
848   CHECK_NUMBER(bunsetsu, 0);
849   if (confirmContext() == 0) {
850     return Qnil;
851   }
852   RkGoTo(IRCP_context, XINT (bunsetsu));
853   len = RkGetKanjiList(IRCP_context, RkBuf, RKBUFSIZE);
854   p = RkBuf;
855   for (i = 0 ; i < len ; i++) {
856     slen = strlen(p);
857     if (res == Qnil) {
858       endp = res = Fcons(make_string(p, slen), Qnil);
859     }
860     else {
861       endp = XCONS (endp)->cdr = Fcons(make_string(p, slen), Qnil);
862     }
863     p += slen + 1;
864   }
865   return res;
866 }
867
868 DEFUN ("canna-bunsetu-henkou", Fcanna_bunsetu_henkou, Scanna_bunsetu_henkou,
869        2, 2, 0,
870 "ʸÀá¤ÎŤµ¤ò»ØÄꤹ¤ë¡£")
871         (bunsetsu, bunlen)
872     Lisp_Object bunsetsu, bunlen;
873 {
874   int nbun, len;
875
876   CHECK_NUMBER(bunsetsu, 0);
877   CHECK_NUMBER(bunlen, 0);
878   
879   nbun = XINT (bunsetsu);
880   if (confirmContext() == 0) {
881     return Qnil;
882   }
883   RkGoTo(IRCP_context, nbun);
884   len = byteLen(nbun, XINT(bunlen));
885   return kanjiYomiList(IRCP_context, RkResize(IRCP_context, len));
886 }
887
888 DEFUN ("canna-henkan-kakutei", Fcanna_henkan_kakutei, Scanna_henkan_kakutei,
889        2, 2, 0,
890 "¸õÊäÁªÂò¡£")
891         (bun, kouho)
892 register Lisp_Object bun, kouho;
893 {
894   if (confirmContext() == 0) {
895     return Qnil;
896   }
897   RkGoTo(IRCP_context, bun);
898   RkXfer(IRCP_context, kouho);
899   return Qt;
900 }
901
902 DEFUN ("canna-henkan-end", Fcanna_henkan_end, Scanna_henkan_end,
903        0, 0, 0,
904 "ÊÑ´¹½ªÎ»¡£")
905         ()
906 {
907   if (confirmContext() == 0) {
908     return Qnil;
909   }
910   RkEndBun(IRCP_context, 1); /* ³Ø½¬¤Ï¤¤¤Ä¤Ç¤â¹Ô¤Ã¤ÆÎɤ¤¤â¤Î¤Ê¤Î¤«¡© */
911   return Qt;
912 }
913
914 DEFUN ("canna-henkan-quit", Fcanna_henkan_quit, Scanna_henkan_quit,
915        0, 0, 0,
916 "ÊÑ´¹½ªÎ»¡£")
917         ()
918 {
919   if (confirmContext() == 0) {
920     return Qnil;
921   }
922   RkEndBun(IRCP_context, 0);
923   return Qt;
924 }
925
926 /* variables below this line is constants of Canna */
927
928 static int Vcanna_mode_AlphaMode = IROHA_MODE_AlphaMode;
929 static int Vcanna_mode_EmptyMode = IROHA_MODE_EmptyMode;
930 static int Vcanna_mode_KigoMode = IROHA_MODE_KigoMode;
931 static int Vcanna_mode_YomiMode = IROHA_MODE_YomiMode;
932 static int Vcanna_mode_JishuMode = IROHA_MODE_JishuMode;
933 static int Vcanna_mode_TankouhoMode = IROHA_MODE_TankouhoMode;
934 static int Vcanna_mode_IchiranMode = IROHA_MODE_IchiranMode;
935 static int Vcanna_mode_YesNoMode = IROHA_MODE_YesNoMode;
936 static int Vcanna_mode_OnOffMode = IROHA_MODE_OnOffMode;
937 #ifdef CANNA_MODE_AdjustBunsetsuMode
938 static int Vcanna_mode_AdjustBunsetsuMode = CANNA_MODE_AdjustBunsetsuMode;
939 #endif
940 #ifdef CANNA_MODE_ChikujiYomiMode
941 static int Vcanna_mode_ChikujiYomiMode = CANNA_MODE_ChikujiYomiMode;
942 static int Vcanna_mode_ChikujiTanMode = CANNA_MODE_ChikujiTanMode;
943 #endif
944
945 static int Vcanna_mode_HenkanMode = IROHA_MODE_HenkanMode;
946 #ifdef CANNA_MODE_HenkanNyuryokuMode
947 static int Vcanna_mode_HenkanNyuryokuMode = CANNA_MODE_HenkanNyuryokuMode;
948 #endif
949 #ifdef CANNA_MODE_ZenHiraHenkanMode
950 static int Vcanna_mode_ZenHiraHenkanMode = CANNA_MODE_ZenHiraHenkanMode;
951 #ifdef CANNA_MODE_HanHiraHenkanMode
952 static int Vcanna_mode_HanHiraHenkanMode = CANNA_MODE_HanHiraHenkanMode;
953 #endif
954 static int Vcanna_mode_ZenKataHenkanMode = CANNA_MODE_ZenKataHenkanMode;
955 static int Vcanna_mode_HanKataHenkanMode = CANNA_MODE_HanKataHenkanMode;
956 static int Vcanna_mode_ZenAlphaHenkanMode = CANNA_MODE_ZenAlphaHenkanMode;
957 static int Vcanna_mode_HanAlphaHenkanMode = CANNA_MODE_HanAlphaHenkanMode;
958 #endif
959 static int Vcanna_mode_ZenHiraKakuteiMode = IROHA_MODE_ZenHiraKakuteiMode;
960 #ifdef CANNA_MODE_HanHiraKakuteiMode
961 static int Vcanna_mode_HanHiraKakuteiMode = CANNA_MODE_HanHiraKakuteiMode;
962 #endif
963 static int Vcanna_mode_ZenKataKakuteiMode = IROHA_MODE_ZenKataKakuteiMode;
964 static int Vcanna_mode_HanKataKakuteiMode = IROHA_MODE_HanKataKakuteiMode;
965 static int Vcanna_mode_ZenAlphaKakuteiMode = IROHA_MODE_ZenAlphaKakuteiMode;
966 static int Vcanna_mode_HanAlphaKakuteiMode = IROHA_MODE_HanAlphaKakuteiMode;
967 static int Vcanna_mode_HexMode = IROHA_MODE_HexMode;
968 static int Vcanna_mode_BushuMode = IROHA_MODE_BushuMode;
969 static int Vcanna_mode_ExtendMode = IROHA_MODE_ExtendMode;
970 static int Vcanna_mode_RussianMode = IROHA_MODE_RussianMode;
971 static int Vcanna_mode_GreekMode = IROHA_MODE_GreekMode;
972 static int Vcanna_mode_LineMode = IROHA_MODE_LineMode;
973 static int Vcanna_mode_ChangingServerMode = IROHA_MODE_ChangingServerMode;
974 static int Vcanna_mode_HenkanMethodMode = IROHA_MODE_HenkanMethodMode;
975 static int Vcanna_mode_DeleteDicMode = IROHA_MODE_DeleteDicMode;
976 static int Vcanna_mode_TourokuMode = IROHA_MODE_TourokuMode;
977 static int Vcanna_mode_TourokuEmptyMode = IROHA_MODE_TourokuEmptyMode;
978 static int Vcanna_mode_TourokuHinshiMode = IROHA_MODE_TourokuHinshiMode;
979 static int Vcanna_mode_TourokuDicMode = IROHA_MODE_TourokuDicMode;
980 static int Vcanna_mode_QuotedInsertMode = IROHA_MODE_QuotedInsertMode;
981 static int Vcanna_mode_BubunMuhenkanMode = IROHA_MODE_BubunMuhenkanMode;
982 static int Vcanna_mode_MountDicMode = IROHA_MODE_MountDicMode;
983
984 static int Vcanna_fn_SelfInsert = IROHA_FN_SelfInsert;
985 static int Vcanna_fn_FunctionalInsert = IROHA_FN_FunctionalInsert;
986 static int Vcanna_fn_QuotedInsert = IROHA_FN_QuotedInsert;
987 static int Vcanna_fn_JapaneseMode = IROHA_FN_JapaneseMode;
988 static int Vcanna_fn_AlphaMode = IROHA_FN_AlphaMode;
989 static int Vcanna_fn_HenkanNyuryokuMode = IROHA_FN_HenkanNyuryokuMode;
990 static int Vcanna_fn_Forward = IROHA_FN_Forward;
991 static int Vcanna_fn_Backward = IROHA_FN_Backward;
992 static int Vcanna_fn_Next = IROHA_FN_Next;
993 static int Vcanna_fn_Prev = IROHA_FN_Prev;
994 static int Vcanna_fn_BeginningOfLine = IROHA_FN_BeginningOfLine;
995 static int Vcanna_fn_EndOfLine = IROHA_FN_EndOfLine;
996 static int Vcanna_fn_DeleteNext = IROHA_FN_DeleteNext;
997 static int Vcanna_fn_DeletePrevious = IROHA_FN_DeletePrevious;
998 static int Vcanna_fn_KillToEndOfLine = IROHA_FN_KillToEndOfLine;
999 static int Vcanna_fn_Henkan = IROHA_FN_Henkan;
1000 static int Vcanna_fn_Kakutei = IROHA_FN_Kakutei;
1001 static int Vcanna_fn_Extend = IROHA_FN_Extend;
1002 static int Vcanna_fn_Shrink = IROHA_FN_Shrink;
1003 #ifdef CANNA_FN_AdjustBunsetsu
1004 static int Vcanna_fn_AdjustBunsetsu = CANNA_FN_AdjustBunsetsu;
1005 #endif
1006 static int Vcanna_fn_Quit = IROHA_FN_Quit;
1007 static int Vcanna_fn_ConvertAsHex = IROHA_FN_ConvertAsHex;
1008 static int Vcanna_fn_ConvertAsBushu = IROHA_FN_ConvertAsBushu;
1009 static int Vcanna_fn_KouhoIchiran = IROHA_FN_KouhoIchiran;
1010 static int Vcanna_fn_BubunMuhenkan = IROHA_FN_BubunMuhenkan;
1011 static int Vcanna_fn_Zenkaku = IROHA_FN_Zenkaku;
1012 static int Vcanna_fn_Hankaku = IROHA_FN_Hankaku;
1013 static int Vcanna_fn_ToUpper = IROHA_FN_ToUpper;
1014 static int Vcanna_fn_Capitalize = IROHA_FN_Capitalize;
1015 static int Vcanna_fn_ToLower = IROHA_FN_ToLower;
1016 static int Vcanna_fn_Hiragana = IROHA_FN_Hiragana;
1017 static int Vcanna_fn_Katakana = IROHA_FN_Katakana;
1018 static int Vcanna_fn_Romaji = IROHA_FN_Romaji;
1019 #ifdef CANNA_FN_BaseHiragana
1020 static int Vcanna_fn_BaseHiragana = CANNA_FN_BaseHiragana;
1021 static int Vcanna_fn_BaseKatakana = CANNA_FN_BaseKatakana;
1022 static int Vcanna_fn_BaseEisu = CANNA_FN_BaseEisu;
1023 static int Vcanna_fn_BaseZenkaku = CANNA_FN_BaseZenkaku;
1024 static int Vcanna_fn_BaseHankaku = CANNA_FN_BaseHankaku;
1025 static int Vcanna_fn_BaseKana = CANNA_FN_BaseKana;
1026 static int Vcanna_fn_BaseKakutei = CANNA_FN_BaseKakutei;
1027 static int Vcanna_fn_BaseHenkan = CANNA_FN_BaseHenkan;
1028 static int Vcanna_fn_BaseHiraKataToggle = CANNA_FN_BaseHiraKataToggle;
1029 static int Vcanna_fn_BaseZenHanToggle = CANNA_FN_BaseZenHanToggle;
1030 static int Vcanna_fn_BaseKanaEisuToggle = CANNA_FN_BaseKanaEisuToggle;
1031 static int Vcanna_fn_BaseKakuteiHenkanToggle =
1032   CANNA_FN_BaseKakuteiHenkanToggle;
1033 static int Vcanna_fn_BaseRotateForward = CANNA_FN_BaseRotateForward;
1034 static int Vcanna_fn_BaseRotateBackward = CANNA_FN_BaseRotateBackward;
1035 #endif
1036 static int Vcanna_fn_ExtendMode = IROHA_FN_ExtendMode;
1037 static int Vcanna_fn_Touroku = IROHA_FN_Touroku;
1038 static int Vcanna_fn_HexMode = IROHA_FN_HexMode;
1039 static int Vcanna_fn_BushuMode = IROHA_FN_BushuMode;
1040 static int Vcanna_fn_KigouMode = IROHA_FN_KigouMode;
1041 #ifdef CANNA_FN_Mark
1042 static int Vcanna_fn_Mark = CANNA_FN_Mark;
1043 #endif
1044 #ifdef CANNA_FN_TemporalMode
1045 static int Vcanna_fn_TemporalMode = CANNA_FN_TemporalMode;
1046 #endif
1047
1048 static int Vcanna_key_Nfer = IROHA_KEY_Nfer;
1049 static int Vcanna_key_Xfer = IROHA_KEY_Xfer;
1050 static int Vcanna_key_Up = IROHA_KEY_Up;
1051 static int Vcanna_key_Left = IROHA_KEY_Left;
1052 static int Vcanna_key_Right = IROHA_KEY_Right;
1053 static int Vcanna_key_Down = IROHA_KEY_Down;
1054 static int Vcanna_key_Insert = IROHA_KEY_Insert;
1055 static int Vcanna_key_Rollup = IROHA_KEY_Rollup;
1056 static int Vcanna_key_Rolldown = IROHA_KEY_Rolldown;
1057 static int Vcanna_key_Home = IROHA_KEY_Home;
1058 static int Vcanna_key_Help = IROHA_KEY_Help;
1059 static int Vcanna_key_KP_Key = IROHA_KEY_KP_Key;
1060 static int Vcanna_key_Shift_Nfer = IROHA_KEY_Shift_Nfer;
1061 static int Vcanna_key_Shift_Xfer = IROHA_KEY_Shift_Xfer;
1062 static int Vcanna_key_Shift_Up = IROHA_KEY_Shift_Up;
1063 static int Vcanna_key_Shift_Left = IROHA_KEY_Shift_Left;
1064 static int Vcanna_key_Shift_Right = IROHA_KEY_Shift_Right;
1065 static int Vcanna_key_Shift_Down = IROHA_KEY_Shift_Down;
1066 static int Vcanna_key_Cntrl_Nfer = IROHA_KEY_Cntrl_Nfer;
1067 static int Vcanna_key_Cntrl_Xfer = IROHA_KEY_Cntrl_Xfer;
1068 static int Vcanna_key_Cntrl_Up = IROHA_KEY_Cntrl_Up;
1069 static int Vcanna_key_Cntrl_Left = IROHA_KEY_Cntrl_Left;
1070 static int Vcanna_key_Cntrl_Right = IROHA_KEY_Cntrl_Right;
1071 static int Vcanna_key_Cntrl_Down = IROHA_KEY_Cntrl_Down;
1072
1073
1074 #ifdef CANNA_EMACS_DL
1075 static struct Lisp_Subr *s_canna_key_proc;
1076 static struct Lisp_Subr *s_canna_set_bunsetsu;
1077 static struct Lisp_Subr *s_canna_initialize;
1078 static struct Lisp_Subr *s_canna_finalize;
1079 static struct Lisp_Subr *s_canna_touroku_string;
1080 static struct Lisp_Subr *s_canna_set_width;
1081 static struct Lisp_Subr *s_canna_change_mode;
1082 static struct Lisp_Subr *s_canna_store_yomi;
1083 static struct Lisp_Subr *s_canna_do_function;
1084 static struct Lisp_Subr *s_canna_parse;
1085 static struct Lisp_Subr *s_canna_query_mode;
1086 static struct Lisp_Subr *s_canna_henkan_begin;
1087 static struct Lisp_Subr *s_canna_henkan_next;
1088 static struct Lisp_Subr *s_canna_bunsetu_henkou;
1089 static struct Lisp_Subr *s_canna_henkan_kakutei;
1090 static struct Lisp_Subr *s_canna_henkan_end;
1091 static struct Lisp_Subr *s_canna_henkan_quit;
1092 #else
1093 static Lisp_Object VCANNA;                      /* hir@nec, 1992.5.21 */
1094 #endif
1095
1096 #ifndef CANNA_EMACS_DL
1097 syms_of_canna ()
1098 {
1099   DEFVAR_LISP ("CANNA", &VCANNA, "");           /* hir@nec, 1992.5.21 */
1100   VCANNA = Qt;                                  /* hir@nec, 1992.5.21 */
1101
1102   defsubr (&Scanna_key_proc);
1103   defsubr (&Scanna_initialize);
1104   defsubr (&Scanna_finalize);
1105   defsubr (&Scanna_touroku_string);
1106   defsubr (&Scanna_set_width);
1107   defsubr (&Scanna_change_mode);
1108   defsubr (&Scanna_store_yomi);
1109   defsubr (&Scanna_do_function);
1110   defsubr (&Scanna_parse);
1111   defsubr (&Scanna_query_mode);
1112   defsubr (&Scanna_set_bunsetsu);
1113 #else /* CANNA_EMACS_DL */
1114 void
1115 emacs_canna_init ()
1116 {
1117   Lisp_Object sym;
1118   
1119   sym = intern("CANNA");
1120   XSYMBOL (sym)->value = Qt;
1121   
1122   s_canna_key_proc
1123     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1124   bcopy (&Scanna_key_proc, s_canna_key_proc, sizeof (struct Lisp_Subr));
1125   defsubr (s_canna_key_proc);
1126
1127   s_canna_initialize
1128     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1129   bcopy (&Scanna_initialize, s_canna_initialize, sizeof (struct Lisp_Subr));
1130   defsubr (s_canna_initialize);
1131   
1132   s_canna_finalize
1133     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1134   bcopy (&Scanna_finalize, s_canna_finalize, sizeof (struct Lisp_Subr));
1135   defsubr (s_canna_finalize);
1136   
1137   s_canna_touroku_string
1138     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1139   bcopy (&Scanna_touroku_string, s_canna_touroku_string,
1140          sizeof (struct Lisp_Subr));
1141   defsubr (s_canna_touroku_string);
1142
1143   s_canna_set_width
1144     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1145   bcopy (&Scanna_set_width, s_canna_set_width,
1146          sizeof (struct Lisp_Subr));
1147   defsubr (s_canna_set_width);
1148
1149   s_canna_change_mode
1150     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1151   bcopy (&Scanna_change_mode, s_canna_change_mode,
1152          sizeof (struct Lisp_Subr));
1153   defsubr (s_canna_change_mode);
1154   
1155   s_canna_store_yomi
1156     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1157   bcopy (&Scanna_store_yomi, s_canna_store_yomi,
1158          sizeof (struct Lisp_Subr));
1159   defsubr (s_canna_store_yomi);
1160   
1161   s_canna_do_function
1162     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1163   bcopy (&Scanna_do_function, s_canna_do_function,
1164          sizeof (struct Lisp_Subr));
1165   defsubr (s_canna_do_function);
1166   
1167   s_canna_parse
1168     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1169   bcopy (&Scanna_parse, s_canna_parse,
1170          sizeof (struct Lisp_Subr));
1171   defsubr (s_canna_parse);
1172   
1173   s_canna_query_mode
1174     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1175   bcopy (&Scanna_query_mode, s_canna_query_mode,
1176          sizeof (struct Lisp_Subr));
1177   defsubr (s_canna_query_mode);
1178   
1179   s_canna_set_bunsetsu
1180     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1181   bcopy (&Scanna_set_bunsetsu, s_canna_set_bunsetsu,
1182          sizeof (struct Lisp_Subr));
1183   defsubr (s_canna_set_bunsetsu);
1184 #endif
1185
1186 #ifndef CANNA_EMACS_DL
1187   DEFVAR_LISP("canna-kakutei-string", &Vcanna_kakutei_string, "");
1188   DEFVAR_LISP("canna-kakutei-yomi",   &Vcanna_kakutei_yomi,   "");
1189   DEFVAR_LISP("canna-kakutei-romaji", &Vcanna_kakutei_romaji, "");
1190   DEFVAR_LISP("canna-henkan-string",  &Vcanna_henkan_string,  "");
1191 #else /* CANNA_EMACS_DL */
1192   sym = intern("canna-kakutei-string"); sym = Qnil;
1193   sym = intern("canna-kakutei-yomi");   sym = Qnil;
1194   sym = intern("canna-kakutei-romaji"); sym = Qnil;
1195   sym = intern("canna-henkan-string");  sym = Qnil;
1196 #endif
1197   DEFVAR_INT ("canna-henkan-length",  &Vcanna_henkan_length,  "");
1198   DEFVAR_INT ("canna-henkan-revpos",  &Vcanna_henkan_revPos,  "");
1199   DEFVAR_INT ("canna-henkan-revlen",  &Vcanna_henkan_revLen,  "");
1200 #ifndef CANNA_EMACS_DL
1201   DEFVAR_LISP("canna-ichiran-string", &Vcanna_ichiran_string, "");
1202 #else /* CANNA_EMACS_DL */
1203   sym = intern("canna-ichiran-string"); sym = Qnil;
1204 #endif
1205   DEFVAR_INT ("canna-ichiran-length", &Vcanna_ichiran_length, "");
1206   DEFVAR_INT ("canna-ichiran-revpos", &Vcanna_ichiran_revPos, "");
1207   DEFVAR_INT ("canna-ichiran-revlen", &Vcanna_ichiran_revLen, "");
1208 #ifndef CANNA_EMACS_DL
1209   DEFVAR_LISP("canna-mode-string",    &Vcanna_mode_string,    "");
1210 #else /* CANNA_EMACS_DL */
1211   sym = intern("canna-mode-string");    sym = Qnil;
1212 #endif
1213   DEFVAR_BOOL ("canna-empty-info", &Vcanna_empty_info, "For canna");
1214   DEFVAR_BOOL ("canna-through-info", &Vcanna_through_info, "For canna");
1215   DEFVAR_BOOL ("canna-underline", &Vcanna_underline, "For canna");
1216   DEFVAR_BOOL ("canna-inhibit-hankakukana", &Vcanna_inhibit_hankakukana, 
1217                "For canna");                    /* hir, 1994.12.5 */
1218
1219 #ifndef CANNA_EMACS_DL
1220   defsubr (&Scanna_henkan_begin);
1221   defsubr (&Scanna_henkan_next);
1222   defsubr (&Scanna_bunsetu_henkou);
1223   defsubr (&Scanna_henkan_kakutei);
1224   defsubr (&Scanna_henkan_end);
1225   defsubr (&Scanna_henkan_quit);
1226 #else /* CANNA_EMACS_DL */
1227   s_canna_henkan_begin
1228     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1229   bcopy (&Scanna_henkan_begin, s_canna_henkan_begin,
1230          sizeof (struct Lisp_Subr));
1231   defsubr (s_canna_henkan_begin);
1232   
1233   s_canna_henkan_next
1234     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1235   bcopy (&Scanna_henkan_next, s_canna_henkan_next,
1236          sizeof (struct Lisp_Subr));
1237   defsubr (s_canna_henkan_next);
1238   
1239   s_canna_bunsetu_henkou
1240     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1241   bcopy (&Scanna_bunsetu_henkou, s_canna_bunsetu_henkou,
1242          sizeof (struct Lisp_Subr));
1243   defsubr (s_canna_bunsetu_henkou);
1244   
1245   s_canna_henkan_kakutei
1246     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1247   bcopy (&Scanna_henkan_kakutei, s_canna_henkan_kakutei,
1248          sizeof (struct Lisp_Subr));
1249   defsubr (s_canna_henkan_kakutei);
1250   
1251   s_canna_henkan_end
1252     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1253   bcopy (&Scanna_henkan_end, s_canna_henkan_end,
1254          sizeof (struct Lisp_Subr));
1255   defsubr (s_canna_henkan_end);
1256   
1257   s_canna_henkan_quit
1258     = (struct Lisp_Subr *)xmalloc (sizeof (struct Lisp_Subr));
1259   bcopy (&Scanna_henkan_quit, s_canna_henkan_quit,
1260          sizeof (struct Lisp_Subr));
1261   defsubr (s_canna_henkan_quit);
1262 #endif
1263
1264   DEFVAR_INT ("canna-mode-alpha-mode", &Vcanna_mode_AlphaMode, "");
1265   DEFVAR_INT ("canna-mode-empty-mode", &Vcanna_mode_EmptyMode, "");
1266   DEFVAR_INT ("canna-mode-kigo-mode",  &Vcanna_mode_KigoMode,  "");
1267   DEFVAR_INT ("canna-mode-yomi-mode",  &Vcanna_mode_YomiMode,  "");
1268   DEFVAR_INT ("canna-mode-jishu-mode", &Vcanna_mode_JishuMode, "");
1269   DEFVAR_INT ("canna-mode-tankouho-mode", &Vcanna_mode_TankouhoMode, "");
1270   DEFVAR_INT ("canna-mode-ichiran-mode",  &Vcanna_mode_IchiranMode,  "");
1271   DEFVAR_INT ("canna-mode-yes-no-mode", &Vcanna_mode_YesNoMode, "");
1272   DEFVAR_INT ("canna-mode-on-off-mode", &Vcanna_mode_OnOffMode, "");
1273 #ifdef CANNA_MODE_AdjustBunsetsuMode
1274   DEFVAR_INT ("canna-mode-adjust-bunsetsu-mode",
1275               &Vcanna_mode_AdjustBunsetsuMode, "");
1276 #endif
1277 #ifdef CANNA_MODE_ChikujiYomiMode
1278   DEFVAR_INT ("canna-mode-chikuji-yomi-mode", &Vcanna_mode_ChikujiYomiMode,"");
1279   DEFVAR_INT ("canna-mode-chikuji-bunsetsu-mode",
1280               &Vcanna_mode_ChikujiTanMode, "");
1281 #endif
1282
1283   DEFVAR_INT ("canna-mode-henkan-mode", &Vcanna_mode_HenkanMode, "");
1284 #ifdef CANNA_MODE_HenkanNyuryokuMode
1285   DEFVAR_INT ("canna-mode-henkan-nyuuryoku-mode",
1286               &Vcanna_mode_HenkanNyuryokuMode, 0);
1287 #endif
1288 #ifdef CANNA_MODE_ZenHiraHenkanMode
1289   DEFVAR_INT ("canna-mode-zen-hira-henkan-mode",
1290               &Vcanna_mode_ZenHiraHenkanMode, "");
1291 #ifdef CANNA_MODE_HanHiraHenkanMode
1292   DEFVAR_INT ("canna-mode-han-hira-henkan-mode",
1293               &Vcanna_mode_HanHiraHenkanMode, "");
1294 #endif
1295   DEFVAR_INT ("canna-mode-zen-kata-henkan-mode",
1296               &Vcanna_mode_ZenKataHenkanMode, "");
1297   DEFVAR_INT ("canna-mode-han-kata-henkan-mode",
1298               &Vcanna_mode_HanKataHenkanMode, "");
1299   DEFVAR_INT ("canna-mode-zen-alpha-henkan-mode",
1300               &Vcanna_mode_ZenAlphaHenkanMode, "");
1301   DEFVAR_INT ("canna-mode-han-alpha-henkan-mode",
1302               &Vcanna_mode_HanAlphaHenkanMode, "");
1303 #endif
1304   DEFVAR_INT ("canna-mode-zen-hira-kakutei-mode",
1305               &Vcanna_mode_ZenHiraKakuteiMode, "");
1306 #ifdef CANNA_MODE_HanHiraKakuteiMode
1307   DEFVAR_INT ("canna-mode-han-hira-kakutei-mode",
1308               &Vcanna_mode_HanHiraKakuteiMode, "");
1309 #endif
1310   DEFVAR_INT ("canna-mode-zen-kata-kakutei-mode",
1311               &Vcanna_mode_ZenKataKakuteiMode, "");
1312   DEFVAR_INT ("canna-mode-han-kata-kakutei-mode",
1313               &Vcanna_mode_HanKataKakuteiMode, "");
1314   DEFVAR_INT ("canna-mode-zen-alpha-kakutei-mode",
1315               &Vcanna_mode_ZenAlphaKakuteiMode, "");
1316   DEFVAR_INT ("canna-mode-han-alpha-kakutei-mode",
1317               &Vcanna_mode_HanAlphaKakuteiMode, "");
1318   DEFVAR_INT ("canna-mode-hex-mode", &Vcanna_mode_HexMode, "");
1319   DEFVAR_INT ("canna-mode-bushu-mode", &Vcanna_mode_BushuMode, "");
1320   DEFVAR_INT ("canna-mode-extend-mode", &Vcanna_mode_ExtendMode, "");
1321   DEFVAR_INT ("canna-mode-russian-mode", &Vcanna_mode_RussianMode, "");
1322   DEFVAR_INT ("canna-mode-greek-mode", &Vcanna_mode_GreekMode, "");
1323   DEFVAR_INT ("canna-mode-line-mode", &Vcanna_mode_LineMode, "");
1324   DEFVAR_INT ("canna-mode-changing-server-mode",
1325               &Vcanna_mode_ChangingServerMode, "");
1326   DEFVAR_INT ("canna-mode-henkan-method-mode",
1327               &Vcanna_mode_HenkanMethodMode, "");
1328   DEFVAR_INT ("canna-mode-delete-dic-mode", &Vcanna_mode_DeleteDicMode, "");
1329   DEFVAR_INT ("canna-mode-touroku-mode", &Vcanna_mode_TourokuMode, "");
1330   DEFVAR_INT ("canna-mode-touroku-empty-mode",
1331               &Vcanna_mode_TourokuEmptyMode, "");
1332   DEFVAR_INT ("canna-mode-touroku-hinshi-mode",
1333               &Vcanna_mode_TourokuHinshiMode, "");
1334   DEFVAR_INT ("canna-mode-touroku-dic-mode", &Vcanna_mode_TourokuDicMode, "");
1335   DEFVAR_INT ("canna-mode-quoted-insert-mode",
1336               &Vcanna_mode_QuotedInsertMode, "");
1337   DEFVAR_INT ("canna-mode-bubun-muhenkan-mode",
1338               &Vcanna_mode_BubunMuhenkanMode, "");
1339   DEFVAR_INT ("canna-mode-mount-dic-mode", &Vcanna_mode_MountDicMode, "");
1340
1341   DEFVAR_INT ("canna-func-self-insert", &Vcanna_fn_SelfInsert ,"");
1342   DEFVAR_INT ("canna-func-functional-insert", &Vcanna_fn_FunctionalInsert ,"");
1343   DEFVAR_INT ("canna-func-quoted-insert", &Vcanna_fn_QuotedInsert ,"");
1344   DEFVAR_INT ("canna-func-japanese-mode", &Vcanna_fn_JapaneseMode ,"");
1345   DEFVAR_INT ("canna-func-alpha-mode", &Vcanna_fn_AlphaMode ,"");
1346   DEFVAR_INT ("canna-func-henkan-nyuryoku-mode",
1347               &Vcanna_fn_HenkanNyuryokuMode ,"");
1348   DEFVAR_INT ("canna-func-forward", &Vcanna_fn_Forward ,"");
1349   DEFVAR_INT ("canna-func-backward", &Vcanna_fn_Backward ,"");
1350   DEFVAR_INT ("canna-func-next", &Vcanna_fn_Next ,"");
1351   DEFVAR_INT ("canna-func-previous", &Vcanna_fn_Prev ,"");
1352   DEFVAR_INT ("canna-func-beginning-of-line", &Vcanna_fn_BeginningOfLine ,"");
1353   DEFVAR_INT ("canna-func-end-of-line", &Vcanna_fn_EndOfLine ,"");
1354   DEFVAR_INT ("canna-func-delete-next", &Vcanna_fn_DeleteNext ,"");
1355   DEFVAR_INT ("canna-func-delete_previous", &Vcanna_fn_DeletePrevious ,"");
1356   DEFVAR_INT ("canna-func-kill-to-end-of-line", &Vcanna_fn_KillToEndOfLine,"");
1357   DEFVAR_INT ("canna-func-henkan", &Vcanna_fn_Henkan ,"");
1358   DEFVAR_INT ("canna-func-kakutei", &Vcanna_fn_Kakutei ,"");
1359   DEFVAR_INT ("canna-func-extend", &Vcanna_fn_Extend ,"");
1360   DEFVAR_INT ("canna-func-shrink", &Vcanna_fn_Shrink ,"");
1361 #ifdef CANNA_FN_AdjustBunsetsu
1362   DEFVAR_INT ("canna-func-adjust-bunsetsu", &Vcanna_fn_AdjustBunsetsu ,"");
1363 #endif
1364   DEFVAR_INT ("canna-func-quit", &Vcanna_fn_Quit ,"");
1365   DEFVAR_INT ("canna-func-convert-as-hex", &Vcanna_fn_ConvertAsHex ,"");
1366   DEFVAR_INT ("canna-func-convert-as-bushu", &Vcanna_fn_ConvertAsBushu ,"");
1367   DEFVAR_INT ("canna-func-kouho-ichiran", &Vcanna_fn_KouhoIchiran ,"");
1368   DEFVAR_INT ("canna-func-bubun-muhenkan", &Vcanna_fn_BubunMuhenkan ,"");
1369   DEFVAR_INT ("canna-func-zenkaku", &Vcanna_fn_Zenkaku ,"");
1370   DEFVAR_INT ("canna-func-hankaku", &Vcanna_fn_Hankaku ,"");
1371   DEFVAR_INT ("canna-func-to-upper", &Vcanna_fn_ToUpper ,"");
1372   DEFVAR_INT ("canna-func-capitalize", &Vcanna_fn_Capitalize ,"");
1373   DEFVAR_INT ("canna-func-to-lower", &Vcanna_fn_ToLower ,"");
1374   DEFVAR_INT ("canna-func-hiragana", &Vcanna_fn_Hiragana ,"");
1375   DEFVAR_INT ("canna-func-katakana", &Vcanna_fn_Katakana ,"");
1376   DEFVAR_INT ("canna-func-romaji", &Vcanna_fn_Romaji ,"");
1377 #ifdef CANNA_FN_BaseHiragana
1378   DEFVAR_INT ("canna-func-base-hiragana", &Vcanna_fn_BaseHiragana ,"");
1379   DEFVAR_INT ("canna-func-base-katakana", &Vcanna_fn_BaseKatakana ,"");
1380   DEFVAR_INT ("canna-func-base-eisu", &Vcanna_fn_BaseEisu ,"");
1381   DEFVAR_INT ("canna-func-base-zenkaku", &Vcanna_fn_BaseZenkaku ,"");
1382   DEFVAR_INT ("canna-func-base-hankaku", &Vcanna_fn_BaseHankaku ,"");
1383   DEFVAR_INT ("canna-func-base-kana", &Vcanna_fn_BaseKana ,"");
1384   DEFVAR_INT ("canna-func-base-kakutei", &Vcanna_fn_BaseKakutei ,"");
1385   DEFVAR_INT ("canna-func-base-henkan", &Vcanna_fn_BaseHenkan ,"");
1386   DEFVAR_INT ("canna-func-base-hiragana-katakana-toggle",
1387               &Vcanna_fn_BaseHiraKataToggle ,"");
1388   DEFVAR_INT ("canna-func-base-zenkaku-hankaku-toggle",
1389               &Vcanna_fn_BaseZenHanToggle ,"");
1390   DEFVAR_INT ("canna-func-base-kana-eisu-toggle",
1391               &Vcanna_fn_BaseKanaEisuToggle ,"");
1392   DEFVAR_INT ("canna-func-base-kakutei-henkan-toggle",
1393               &Vcanna_fn_BaseKakuteiHenkanToggle ,"");
1394   DEFVAR_INT ("canna-func-base-rotate-forward",
1395               &Vcanna_fn_BaseRotateForward ,"");
1396   DEFVAR_INT ("canna-func-base-rotate-backward",
1397               &Vcanna_fn_BaseRotateBackward ,"");
1398 #endif
1399   DEFVAR_INT ("canna-func-extend-mode", &Vcanna_fn_ExtendMode ,"");
1400   DEFVAR_INT ("canna-func-touroku", &Vcanna_fn_Touroku ,"");
1401   DEFVAR_INT ("canna-func-hex-mode", &Vcanna_fn_HexMode ,"");
1402   DEFVAR_INT ("canna-func-bushu-mode", &Vcanna_fn_BushuMode ,"");
1403   DEFVAR_INT ("canna-func-kigo-mode", &Vcanna_fn_KigouMode ,"");
1404 #ifdef CANNA_FN_Mark
1405   DEFVAR_INT ("canna-func-mark", &Vcanna_fn_Mark ,"");
1406 #endif
1407 #ifdef CANNA_FN_TemporalMode
1408   DEFVAR_INT ("canna-func-temporal-mode", &Vcanna_fn_TemporalMode ,"");
1409 #endif
1410
1411   DEFVAR_INT ("canna-key-nfer", &Vcanna_key_Nfer, "");
1412   DEFVAR_INT ("canna-key-xfer", &Vcanna_key_Xfer, "");
1413   DEFVAR_INT ("canna-key-up", &Vcanna_key_Up, "");
1414   DEFVAR_INT ("canna-key-left", &Vcanna_key_Left, "");
1415   DEFVAR_INT ("canna-key-right", &Vcanna_key_Right, "");
1416   DEFVAR_INT ("canna-key-down", &Vcanna_key_Down, "");
1417   DEFVAR_INT ("canna-key-insert", &Vcanna_key_Insert, "");
1418   DEFVAR_INT ("canna-key-rollup", &Vcanna_key_Rollup, "");
1419   DEFVAR_INT ("canna-key-rolldown", &Vcanna_key_Rolldown, "");
1420   DEFVAR_INT ("canna-key-home", &Vcanna_key_Home, "");
1421   DEFVAR_INT ("canna-key-help", &Vcanna_key_Help, "");
1422   DEFVAR_INT ("canna-key-kp-key", &Vcanna_key_KP_Key, "");
1423   DEFVAR_INT ("canna-key-shift-nfer", &Vcanna_key_Shift_Nfer, "");
1424   DEFVAR_INT ("canna-key-shift-xfer", &Vcanna_key_Shift_Xfer, "");
1425   DEFVAR_INT ("canna-key-shift-up", &Vcanna_key_Shift_Up, "");
1426   DEFVAR_INT ("canna-key-shift-left", &Vcanna_key_Shift_Left, "");
1427   DEFVAR_INT ("canna-key-shift-right", &Vcanna_key_Shift_Right, "");
1428   DEFVAR_INT ("canna-key-shift-down", &Vcanna_key_Shift_Down, "");
1429   DEFVAR_INT ("canna-key-control-nfer", &Vcanna_key_Cntrl_Nfer, "");
1430   DEFVAR_INT ("canna-key-control-xfer", &Vcanna_key_Cntrl_Xfer, "");
1431   DEFVAR_INT ("canna-key-control-up", &Vcanna_key_Cntrl_Up, "");
1432   DEFVAR_INT ("canna-key-control-left", &Vcanna_key_Cntrl_Left, "");
1433   DEFVAR_INT ("canna-key-control-right", &Vcanna_key_Cntrl_Right, "");
1434   DEFVAR_INT ("canna-key-control-down", &Vcanna_key_Cntrl_Down, "");
1435 }
1436
1437 #ifdef CANNA_EMACS_DL
1438 void
1439 emacs_wnnfns_fini ()
1440 {
1441   undefsubr (s_canna_key_proc);
1442   free (s_canna_key_proc);
1443   
1444   undefsubr (s_canna_initialize);
1445   free (s_canna_initialize);
1446
1447   undefsubr (s_canna_finalize);
1448   free (s_canna_finalize);
1449
1450   undefsubr (s_canna_touroku_string);
1451   free (s_canna_touroku_string);
1452
1453   undefsubr (s_canna_set_width);
1454   free (s_canna_set_width);
1455
1456   undefsubr (s_canna_change_mode);
1457   free (s_canna_change_mode);
1458
1459   undefsubr (s_canna_store_yomi);
1460   free (s_canna_store_yomi);
1461
1462   undefsubr (s_canna_do_function);
1463   free (s_canna_do_function);
1464
1465   undefsubr (s_canna_parse);
1466   free (s_canna_parse);
1467
1468   undefsubr (s_canna_query_mode);
1469   free (s_canna_query_mode);
1470
1471   undefsubr (s_canna_set_bunsetsu);
1472   free (s_canna_set_bunsetsu);
1473
1474   undefsubr (s_canna_henkan_begin);
1475   free (s_canna_henkan_begin);
1476
1477   undefsubr (s_canna_henkan_next);
1478   free (s_canna_henkan_next);
1479
1480   undefsubr (s_canna_bunsetu_henkou);
1481   free (s_canna_bunsetu_henkou);
1482
1483   undefsubr (s_canna_henkan_kakutei);
1484   free (s_canna_henkan_kakutei);
1485
1486   undefsubr (s_canna_henkan_end);
1487   free (s_canna_henkan_end);
1488
1489   undefsubr (s_canna_henkan_quit);
1490   free (s_canna_henkan_quit);
1491 }
1492 #endif
1493
1494 #ifndef CANNA_NEMACS
1495 /* To handle MULE internal code and EUC.
1496    I assume CANNA can handle only Japanese EUC. */
1497
1498 /* EUC multibyte string to MULE internal string */
1499
1500 static
1501 c2mu(cp, l, mp)
1502 char    *cp;
1503 int     l;
1504 char    *mp;
1505 {
1506   char  ch, *ep = cp+l;
1507   
1508   while((cp < ep) && (ch = *cp)) {
1509     if ((unsigned char)ch == ISO_CODE_SS2) {
1510       *mp++ = CHARSET_KATAKANA_JISX0201;
1511       cp++;
1512     }
1513     else if ((unsigned char)ch == ISO_CODE_SS3) {
1514       *mp++ = CHARSET_JAPANESE_JISX0212;
1515       cp++;
1516       *mp++ = *cp++;
1517     }
1518     else if(ch & 0x80) {
1519       *mp++ = CHARSET_JAPANESE_JISX0208;
1520       *mp++ = *cp++;
1521     }
1522     *mp++ = *cp++;
1523   }
1524   *mp = 0;
1525 }
1526
1527 /* MULE internal string to EUC multibyte string */
1528
1529 static
1530 m2c(mp, l, cp)
1531 unsigned char   *mp;
1532 int     l;
1533 unsigned char   *cp;
1534 {
1535   unsigned char ch, *ep = mp + l;;
1536   
1537   while((mp < ep) && (ch = *mp++)) {
1538     switch (ch) {
1539     case CHARSET_KATAKANA_JISX0201:
1540       *cp++ = ISO_CODE_SS2;
1541       *cp++ = *mp++;
1542       break;
1543     case CHARSET_JAPANESE_JISX0212:
1544       *cp++ = ISO_CODE_SS3;
1545     case CHARSET_JAPANESE_JISX0208:
1546       *cp++ = *mp++;
1547       *cp++ = *mp++;
1548       break;
1549     default:
1550       *cp++ = ch;
1551       break;
1552     }
1553   }     
1554   *cp = 0;
1555 }
1556
1557 #undef make_string
1558
1559 /* make_string after converting EUC string to MULE internal string */
1560 static
1561 Lisp_Object
1562 mule_make_string(p,l)
1563 unsigned char *p;
1564 int l;
1565 {
1566   unsigned char cbuf[4096];
1567   
1568   c2mu(p,l,cbuf);
1569   return (make_string(cbuf,strlen(cbuf)));
1570 }       
1571
1572 /* return the MULE internal string length of EUC string */
1573 static
1574 mule_strlen(p,l)
1575 unsigned char *p;
1576 int l;
1577 {
1578   unsigned char ch, *cp = p;
1579   int len = 0;
1580   
1581   while((cp < p + l) && (ch = *cp)) {
1582     if ((unsigned char)ch == ISO_CODE_SS2) {
1583 #ifdef STRING_BYTES
1584       len++;
1585 #else
1586       len += 2;
1587 #endif
1588       cp += 2;
1589     }
1590     else if ((unsigned char)ch == ISO_CODE_SS3) {
1591 #ifdef STRING_BYTES
1592       len++;
1593 #else
1594       len += 3;
1595 #endif
1596       cp += 3;
1597     }
1598     else if(ch & 0x80) {
1599 #ifdef STRING_BYTES
1600       len++;
1601 #else
1602       len += 3;
1603 #endif
1604       cp += 2;
1605     }
1606     else {
1607       len++;
1608       cp++;     
1609     }
1610   }
1611   return(len);
1612 }
1613
1614 /* count number of characters */
1615 static
1616 count_char(p,len,pos,rev,clen,cpos,crev)
1617 unsigned char *p;       
1618 int len,pos,rev,*clen,*cpos,*crev;
1619 {
1620   unsigned char *q = p;
1621   
1622   *clen = *cpos = *crev = 0;
1623   if (len == 0) return;
1624   while (q < p + pos) {
1625     (*clen)++;
1626     (*cpos)++;
1627     if (*q++ & 0x80) q++;
1628   }
1629   while (q < p + pos + rev) {
1630     (*clen)++;
1631     (*crev)++;
1632     if (*q++ & 0x80) q++;
1633   }             
1634   while (q < p + len) {
1635     (*clen)++;
1636     if (*q++ & 0x80) q++;
1637   }
1638 }
1639 #endif /* CANNA_MULE */