1 /* Copyright 1992 NEC Corporation, Tokyo, Japan.
2  *
3  * Permission to use, copy, modify, distribute and sell this software
4  * and its documentation for any purpose is hereby granted without
5  * fee, provided that the above copyright notice appear in all copies
6  * and that both that copyright notice and this permission notice
7  * appear in supporting documentation, and that the name of NEC
8  * Corporation not be used in advertising or publicity pertaining to
9  * distribution of the software without specific, written prior
10  * permission.  NEC Corporation makes no representations about the
11  * suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
16  * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
18  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
19  * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 #if !defined(lint) && !defined(__CODECENTER__)
24 static char rcs_id[] = "@(#) 102.1 $Id: kctrl.c,v 1.10 2003/09/21 09:08:17 aida_s Exp $";
25 #endif /* lint */
26 
27 #include "canna.h"
28 
29 #include <errno.h>
30 #include <sys/types.h>
31 #include <canna/mfdef.h>
32 
33 /*********************************************************************
34  *                      wchar_t replace begin                        *
35  *********************************************************************/
36 #ifdef wchar_t
37 # error "wchar_t is already defined"
38 #endif
39 #define wchar_t cannawc
40 
41 #define DEFAULT_COLUMN_WIDTH	70
42 
43 extern char *CANNA_initfilename;
44 extern char saveapname[];
45 
46 static int insertEmptySlots pro((uiContext));
47 static int callCallback pro((uiContext, int));
48 static void freeKeysup pro((void));
49 static void freeBuffer pro((void));
50 static void freeExtra pro((void));
51 extern int ckverbose;
52 
53 static
doInitializeFunctions(d)54 doInitializeFunctions(d)
55 uiContext d;
56 {
57   BYTE *p;
58   int res = 0;
59   wcKanjiStatus ks, *pks;
60   extern BYTE *initfunc;
61   wchar_t xxxx[10];
62 
63   d->ch = 0;
64   d->buffer_return = xxxx;
65   d->n_buffer = sizeof(xxxx) / sizeof(wchar_t);
66   d->nbytes = 0;
67 
68   if (initfunc) {
69     pks = d->kanji_status_return;
70     d->kanji_status_return = &ks;
71     for (p = initfunc ; *p ; p++) {
72       res = _doFunc(d, *p);
73     }
74     res = _afterDoFunc(d, res);
75     d->kanji_status_return = pks;
76   }
77   return res;
78 }
79 
80 /* uiContext �ν���� */
81 
initRomeStruct(d,flg)82 initRomeStruct(d, flg)
83      uiContext	d;
84      int	flg;
85 {
86   extern KanjiModeRec alpha_mode, empty_mode;
87   extern KanjiModeRec kzhr_mode, kzkt_mode, kzal_mode;
88   extern KanjiModeRec khkt_mode, khal_mode;
89   yomiContext yc;
90   extern defaultContext, defaultBushuContext;
91 
92   bzero(d, sizeof(uiContextRec));
93 
94   if (insertEmptySlots(d) < 0) {
95     return -1;
96   }
97 
98   /* ����ƥ����Ȥ�ǽ�˥ǥ�ץꥱ���Ȥ��Ƥ��������ä��ʤ� */
99   d->contextCache = -1;
100 
101   /* ����⡼��(����ե��٥åȥ⡼��)������� */
102   d->majorMode = d->minorMode = CANNA_MODE_AlphaMode;
103   yc = (yomiContext)d->modec;
104   if (flg) {
105     yc->minorMode = CANNA_MODE_ChikujiYomiMode;
106     yc->generalFlags |= CANNA_YOMI_CHIKUJI_MODE;
107   }
108   alphaMode(d);
109 
110   /* ��� func ��¹Ԥ��� */
111 
112   (void)doInitializeFunctions(d);
113   return 0;
114 }
115 
116 static void
freeModec(modec)117 freeModec(modec)
118 mode_context modec;
119 {
120   coreContext cc;
121   union {
122     coreContext c;
123     yomiContext y;
124     ichiranContext i;
125     forichiranContext f;
126     mountContext m;
127     tourokuContext t;
128   } gc;
129 
130   cc = (coreContext)modec;
131   while (cc) {
132     switch (cc->id) {
133     case CORE_CONTEXT:
134       gc.c = cc;
135       cc = (coreContext)gc.c->next;
136       freeCoreContext(gc.c);
137       break;
138     case YOMI_CONTEXT:
139       gc.y = (yomiContext)cc;
140       cc = (coreContext)gc.y->next;
141       /* yc->context �� close �Ϥ���ʤ��Τ��ʤ���1996.10.30 �� */
142       freeYomiContext(gc.y);
143       break;
144     case ICHIRAN_CONTEXT:
145       gc.i = (ichiranContext)cc;
146       cc = (coreContext)gc.i->next;
147       freeIchiranContext(gc.i);
148       break;
149     case FORICHIRAN_CONTEXT:
150       gc.f = (forichiranContext)cc;
151       cc = (coreContext)gc.f->next;
152       freeForIchiranContext(gc.f);
153       break;
154     case MOUNT_CONTEXT:
155       gc.m = (mountContext)cc;
156       cc = (coreContext)gc.m->next;
157       freeIchiranContext(gc.i);
158       break;
159     case TOUROKU_CONTEXT:
160       gc.t = (tourokuContext)cc;
161       cc = (coreContext)gc.t->next;
162       free(gc.t);
163       break;
164     default:
165       break;
166     }
167   }
168 }
169 
170 static void
freeCallbacks(cb)171 freeCallbacks(cb)
172 struct callback *cb;
173 {
174   struct callback *nextcb;
175 
176   for (; cb ; cb = nextcb) {
177     nextcb = cb->next;
178     free(cb);
179   }
180 }
181 
182 void
freeRomeStruct(d)183 freeRomeStruct(d)
184 uiContext d;
185 {
186   freeModec(d->modec);
187   if (d->cb) {
188     freeCallbacks(d->cb);
189   }
190   if (d->contextCache >= 0) {
191     if (RkwCloseContext(d->contextCache) < 0) {
192       if (errno == EPIPE) {
193 	jrKanjiPipeError();
194       }
195     }
196   }
197 #ifndef NO_EXTEND_MENU
198   freeAllMenuInfo(d->minfo);
199 #endif
200   if (d->selinfo) {
201     selectinfo *p, *q;
202 
203     for (p = d->selinfo ; p ; p = q) {
204       q = p->next;
205       free((char *)p);
206     }
207   }
208   if (d->attr) {
209     if (d->attr->u.attr) {
210       free(d->attr->u.attr);
211     }
212     free((char *)d->attr);
213   }
214   free(d);
215 }
216 
217 static
insertEmptySlots(d)218 insertEmptySlots(d)
219 uiContext d;
220 {
221   extern KanjiModeRec	empty_mode;
222   struct callback	*pushCallback();
223   yomiContext		yc;
224 
225   if (pushCallback(d, (mode_context) NULL, NO_CALLBACK, NO_CALLBACK,
226 		   NO_CALLBACK, NO_CALLBACK) == (struct callback *)NULL)
227     return NoMoreMemory();
228 
229   yc = newYomiContext((wchar_t *)NULL, 0, /* ��̤ϳ�Ǽ���ʤ� */
230 		      CANNA_NOTHING_RESTRICTED,
231 		      (int)!CANNA_YOMI_CHGMODE_INHIBITTED,
232 		      (int)!CANNA_YOMI_END_IF_KAKUTEI,
233 		      CANNA_YOMI_INHIBIT_NONE);
234   if (yc == (yomiContext)0) {
235     popCallback(d);
236     return NoMoreMemory();
237   }
238   yc->majorMode = yc->minorMode = CANNA_MODE_HenkanMode;
239   d->majorMode = d->minorMode = CANNA_MODE_HenkanMode;
240   d->modec = (mode_context)yc;
241 
242   d->current_mode = yc->curMode = yc->myEmptyMode = &empty_mode;
243   yc->romdic = romajidic;
244   d->ncolumns = DEFAULT_COLUMN_WIDTH;
245   d->minfo = (menuinfo *)0;
246   d->selinfo = (selectinfo *)0;
247   d->prevMenu = (menustruct *)0;
248   return 0;
249 }
250 
251 /*
252 
253   display �� window ���Ȥ� ����ƥ�����ID ��ºݤΥ���ƥ����Ȥ��б���
254   ���뤿��Υϥå���ơ��֥�
255 
256   display �� window �������륭���ΤȤ��������ȡ������˥���ƥ�����
257   �����äƤ����Ψ���⤤���⤷���äƤ��ʤ��Ȥ⡢�ݥ�������������ɤä�
258   �Ԥ��Ȥ��Ĥ��ϥ���ƥ����Ȥ�������˰㤤�ʤ���
259 
260  */
261 
262 #define HASHTABLESIZE 96
263 
264 static struct bukRec {
265   unsigned int data1, data2;
266   uiContext context;
267   struct bukRec *next;
268 } *conHash[HASHTABLESIZE];
269 
270 /* �ϥå���ơ��֥��Ĵ�٤ƥ���ƥ����Ȥ����뤫�ɤ���Ĵ�٤�ؿ� */
271 
272 static
countContext()273 countContext()
274 {
275   struct bukRec *hash;
276 
277   int i, c;
278   for(i = 0, c = 0; i < HASHTABLESIZE; i++) {
279     for(hash = conHash[i] ; hash && hash->context ;hash = hash->next){
280       c++;
281     }
282   }
283 #if defined(DEBUG)
284   fprintf(stderr, "���=%d\n", c);
285 #endif
286   if(c) {
287     return 0;
288   }
289   else {
290     return 1;
291   }
292 }
293 
294 /* �ϥå��奭������ؿ�(�����ø�) */
295 
296 static unsigned int
makeKey(data1,data2)297 makeKey(data1, data2)
298 unsigned int data1, data2;
299 {
300   unsigned int key;
301 
302   key = data1 % HASHTABLESIZE;
303   key += data2 % HASHTABLESIZE;
304   key %= HASHTABLESIZE;
305   return key;
306 }
307 
308 /*
309 
310   keyToContext -- Display �� Window ���Ȥʤɤ��饳��ƥ����Ȥ���Ф�����
311 
312   display �� window ���Ȥ�����ƥ����Ȥ���äƤ���Ф��Υ���ƥ�����
313   ���֤���
314 
315   ���äƤ��ʤ��ΤǤ���С�NULL ���֤���
316 
317   */
318 
319 uiContext
keyToContext(data1,data2)320 keyToContext(data1, data2)
321 unsigned int data1, data2;
322 {
323   unsigned int key;
324   struct bukRec *p;
325 
326   key = makeKey(data1, data2);
327   for (p = conHash[key] ; p ; p = p->next) {
328     if (p->data1 == data1 && p->data2 == data2) {
329       /* ����㤢����ƥ����Ȥ����Ĥ���ޤ����� */
330       return p->context;
331     }
332   }
333   return (uiContext)0; /* ���Ĥ���ޤ���Ǥ����� */
334 }
335 
336 
337 /* internContext -- �ϥå���ơ��֥����Ͽ����
338 
339   ���ΤȤ������ˡ�display �� window ���Ȥ�¸�ߤ���ΤǤ���С�
340   ������ˤĤʤ��äƤ��륳��ƥ����Ȥ�ե꡼����Τ���ա���
341 
342 */
343 
344 struct bukRec *
internContext(data1,data2,context)345 internContext(data1, data2, context)
346 unsigned int data1, data2;
347 uiContext context;
348 {
349   unsigned int key;
350   struct bukRec *p, **pp;
351 
352   key = makeKey(data1, data2);
353   for (pp = &conHash[key]; (p = *pp) != (struct bukRec *)0; pp = &(p->next)) {
354     if (p->data1 == data1 && p->data2 == data2) {
355       freeRomeStruct(p->context);
356       p->context = context;
357       return p;
358     }
359   }
360   p = *pp = (struct bukRec *)malloc(sizeof(struct bukRec));
361   if (p) {
362     p->data1 = data1;
363     p->data2 = data2;
364     p->context = context;
365     p->next = (struct bukRec *)0;
366   }
367   return p;
368 }
369 
370 
371 /* rmContext -- �ϥå���ơ��֥뤫��������
372 
373 */
374 
375 void
rmContext(data1,data2)376 rmContext(data1, data2)
377 unsigned int data1, data2;
378 {
379   unsigned int key;
380   struct bukRec *p, *q, **pp;
381 
382   key = makeKey(data1, data2);
383   pp = &conHash[key];
384   for (p = *pp ; p ; p = q) {
385     q = p->next;
386     if (p->data1 == data1 && p->data2 == data2) {
387       *pp = q;
388       free(p);
389     }
390     else {
391       pp = &(p->next);
392     }
393   }
394 }
395 
396 /* cfuncdef
397 
398   freeBukRecs() -- �ݥ���Ȥ���Ƥ�����ΥХ��åȤΥե꡼
399 
400   �Х��åȤˤ�äƥݥ���Ȥ���Ƥ���ǡ������٤ƥե꡼���롣
401   �ե꡼���оݤˤ� uiContext ��ޤޤ�롣
402 
403 */
404 
405 static void
freeBukRecs(p)406 freeBukRecs(p)
407 struct bukRec *p;
408 {
409   struct bukRec *nextp;
410 
411   if (p) { /* reconfirm that p points some structure */
412     freeRomeStruct(p->context);
413     nextp = p->next;
414     if (nextp) {
415       freeBukRecs(nextp);
416     }
417     free(p);
418   }
419 }
420 
421 /* cfuncdef
422 
423   clearHashTable() -- �ϥå���ơ��֥�����Ƥ��٤ƥե꡼���롣
424 
425 */
426 
427 static void
clearHashTable()428 clearHashTable()
429 {
430   int i;
431   struct bukRec *p;
432 
433   for (i = 0 ; i < HASHTABLESIZE ; i++) {
434     p = conHash[i];
435     conHash[i] = 0;
436     if (p) {
437       freeBukRecs(p);
438     }
439   }
440 }
441 
442 #define NWARNINGMESG 64
443 static char *WarningMesg[NWARNINGMESG + 1]; /* +1 �ϺǸ�� NULL �ݥ�����ʬ */
444 static int nWarningMesg = 0;
445 
446 static void
initWarningMesg()447 initWarningMesg()
448 {
449   int i;
450 
451   for (i = 0 ; i < nWarningMesg ; i++) {
452     free(WarningMesg[i]);
453     WarningMesg[i] = (char *)0;
454   }
455   nWarningMesg = 0;
456 }
457 
458 void
addWarningMesg(s)459 addWarningMesg(s)
460 char *s;
461 {
462   int n;
463   char *work;
464 
465   if (nWarningMesg < NWARNINGMESG) {
466     n = strlen(s);
467     work = (char *)malloc(n + 1);
468     if (work) {
469       strcpy(work, s);
470       WarningMesg[nWarningMesg++] = work;
471     }
472   }
473 }
474 
475 static int
KC_keyconvCallback(d,arg)476 KC_keyconvCallback(d, arg)
477 uiContext d;
478 char *arg;
479 /* ARGSUSED */
480 {
481   extern void (*keyconvCallback)();
482 
483   if (arg) {
484     keyconvCallback = (void (*)())arg;
485   }
486   else {
487     keyconvCallback = (void (*)())0;
488   }
489   return 0;
490 }
491 
492 extern void restoreBindings();
493 
494 static
KC_initialize(d,arg)495 KC_initialize(d, arg)
496      uiContext d;
497      char *arg;
498      /* ARGSUSED */
499 {
500   extern FirstTime;
501 
502   if (FirstTime) {
503 #ifdef ENGINE_SWITCH
504     extern char *RkGetServerEngine pro((void));
505     if (!RkGetServerEngine()) {
506       RkSetServerName((char *)0);
507     }
508 #endif
509 
510     InitCannaConfig(&cannaconf);
511 
512     debug_message("KC_INITIALIZE \244\362\313\334\305\366\244\313\244\271\244\353\244\276\n",0,0,0);
513                                  /* �������ˤ��뤾 */
514 
515 #ifndef NO_EXTEND_MENU
516     if (initExtMenu() < 0) {
517       jrKanjiError = "Insufficient memory.";
518       if (arg) *(char ***)arg = (char **)0;
519       return -1;
520     }
521 #endif
522 
523     /* �磻�ɥ���饯���ѥ�������ν���� */
524 
525     WStringOpen();
526 #ifndef NO_EXTEND_MENU
527     if (initBushuTable() != NG) {
528       if (initGyouTable() != NG) {
529         if (initHinshiTable() != NG) {
530           if (initUlKigoTable() != NG) {
531             if (initUlKeisenTable() != NG) {
532               if (initOnoffTable() != NG) {
533                 initKigoTable(); /* ���⤷�Ƥ��ʤ� */
534                 if (initHinshiMessage() != NG) {
535 #endif
536 
537                   /* �������˥���å������ν���� */
538                   initWarningMesg();
539 
540                   /* �⡼��̾�ν���� */
541                   initModeNames();
542 
543                   /* �����ơ��֥�ν���� */
544                   if (initKeyTables() != NG) {
545 
546                     /* ������ե�������ɤ߹��� */
547 #ifdef BINARY_CUSTOM
548                     binparse();
549 #else
550                     parse();
551 #endif
552 
553                     /* keyconvCallback �� parse ������פʤΤǥ��ꥢ���� */
554                     KC_keyconvCallback(d, (char *)0);
555 
556                     /* �����ط�ʸ����ν���� */
557                     if (initIchiran() != NG) {
558 
559                       /* ���޻������Ѵ��ν���� */
560                       RomkanaInit();
561 
562                       /* ���ʴ����Ѵ��ν���� */
563                       if (ckverbose || !cannaconf.DelayConnect)
564 			KanjiInit();
565                       /* �����Ǥ⥨�顼��̵�뤷�ޤ���
566                          �����ˤʤ�ʤ��Ƥ⤤������ */
567 
568                       if (arg) {
569                       *(char ***)arg = nWarningMesg ? WarningMesg : (char **)0;
570                       }
571                       FirstTime = 0;
572                       return 0;
573                     }
574                     /* uiContext �θ����Τ���Υϥå���ơ��֥���ꥢ
575                        uiContext ����˥ե꡼���� */
576                     clearHashTable();
577 
578                     /* ���������ä� */
579                     freeKeysup();
580 
581                     /* �����ȥ������ޥ�������Ƥ������Ȥ��᤹�� */
582                     restoreBindings();
583 
584                     /* ��ĥ��ǽ��initfileɽ���ѤΥХåե���������� */
585                     freeBuffer();
586 
587 #ifndef NO_EXTEND_MENU
588                     /* ��˥塼��Ϣ�Υ���γ��� */
589                     finExtMenu();
590 #endif
591 
592                     /* �ǥե���Ȱʳ��Υ⡼���ѥ���γ��� */
593                     freeExtra();
594 
595 
596                     /* �����ޥåץơ��֥�Υ��ꥢ */
597                     restoreDefaultKeymaps();
598                   }
599                   /* �⡼��ʸ����Υե꡼ */
600                   resetModeNames();
601 #ifndef NO_EXTEND_MENU
602                 }
603               }
604             }
605           }
606         }
607       }
608     }
609 #endif
610     /* �磻�ɥ���饯���Ѽ�ư��������ν�λ���� */
611     WStringClose();
612 
613     /* ������̾�ݻ��ѥ���γ��� */
614     /* RkSetServerName((char *)0); ���ƤϤ����ʤ��ΤǤϡ� */
615 
616     /* ������Υ����� */
617     close_engine();
618 
619     return -1;
620   }
621   else {
622     /* ����Initialize���Ƥ�����ˤϤ⤦��å�����������ʤ����Ȥˤ��� */
623     if (arg) {
624       *(char ***)arg = (char **)0;
625     }
626     return -1;
627   }
628 }
629 
630 static void
freeKeysup()631 freeKeysup()
632 {
633   int i;
634   extern keySupplement keysup[];
635   extern int nkeysup;
636 
637   for (i = 0 ; i < nkeysup ; i++) {
638     if (keysup[i].cand) {
639       free((char *)keysup[i].cand);
640       keysup[i].cand = (wchar_t **)0;
641     }
642     if (keysup[i].fullword) {
643       free((char *)keysup[i].fullword);
644       keysup[i].fullword = (wchar_t *)0;
645     }
646   }
647   nkeysup = 0;
648 }
649 
650 extern int nothermodes;
651 
652 static void
freeBuffer()653 freeBuffer()
654 {
655   if(CANNA_initfilename) {
656     free(CANNA_initfilename);
657   }
658   CANNA_initfilename = (char *)NULL;
659 }
660 
661 static void
freeExtra()662 freeExtra()
663 {
664   extern extraFunc *extrafuncp;
665   extraFunc *p, *q;
666 
667   for (p = extrafuncp ; p ; p = q) {
668     q = p->next;
669     switch (p->keyword) {
670       case EXTRA_FUNC_DEFMODE:
671         if (p->u.modeptr->romdic_owner &&
672 	    p->u.modeptr->romdic != (struct RkRxDic *)NULL) {
673 	  RkwCloseRoma(p->u.modeptr->romdic);
674 	}
675         free((char *)p->u.modeptr->emode);
676 	if (p->u.modeptr->romaji_table) {
677 	  free((char *)p->u.modeptr->romaji_table);
678 	}
679         free((char *)p->u.modeptr);
680         break;
681       case EXTRA_FUNC_DEFSELECTION:
682         free((char *)p->u.kigoptr->kigo_str);
683         free((char *)p->u.kigoptr->kigo_data);
684         free((char *)p->u.kigoptr);
685         break;
686 #ifndef NO_EXTEND_MENU
687       case EXTRA_FUNC_DEFMENU:
688         freeMenu(p->u.menuptr);
689         break;
690 #endif
691     }
692     free((char *)p);
693   }
694   extrafuncp = (extraFunc *)0;
695 }
696 
697 static
KC_finalize(d,arg)698 KC_finalize(d, arg)
699      uiContext d;
700      char *arg;
701      /* ARGSUSED */
702 {
703   extern FirstTime;
704   int res;
705 
706   /* �������˥���å������ν���� */
707   initWarningMesg();
708   if (arg) {
709     *(char ***)arg = 0;
710   }
711 
712   if (FirstTime) {
713     jrKanjiError = "\275\351\264\374\262\275\244\342\244\265\244\354\244\306"
714 	"\244\244\244\312\244\244\244\316\244\313\241\330\275\252\244\357"
715 	"\244\354\241\331\244\310\270\300\244\357\244\354\244\336\244\267"
716 	"\244\277";
717                    /* ������⤵��Ƥ��ʤ��Τˡؽ����٤ȸ����ޤ��� */
718     return -1;
719   }
720   else {
721     FirstTime = 1;
722 
723     /* ���ʴ����Ѵ��ν�λ */
724     res = KanjiFin();
725 
726     /* ���޻������Ѵ��ν�λ */
727     RomkanaFin();
728 
729     /* free all uiContexts and hash tables here */
730 
731     /* �����ޥåץơ��֥�Υ��ꥢ */
732     restoreDefaultKeymaps();
733 
734     /* �⡼��ʸ����Υե꡼ */
735     resetModeNames();
736 
737     /* uiContext �θ����Τ���Υϥå���ơ��֥���ꥢ
738        uiContext ����˥ե꡼���� */
739     clearHashTable();
740 
741     /* ���������ä� */
742     freeKeysup();
743 
744     /* �����ȥ������ޥ�������Ƥ������Ȥ��᤹�� */
745     restoreBindings();
746 
747     /* ��ĥ��ǽ��initfileɽ���ѤΥХåե���������� */
748     freeBuffer();
749 
750     /* �磻�ɥ���饯���Ѽ�ư��������ν�λ���� */
751     WStringClose();
752 
753     /* ������̾�ݻ��ѥ���γ��� */
754     /* RkSetServerName((char *)0); ���ƤϤ����ʤ��ΤǤϡ� */
755 
756 #ifndef NO_EXTEND_MENU
757     /* ��˥塼��Ϣ�Υ���γ��� */
758     finExtMenu();
759 #endif
760 
761     /* �ǥե���Ȱʳ��Υ⡼���ѥ���γ��� */
762     freeExtra();
763 
764     /* ������Υ����� */
765     close_engine();
766 
767     if (arg) {
768       *(char ***)arg = nWarningMesg ? WarningMesg : (char **)0;
769     }
770     return res;
771   }
772 }
773 
774 static
KC_setWidth(d,arg)775 KC_setWidth(d, arg)
776 uiContext d;
777 caddr_t arg;
778 {
779   d->ncolumns = (int)(POINTERINT)arg;
780   return 0;
781 }
782 
783 static
KC_setBunsetsuKugiri(d,arg)784 KC_setBunsetsuKugiri(d, arg)
785      uiContext d;
786      caddr_t arg;
787      /* ARGSUSED */
788 {
789   cannaconf.BunsetsuKugiri = (int)(POINTERINT)arg;
790   return 0;
791 }
792 
793 #define CHANGEBUFSIZE 1024
794 
795 static long gflags[] = {
796   0L,
797   CANNA_YOMI_BASE_HANKAKU,
798   CANNA_YOMI_KATAKANA,
799   CANNA_YOMI_KATAKANA | CANNA_YOMI_HANKAKU | CANNA_YOMI_BASE_HANKAKU,
800   CANNA_YOMI_ROMAJI | CANNA_YOMI_ZENKAKU,
801   CANNA_YOMI_ROMAJI | CANNA_YOMI_BASE_HANKAKU,
802   CANNA_YOMI_KAKUTEI,
803   CANNA_YOMI_BASE_HANKAKU | CANNA_YOMI_KAKUTEI,
804   CANNA_YOMI_KATAKANA | CANNA_YOMI_KAKUTEI,
805   CANNA_YOMI_KATAKANA | CANNA_YOMI_HANKAKU | CANNA_YOMI_BASE_HANKAKU |
806     CANNA_YOMI_KAKUTEI,
807   CANNA_YOMI_ROMAJI | CANNA_YOMI_ZENKAKU | CANNA_YOMI_KAKUTEI,
808   CANNA_YOMI_ROMAJI | CANNA_YOMI_BASE_HANKAKU | CANNA_YOMI_KAKUTEI,
809 };
810 
811 static
KC_changeMode(d,arg)812 KC_changeMode(d, arg)
813 uiContext d;
814 wcKanjiStatusWithValue *arg;
815 {
816   coreContext cc;
817   yomiContext yc;
818 
819   d->buffer_return = arg->buffer;
820   d->n_buffer = arg->n_buffer;
821   d->kanji_status_return = arg->ks;
822 
823   bzero(d->kanji_status_return, sizeof(wcKanjiStatus));
824 
825   d->nbytes = escapeToBasicStat(d, CANNA_FN_Quit);
826   cc = (coreContext)d->modec;
827   d->kanji_status_return->info &= ~(KanjiThroughInfo | KanjiEmptyInfo);
828 
829   if (cc->majorMode == CANNA_MODE_AlphaMode) {
830     /* ���⡼�ɤ��ä���ȴ���롣
831        �١����å��⡼�ɤϦ��⡼�ɤ��Ѵ��⡼�ɤ��餤�����ʤ��Ȼפ��� */
832     if (arg->val == CANNA_MODE_AlphaMode) {
833       return 0;
834     }
835     else {
836       cc = (coreContext)cc->next; /* ���Υ���ƥ����� */
837       yc = (yomiContext)cc;
838 
839       if (yc->generalFlags & CANNA_YOMI_CHGMODE_INHIBITTED) {
840 	CannaBeep();
841 	arg->val = 0;
842 	return 0;
843       }
844 
845       doFunc(d, CANNA_FN_JapaneseMode);
846     }
847   }
848   else {
849     yc = (yomiContext)cc;
850 
851     if (yc->generalFlags & CANNA_YOMI_CHGMODE_INHIBITTED) {
852       CannaBeep();
853       arg->val = 0;
854       return 0;
855     }
856   }
857 
858   switch (arg->val) {
859   case CANNA_MODE_AlphaMode:
860     arg->val = doFunc(d, CANNA_FN_AlphaMode);
861     return 0;
862 
863   case CANNA_MODE_HenkanMode:
864     arg->val = doFunc(d, CANNA_FN_HenkanNyuryokuMode);
865     return 0;
866 
867 #ifndef NO_EXTEND_MENU
868   case CANNA_MODE_HexMode:
869     arg->val = doFunc(d, CANNA_FN_HexMode);
870     return 0;
871 #endif /* not NO_EXTEND_MENU */
872 
873   case CANNA_MODE_BushuMode:
874     arg->val = doFunc(d, CANNA_FN_BushuMode);
875     return 0;
876 
877   case CANNA_MODE_KigoMode:
878     arg->val = doFunc(d, CANNA_FN_KigouMode);
879     return 0;
880 
881   case CANNA_MODE_TourokuMode:
882     arg->val = doFunc(d, CANNA_FN_ExtendMode);
883     return 0;
884 
885   case CANNA_MODE_HanKataHenkanMode:
886   case CANNA_MODE_HanKataKakuteiMode:
887     if (cannaconf.InhibitHankakuKana) {
888       CannaBeep();
889       arg->val = 0;
890       return 0;
891     }
892   case CANNA_MODE_ZenHiraHenkanMode:
893   case CANNA_MODE_HanHiraHenkanMode:
894   case CANNA_MODE_ZenKataHenkanMode:
895   case CANNA_MODE_ZenAlphaHenkanMode:
896   case CANNA_MODE_HanAlphaHenkanMode:
897   case CANNA_MODE_ZenHiraKakuteiMode:
898   case CANNA_MODE_HanHiraKakuteiMode:
899   case CANNA_MODE_ZenKataKakuteiMode:
900   case CANNA_MODE_ZenAlphaKakuteiMode:
901   case CANNA_MODE_HanAlphaKakuteiMode:
902     yc->generalFlags &= ~(CANNA_YOMI_ATTRFUNCS | CANNA_YOMI_BASE_HANKAKU);
903     yc->generalFlags |= gflags[arg->val - CANNA_MODE_ZenHiraHenkanMode];
904     EmptyBaseModeInfo(d, yc);
905     arg->val = 0;
906     return 0;
907   default:
908     return(-1);
909   }
910   /* NOTREACHED */
911 }
912 
913 static
baseModeP(d)914 baseModeP(d)
915 uiContext d;
916 {
917   extern KanjiModeRec alpha_mode, empty_mode;
918 
919   return (d->current_mode == &alpha_mode) ||
920     (d->current_mode == &empty_mode
921      && ((yomiContext)(d->modec))->next == (mode_context)0);
922 }
923 
924 /*
925 
926   ����Ū�ʾ��֤ˤ�ɤ롣���ʤ�����ɤߤ����äƤ������Ѵ���ξ��֤���ȴ
927   ���롣������ȴ���뤫���裲�����ǻ��ꤹ�롣ȴ�����Ȥ��Ƥ�
928 
929   ��QUIT (C-g) ��ȴ����
930   ������ (Return) ��ȴ����
931 
932   �����롣
933 
934 */
935 
escapeToBasicStat(d,how)936 escapeToBasicStat(d, how)
937 uiContext d;
938 int how;
939 {
940   int len = 0, totallen = 0;
941   wchar_t *p = d->buffer_return;
942   int totalinfo = 0;
943   int maxcount = 32;
944 
945   do {
946     if(d->kanji_status_return) {
947       d->kanji_status_return->length = 0;
948       totalinfo |= (d->kanji_status_return->info & KanjiModeInfo);
949     }
950     else {
951       return -1;
952     }
953     d->kanji_status_return->info = 0;
954     d->nbytes = 0; /* �����ͤ�����ʸ��Ĺ�Ȥ��ƻȤ���礬����Τǥ��ꥢ���� */
955     len = doFunc(d, how);
956     d->buffer_return += len;
957     d->n_buffer -= len;
958     totallen += len;
959     maxcount--;
960   } while (maxcount > 0 && !baseModeP(d));
961   d->kanji_status_return->info |= KanjiGLineInfo | totalinfo;
962   d->kanji_status_return->gline.length = 0;
963   d->kanji_status_return->gline.revPos = 0;
964   d->kanji_status_return->gline.revLen = 0;
965   d->buffer_return = p;
966   return totallen;
967 }
968 
969 static
KC_setUFunc(d,arg)970 KC_setUFunc(d, arg)
971      uiContext d;
972      caddr_t arg;
973      /* ARGSUSED */
974 {
975   extern howToBehaveInCaseOfUndefKey;
976 
977   howToBehaveInCaseOfUndefKey = (int)(POINTERINT)arg;
978   return 0;
979 }
980 
981 static
KC_setModeInfoStyle(d,arg)982 KC_setModeInfoStyle(d, arg)
983      uiContext d;
984      caddr_t arg;
985      /* ARGSUSED */
986 {
987   int	tmpval;
988   extern howToReturnModeInfo;
989 
990   if ((tmpval = (int)(POINTERINT)arg) < 0 || tmpval > MaxModeInfoStyle)
991     return(-1);
992   howToReturnModeInfo = (int)(POINTERINT)arg;
993   return 0;
994 }
995 
996 static
KC_setHexInputStyle(d,arg)997 KC_setHexInputStyle(d, arg)
998      uiContext d;
999      caddr_t arg;
1000      /* ARGSUSED */
1001 {
1002   cannaconf.hexCharacterDefiningStyle = (int)(POINTERINT)arg;
1003   return 0;
1004 }
1005 
1006 static
KC_inhibitHankakuKana(d,arg)1007 KC_inhibitHankakuKana(d, arg)
1008      uiContext d;
1009      caddr_t arg;
1010      /* ARGSUSED */
1011 {
1012   cannaconf.InhibitHankakuKana = (int)(POINTERINT)arg;
1013   return 0;
1014 }
1015 
1016 #ifndef NO_EXTEND_MENU
1017 extern void popTourokuMode pro((uiContext));
1018 
1019 static
popTourokuWithGLineClear(d,retval,env)1020 popTourokuWithGLineClear(d, retval, env)
1021      uiContext d;
1022      int retval;
1023      mode_context env;
1024      /* ARGSUSED */
1025 {
1026   tourokuContext tc;
1027 
1028   popCallback(d); /* �ɤߤ� pop */
1029 
1030   tc = (tourokuContext)d->modec;
1031   if (tc->udic) {
1032     free(tc->udic);
1033   }
1034   popTourokuMode(d);
1035   popCallback(d);
1036   GlineClear(d);
1037   currentModeInfo(d);
1038   return 0;
1039 }
1040 #endif
1041 
1042 static
KC_defineKanji(d,arg)1043 KC_defineKanji(d, arg)
1044 uiContext d;
1045 wcKanjiStatusWithValue *arg;
1046 {
1047 #ifdef NO_EXTEND_MENU
1048   return 0;
1049 #else
1050   d->buffer_return = arg->buffer;
1051   d->n_buffer = arg->n_buffer;
1052   d->kanji_status_return = arg->ks;
1053 
1054   if(arg->ks->length > 0 && arg->ks->echoStr && arg->ks->echoStr[0]) {
1055     wchar_t xxxx[ROMEBUFSIZE]; /* BIGARRAY */
1056 
1057     WStrncpy(xxxx, arg->ks->echoStr, arg->ks->length);
1058     xxxx[arg->ks->length] = (wchar_t)0;
1059 
1060     bzero(d->kanji_status_return, sizeof(wcKanjiStatus));
1061 
1062     d->nbytes = escapeToBasicStat(d, CANNA_FN_Quit);
1063     d->kanji_status_return->info &= ~(KanjiThroughInfo | KanjiEmptyInfo);
1064     dicTourokuControl(d, xxxx, popTourokuWithGLineClear);
1065     arg->val = d->nbytes;
1066   } else {
1067     d->nbytes = escapeToBasicStat(d, CANNA_FN_Quit);
1068     d->kanji_status_return->info &= ~(KanjiThroughInfo | KanjiEmptyInfo);
1069     arg->val = dicTourokuControl(d, 0, popTourokuWithGLineClear);
1070   }
1071   arg->val = callCallback(d, arg->val);
1072 
1073   return 0;
1074 #endif /* NO_EXTEND_MENU */
1075 }
1076 
1077 
1078 /* cfuncdef
1079 
1080   RK ����ƥ����Ȥ�̵���ˤ��롣
1081   flag �����ʳ��ʤ� RkwClose() ��Ԥ���
1082 
1083  */
1084 
1085 static void
closeRK(cxp,flag)1086 closeRK(cxp, flag)
1087 int *cxp;
1088 int flag;
1089 {
1090   if (flag && *cxp >= 0) {
1091     RkwCloseContext(*cxp);
1092   }
1093   *cxp = -1;
1094 }
1095 
1096 /* cfuncdef
1097 
1098    closeRKContextInUIContext -- uiContext ��� RK ����ƥ����Ȥ� close ���롣
1099 
1100  */
1101 
1102 static void closeRKContextInUIContext pro((uiContext, int));
1103 
1104 static void
closeRKContextInUIContext(d,flag)1105 closeRKContextInUIContext(d, flag)
1106 uiContext d;
1107 int flag; /* ���ʳ��ʤ饯�����⤹�롣 */
1108 {
1109   coreContext cc;
1110 
1111   closeRK(&(d->contextCache), flag);
1112   for (cc = (coreContext)d->modec ; cc ; cc = (coreContext)cc->next) {
1113     if (cc->id == YOMI_CONTEXT) {
1114       closeRK(&(((yomiContext)cc)->context), flag);
1115     }
1116   }
1117 }
1118 
1119 /* cfuncdef
1120 
1121   closeRKContextInMemory() -- ���٤Ƥ� RK ����ƥ����ȤΥ�����
1122 
1123   �Х��åȤˤ�äƥݥ���Ȥ���Ƥ���ǡ���������Ƥ� RK ����ƥ����Ȥ�
1124   ���������롣
1125 
1126 */
1127 
1128 static void
closeRKContextInMemory(p,flag)1129 closeRKContextInMemory(p, flag)
1130 struct bukRec *p;
1131 int flag;
1132 {
1133 
1134   while (p) { /* reconfirm that p points some structure */
1135     closeRKContextInUIContext(p->context, flag);
1136     p = p->next;
1137   }
1138 }
1139 
1140 /* cfuncdef
1141 
1142   makeContextToBeClosed() -- �ϥå���ơ��֥���Υ���ƥ����Ȥ�̵���ˤ���
1143 
1144 */
1145 
1146 void
makeAllContextToBeClosed(flag)1147 makeAllContextToBeClosed(flag)
1148 int flag;
1149 {
1150   int i;
1151   struct bukRec *p;
1152 
1153   for (i = 0 ; i < HASHTABLESIZE ; i++) {
1154     p = conHash[i];
1155     if (p) {
1156       closeRKContextInMemory(p, flag);
1157     }
1158   }
1159 }
1160 
1161 static
KC_kakutei(d,arg)1162 KC_kakutei(d, arg)
1163 uiContext d;
1164 wcKanjiStatusWithValue *arg;
1165 {
1166   d->buffer_return = arg->buffer;
1167   d->n_buffer = arg->n_buffer;
1168   d->kanji_status_return = arg->ks;
1169 
1170   bzero(d->kanji_status_return, sizeof(wcKanjiStatus));
1171 
1172   d->nbytes = escapeToBasicStat(d, CANNA_FN_Kakutei);
1173   if ( !baseModeP(d) ) {
1174     d->nbytes = escapeToBasicStat(d, CANNA_FN_Quit);
1175   }
1176   d->kanji_status_return->info &= ~KanjiThroughInfo;
1177   arg->val = d->nbytes;
1178   return d->nbytes;
1179 }
1180 
1181 static
KC_kill(d,arg)1182 KC_kill(d, arg)
1183 uiContext d;
1184 wcKanjiStatusWithValue *arg;
1185 {
1186   d->buffer_return = arg->buffer;
1187   d->n_buffer = arg->n_buffer;
1188   d->kanji_status_return = arg->ks;
1189 
1190   bzero(d->kanji_status_return, sizeof(wcKanjiStatus));
1191 
1192   d->nbytes = escapeToBasicStat(d, CANNA_FN_Quit);
1193   d->kanji_status_return->info &= ~KanjiThroughInfo;
1194   arg->val = d->nbytes;
1195   return d->nbytes;
1196 }
1197 
1198 static
KC_modekeys(d,arg)1199 KC_modekeys(d, arg)
1200 uiContext d;
1201 unsigned char *arg;
1202 {
1203   int n = 0;
1204   int i;
1205   extern KanjiModeRec alpha_mode;
1206   int func;
1207 
1208   for (i = 0 ; i < 256 ; i++) {
1209     func = alpha_mode.keytbl[i];
1210     if (func != CANNA_FN_SelfInsert &&
1211 	func != CANNA_FN_FunctionalInsert &&
1212 	func != CANNA_FN_Undefined &&
1213 	func != CANNA_FN_FuncSequence &&
1214 	func != CANNA_FN_UseOtherKeymap	&&
1215 	alpha_mode.func(d, &alpha_mode, KEY_CHECK, 0/*dummy*/, func)) {
1216       arg[n++] = i;
1217     }
1218   }
1219   return n;
1220 }
1221 
1222 static
KC_queryMode(d,arg)1223 KC_queryMode(d, arg)
1224 uiContext d;
1225 wchar_t *arg;
1226 {
1227   return queryMode(d, arg);
1228 }
1229 
1230 static
KC_queryConnection(d,arg)1231 KC_queryConnection(d, arg)
1232      uiContext d;
1233      unsigned char *arg;
1234      /* ARGSUSED */
1235 {
1236   extern defaultContext;
1237 
1238   if (defaultContext != -1) {
1239     return 1;
1240   }
1241   else {
1242     return 0;
1243   }
1244 }
1245 
1246 static
KC_setServerName(d,arg)1247 KC_setServerName(d, arg)
1248      uiContext d;
1249      unsigned char *arg;
1250      /* ARGSUSED */
1251 {
1252   return RkSetServerName((char *)arg);
1253 }
1254 
1255 static
KC_parse(d,arg)1256 KC_parse(d, arg)
1257      uiContext d;
1258      char **arg;
1259      /* ARGSUSED */
1260 {
1261   initWarningMesg();
1262 
1263   parse_string(*arg);
1264 
1265   *(char ***)arg = nWarningMesg ? WarningMesg : (char **)0;
1266 
1267   return nWarningMesg;
1268 }
1269 
1270 int yomiInfoLevel = 0;
1271 
1272 static
KC_yomiInfo(d,arg)1273 KC_yomiInfo(d, arg)
1274      uiContext d;
1275      int arg;
1276      /* ARGSUSED */
1277 {
1278   yomiInfoLevel = arg;
1279   return 0;
1280 }
1281 
1282 static
KC_storeYomi(d,arg)1283 KC_storeYomi(d, arg)
1284 uiContext d;
1285 wcKanjiStatusWithValue *arg;
1286 {
1287   extern KanjiModeRec yomi_mode, cy_mode;
1288   coreContext cc;
1289   wchar_t *p, *q;
1290   int len = 0;
1291 #ifndef USE_MALLOC_FOR_BIG_ARRAY
1292   wchar_t buf[2048];
1293 #else
1294   wchar_t *buf = (wchar_t *)malloc(sizeof(wchar_t) * 2048);
1295   if (!buf) {
1296     /* This should the 'no more memory' message on the guide line... */
1297     arg->val = 0;
1298     arg->ks->length = 0;
1299     arg->ks->info = 0;
1300     return len;
1301   }
1302 #endif
1303 
1304   p = arg->ks->echoStr;
1305   q = arg->ks->mode;
1306   if (p) {
1307     WStrcpy(buf, p);
1308     p = buf;
1309     len = WStrlen(buf);
1310   }
1311   if (q) {
1312     WStrcpy(buf + len + 1, q);
1313     q = buf + len + 1;
1314   }
1315   KC_kill(d, arg);
1316   cc = (coreContext)d->modec;
1317   if (cc->majorMode == CANNA_MODE_AlphaMode) {
1318     doFunc(d, CANNA_FN_JapaneseMode);
1319   }
1320   d->kanji_status_return = arg->ks;
1321   d->kanji_status_return->info &= ~(KanjiThroughInfo | KanjiEmptyInfo);
1322   RomajiStoreYomi(d, p, q);
1323   if (p && *p) {
1324     d->current_mode =
1325       (((yomiContext)d->modec)->generalFlags & CANNA_YOMI_CHIKUJI_MODE)
1326 	? &cy_mode : &yomi_mode;
1327   }
1328   makeYomiReturnStruct(d);
1329   arg->val = 0;
1330 #ifdef USE_MALLOC_FOR_BIG_ARRAY
1331   (void)free((char *)buf);
1332 #endif
1333   return 0;
1334 }
1335 
1336 char *initFileSpecified = (char *)NULL;
1337 
1338 static
KC_setInitFileName(d,arg)1339 KC_setInitFileName(d, arg)
1340      uiContext d;
1341      char *arg;
1342      /* ARGSUSED */
1343 {
1344   int len;
1345 
1346   if (initFileSpecified) { /* �����Τ�Τ�ե꡼���� */
1347     free(initFileSpecified);
1348   }
1349 
1350   if ( arg && *arg ) {
1351     len = strlen(arg);
1352     initFileSpecified = malloc(len + 1);
1353     if (initFileSpecified) {
1354       strcpy(initFileSpecified, arg);
1355     }
1356     else {
1357       return -1;
1358     }
1359   }
1360   else {
1361     initFileSpecified = (char *)NULL;
1362   }
1363   return 0;
1364 }
1365 
1366 static
KC_do(d,arg)1367 KC_do(d, arg)
1368 uiContext d;
1369 wcKanjiStatusWithValue *arg;
1370 {
1371   d->buffer_return = arg->buffer;
1372   d->n_buffer = arg->n_buffer;
1373   d->kanji_status_return = arg->ks;
1374   d->ch = (unsigned)*(d->buffer_return);
1375   d->nbytes = 1;
1376 
1377   bzero(d->kanji_status_return, sizeof(wcKanjiStatus));
1378 
1379   arg->val = doFunc(d, arg->val);
1380   return arg->val;
1381 }
1382 
1383 #ifndef NO_EXTEND_MENU
1384 /*
1385 
1386   �ȥåץ�٥�ˤϤʤ��⡼�ɤ��Ф��Ʋ��餫�κ�Ȥ�
1387   ���������Ȥ��˸ƤӽФ��ؿ���fnum == 0 �� d->ch ���롣
1388 
1389   '91.12.28 ���ߤ� uldefine.c ���餷���ƤФ�Ƥ��餺 modec ���ͤ�
1390   yomi_mode �������äƤ��ʤ���
1391 
1392   ���δؿ��Ϥ�����ǸƤִؿ��ˤ�äƥ⡼�ɤ��ץå��夵�줿���ʤ�������
1393   ���뤳�Ȥ�����ʤ��ʤäƤ��ޤ��Τǥ⡼���ѹ���ȼ����ǽ�θƽФ�����
1394   Ū�˶ػߤ��뤳�ȤȤ��롣
1395 
1396  */
1397 
_do_func_slightly(d,fnum,mode_c,c_mode)1398 _do_func_slightly(d, fnum, mode_c, c_mode)
1399 uiContext d;
1400 int fnum;
1401 mode_context mode_c;
1402 KanjiMode c_mode;
1403 {
1404   wcKanjiStatus ks;
1405   long gfback;
1406   BYTE inhback;
1407   int retval;
1408   yomiContext yc = (yomiContext)0;
1409 #ifndef USE_MALLOC_FOR_BIG_ARRAY
1410   uiContextRec f, *e = &f;
1411 #else
1412   uiContext e = (uiContext)malloc(sizeof(uiContextRec));
1413 
1414   if (e) {
1415 #endif
1416 
1417   bzero(e, sizeof(uiContextRec));
1418   e->buffer_return = e->genbuf;
1419   e->n_buffer = ROMEBUFSIZE;
1420   e->kanji_status_return = &ks;
1421 
1422   e->nbytes = d->nbytes;
1423   e->ch     = d->ch;
1424 
1425   e->status = 0; /* �⡼�ɤˤĤ���"������"�Υ��ơ�����������ͤȤ��� */
1426   e->more.todo = 0;
1427   e->modec = mode_c;
1428   e->current_mode = c_mode;
1429   e->cb = (struct callback *)0;
1430 
1431   if (((coreContext)mode_c)->id == YOMI_CONTEXT) {
1432     yc = (yomiContext)mode_c;
1433     gfback = yc->generalFlags;
1434     inhback = yc->henkanInhibition;
1435     yc->generalFlags |= CANNA_YOMI_CHGMODE_INHIBITTED;
1436     yc->henkanInhibition |= CANNA_YOMI_INHIBIT_ALL;
1437   }
1438 
1439   retval = (*c_mode->func)(e, c_mode, KEY_CALL, e->ch, fnum);
1440 
1441   if (yc) {
1442     yc->generalFlags = gfback;
1443     yc->henkanInhibition = inhback;
1444   }
1445 #ifdef USE_MALLOC_FOR_BIG_ARRAY
1446     (void)free((char *)e);
1447   }
1448 #endif
1449   return retval;
1450 }
1451 
1452 #endif
1453 
1454 static
callCallback(d,res)1455 callCallback(d, res)  /* ������Хå���Ƥ� */
1456 uiContext d;
1457 int res;
1458 {
1459   struct callback *cbp;
1460 
1461   for (cbp = d->cb; cbp ;) {
1462     int index;
1463     int (*callbackfunc) pro((uiContext, int, mode_context));
1464 
1465     index = d->status;
1466     d->status = 0; /* Callback ���ʤ��Ƥ� EXIT��QUIT��AUX �ϥ��ꥢ���� */
1467     callbackfunc = cbp->func[index];
1468     if (callbackfunc) {
1469       d->kanji_status_return->info &= ~KanjiEmptyInfo;
1470       if (index) { /* everytime �ʳ� */
1471 	res = (*callbackfunc)(d, res, cbp->env);
1472 	cbp = d->cb; /* ������Хå��ؿ��ˤ�ꥳ����Хå���
1473 			�ƤӽФ����Τ�ٱ礹�뤿������ľ�� */
1474 	/* �����ǥ�����Хå��ؿ���ݥåץ��åפ��褦���ɤ����ͤ��ɤ��� */
1475 	continue;
1476       }
1477       else {
1478 	res = (*callbackfunc)(d, res, cbp->env);
1479       }
1480     }
1481     cbp = cbp->next;
1482   }
1483   return res;
1484 }
1485 
_doFunc(d,fnum)1486 _doFunc(d, fnum)
1487 uiContext d;
1488 int fnum;
1489 {
1490   int res = 0, tmpres, ginfo = 0;
1491   int reallyThrough = 1;
1492   wchar_t *prevEcho, *prevGEcho;
1493   int prevEchoLen = -1, prevRevPos, prevRevLen;
1494   int prevGEchoLen, prevGRevPos, prevGRevLen;
1495 
1496   d->status = 0; /* �⡼�ɤˤĤ���"������"�Υ��ơ�����������ͤȤ��� */
1497   d->more.todo = 0;
1498   tmpres = d->current_mode->func(d, d->current_mode, KEY_CALL, d->ch, fnum);
1499 
1500   if (d->flags & MULTI_SEQUENCE_EXECUTED) {
1501     d->flags &= ~MULTI_SEQUENCE_EXECUTED;
1502     return tmpres;
1503   }
1504 
1505   /* ������Хå���¹Ԥ��� */
1506   res = tmpres = callCallback(d, tmpres);
1507 
1508   if (d->kanji_status_return->length >= 0) {
1509     prevEcho    = d->kanji_status_return->echoStr;
1510     prevEchoLen = d->kanji_status_return->length;
1511     prevRevPos  = d->kanji_status_return->revPos;
1512     prevRevLen  = d->kanji_status_return->revLen;
1513   }
1514   if (d->kanji_status_return->info & KanjiGLineInfo) {
1515     ginfo = 1;
1516     prevGEcho    = d->kanji_status_return->gline.line;
1517     prevGEchoLen = d->kanji_status_return->gline.length;
1518     prevGRevPos  = d->kanji_status_return->gline.revPos;
1519     prevGRevLen  = d->kanji_status_return->gline.revLen;
1520   }
1521 
1522   /* moreToDo ��¹Ԥ��ʤ��Ƥ� */
1523   while (d->more.todo) {
1524     if (!(d->kanji_status_return->info & KanjiThroughInfo)) {
1525       reallyThrough = 0;
1526     }
1527     d->kanji_status_return->info &= ~(KanjiThroughInfo | KanjiEmptyInfo);
1528     d->more.todo = 0;
1529     d->ch = d->more.ch;	/* moreTodo �� more.ch �Ϥ���ʤ��ΤǤϡ� */
1530     d->nbytes = 1;
1531     d->buffer_return += tmpres;
1532     d->n_buffer -= tmpres;
1533 
1534     {
1535       int check;
1536       /* �����ܰʹߤ˰ʲ��Υǡ����������Ƥ����礬����Τ�����ľ���� */
1537       d->buffer_return[0] = key2wchar(d->ch, &check);
1538       if (!check) {
1539 	d->nbytes = 0;
1540       }
1541     }
1542 
1543     tmpres = _doFunc(d, d->more.fnum);
1544 
1545     if (tmpres >= 0) {
1546       res += tmpres;
1547       if (d->kanji_status_return->length >= 0) {
1548 	prevEcho    = d->kanji_status_return->echoStr;
1549 	prevEchoLen = d->kanji_status_return->length;
1550 	prevRevPos  = d->kanji_status_return->revPos;
1551 	prevRevLen  = d->kanji_status_return->revLen;
1552       }
1553       if (d->kanji_status_return->info & KanjiGLineInfo) {
1554 	ginfo = 1;
1555 	prevGEcho    = d->kanji_status_return->gline.line;
1556 	prevGEchoLen = d->kanji_status_return->gline.length;
1557 	prevGRevPos  = d->kanji_status_return->gline.revPos;
1558 	prevGRevLen  = d->kanji_status_return->gline.revLen;
1559       }
1560     }
1561   }
1562   if (!reallyThrough) {
1563     d->kanji_status_return->info &= ~KanjiThroughInfo;
1564   }
1565 
1566   d->kanji_status_return->length  = prevEchoLen;
1567   if (prevEchoLen >= 0) {
1568     d->kanji_status_return->echoStr = prevEcho;
1569     d->kanji_status_return->revPos  = prevRevPos;
1570     d->kanji_status_return->revLen  = prevRevLen;
1571   }
1572   if (ginfo) {
1573     d->kanji_status_return->gline.line    = prevGEcho;
1574     d->kanji_status_return->gline.length  = prevGEchoLen;
1575     d->kanji_status_return->gline.revPos  = prevGRevPos;
1576     d->kanji_status_return->gline.revLen  = prevGRevLen;
1577     d->kanji_status_return->info |= KanjiGLineInfo;
1578   }
1579 
1580   return res;
1581 }
1582 
_afterDoFunc(d,retval)1583 _afterDoFunc(d, retval)
1584 uiContext d;
1585 int retval;
1586 {
1587   int res = retval;
1588   wcKanjiStatus   *kanji_status_return = d->kanji_status_return;
1589 
1590   /* GLine ��ä��ȸ����Τʤ�ä��ޤ��礦 */
1591   if (d->flags & PLEASE_CLEAR_GLINE) {
1592     if (d->flags & PCG_RECOGNIZED) { /* �����������ʤ� */
1593       if (res >= 0 &&	kanji_status_return->length >= 0) {
1594 	d->flags &= ~(PLEASE_CLEAR_GLINE | PCG_RECOGNIZED);
1595 	   /* ��������ܤ�̤����ޤ��� */
1596 	if (!(kanji_status_return->info & KanjiGLineInfo)) {
1597 	  GlineClear(d);
1598 	}
1599       }
1600     }
1601     else {
1602       d->flags |= PCG_RECOGNIZED;
1603     }
1604   }
1605   return res;
1606 }
1607 
1608 /* cfuncdef
1609 
1610   doFunc -- _doFunc ���ɤ�ǡ������ ClearGLine �����䡢������Хå���
1611             �������롣
1612 
1613  */
1614 
doFunc(d,fnum)1615 doFunc(d, fnum)
1616 uiContext d;
1617 int fnum;
1618 {
1619   return _afterDoFunc(d, _doFunc(d, fnum));
1620 }
1621 
1622 static
KC_getContext(d,arg)1623 KC_getContext(d, arg)
1624      uiContext d;
1625      int arg;
1626      /* ARGSUSED */
1627 {
1628   extern defaultContext, defaultBushuContext;
1629 
1630   switch (arg)
1631     {
1632     case 0:
1633       return RkwDuplicateContext(defaultContext);
1634     case 1:
1635       return RkwDuplicateContext(defaultBushuContext);
1636     case 2:
1637       return defaultContext;
1638     default:
1639       return(-1);
1640     }
1641   /* NOTREACHED */
1642 }
1643 
1644 static
KC_closeUIContext(d,arg)1645 KC_closeUIContext(d, arg)
1646 uiContext d;
1647 wcKanjiStatusWithValue *arg;
1648 {
1649   extern struct ModeNameRecs ModeNames[];
1650   int ret;
1651 
1652   d->buffer_return = arg->buffer;
1653   d->n_buffer = arg->n_buffer;
1654   d->kanji_status_return = arg->ks;
1655 
1656   bzero(d->kanji_status_return, sizeof(wcKanjiStatus));
1657 
1658   if ((d->nbytes = escapeToBasicStat(d, CANNA_FN_Quit)) < 0)
1659     return -1;
1660   d->kanji_status_return->info &= ~KanjiThroughInfo;
1661   arg->val = d->nbytes;
1662   freeRomeStruct(d);
1663 
1664   ret = countContext();
1665 #if defined(DEBUG)
1666   fprintf(stderr, "ret=%d\n", ret);
1667 #endif
1668   return ret;
1669 }
1670 
1671 static yomiContext
getYomiContext(d)1672 getYomiContext(d)
1673 uiContext d;
1674 {
1675   coreContext cc = (coreContext)d->modec;
1676   yomiContext yc;
1677 
1678   switch (cc->id) {
1679   case YOMI_CONTEXT:
1680     yc = (yomiContext)cc;
1681     break;
1682   default:
1683     if (cc->minorMode == CANNA_MODE_AlphaMode) {
1684       yc = (yomiContext)(cc->next);
1685     }
1686     else {
1687       yc = (yomiContext)0;
1688     }
1689     break;
1690   }
1691   return yc;
1692 }
1693 
1694 static
KC_inhibitChangeMode(d,arg)1695 KC_inhibitChangeMode(d, arg)
1696 uiContext d;
1697 int arg;
1698 {
1699   yomiContext yc;
1700 
1701   yc = getYomiContext(d);
1702   if (yc) {
1703     if (arg) {
1704       yc->generalFlags |= CANNA_YOMI_CHGMODE_INHIBITTED;
1705     }
1706     else {
1707       yc->generalFlags &= ~CANNA_YOMI_CHGMODE_INHIBITTED;
1708     }
1709     return 0;
1710   }
1711   else {
1712     return -1;
1713   }
1714 }
1715 
1716 static
KC_letterRestriction(d,arg)1717 KC_letterRestriction(d, arg)
1718 uiContext d;
1719 int arg;
1720 {
1721   yomiContext yc;
1722 
1723   yc = getYomiContext(d);
1724   if (yc) {
1725     yc->allowedChars = arg;
1726     return 0;
1727   }
1728   else {
1729     return -1;
1730   }
1731 }
1732 
1733 static
countColumns(str)1734 countColumns(str)
1735 wchar_t *str;
1736 {
1737   int len = 0;
1738   wchar_t *p;
1739 
1740   if (str) {
1741     for (p = str ; *p ; p++) {
1742       switch (WWhatGPlain(*p)) {
1743       case 0:
1744       case 2:
1745 	len += 1;
1746 	break;
1747       case 1:
1748       case 3:
1749 	len += 2;
1750 	break;
1751       }
1752     }
1753   }
1754   return len;
1755 }
1756 
1757 static
KC_queryMaxModeStr(d,arg)1758 KC_queryMaxModeStr(d, arg)
1759      uiContext d;
1760      int arg;
1761      /* ARGSUSED */
1762 {
1763   int i, maxcolumns = 0, ncols;
1764   extern struct ModeNameRecs ModeNames[];
1765   extern extraFunc *extrafuncp;
1766   extraFunc *ep;
1767 
1768   for (i = 0 ; i < CANNA_MODE_MAX_IMAGINARY_MODE ; i++) {
1769     ncols = countColumns(ModeNames[i].name);
1770     if (ncols > maxcolumns) {
1771       maxcolumns = ncols;
1772     }
1773   }
1774   for (ep = extrafuncp ; ep ; ep = ep->next) {
1775     ncols = countColumns(ep->display_name);
1776     if (ncols > maxcolumns) {
1777       maxcolumns = ncols;
1778     }
1779   }
1780   return maxcolumns;
1781 }
1782 
1783 static int
KC_setListCallback(d,arg)1784 KC_setListCallback(d, arg)
1785 uiContext d;
1786 jrListCallbackStruct *arg;
1787 {
1788   if (cannaconf.iListCB) {
1789     d->client_data = (char *)0;
1790     d->list_func = (int (*) pro((char *, int, wchar_t **, int, int *)))0;
1791     return -1;
1792   }
1793   if (arg->callback_func) {
1794     d->list_func = arg->callback_func;
1795     if (arg->callback_func == &EUCListCallback
1796 #if SUPPORT_OLD_WCHAR
1797 	|| arg->callback_func == &owcListCallback
1798 #endif
1799 	) {
1800       /* arg->client_data�ϥ����å���ˤ���Τ�uiContext�˰��ñۤ� */
1801       d->elistcb = *((const jrEUCListCallbackStruct *)arg->client_data);
1802       d->client_data = (char *)&d->elistcb;
1803     } else {
1804       d->client_data = arg->client_data;
1805     }
1806   }
1807   else {
1808     d->client_data = (char *)0;
1809     d->list_func = (int (*) pro((char *, int, wchar_t **, int, int *)))0;
1810   }
1811   return 0;
1812 }
1813 
1814 static int
KC_setVerbose(d,arg)1815 KC_setVerbose(d, arg)
1816      uiContext d;
1817      int arg;
1818      /* ARGSUSED */
1819 {
1820   extern int ckverbose;
1821 
1822   ckverbose = arg;
1823   return 0;
1824 }
1825 
1826 /* kanjiInitialize ���ʴ����Ѵ��ν���� KC_INITIALIZE�������Ǥ��롣 */
1827 
1828 exp(int)
1829 kanjiInitialize(mes)
1830 char ***mes;
1831 {
1832   return KC_initialize((uiContext)0, (char *)mes);
1833 }
1834 
1835 /* kanjiFinalize KC_FINALIZE�������Ǥ��롣 */
1836 
1837 exp(int)
1838 kanjiFinalize(mes)
1839 char ***mes;
1840 {
1841   return KC_finalize((uiContext)0, (char *)mes);
1842 }
1843 
1844 /* createKanjiContext ����ƥ����Ȥ���������ΤǤ��롣 */
1845 
1846 unsigned char context_table[100] = "";
1847 
1848 exp(int)
createKanjiContext()1849 createKanjiContext()
1850 {
1851   int i;
1852 
1853   for (i = 0; i < 100; i++) {
1854     if (!context_table[i]) {
1855       context_table[i] = 1;
1856       return i;
1857     }
1858   }
1859   return -1; /* ����ƥ����Ȥ�����Ǥ��ʤ��ä��� */
1860 }
1861 
1862 /* wcCloseKanjiContext ����ƥ����Ȥ����������Ρ� */
1863 
1864 exp(int)
1865 wcCloseKanjiContext(context,ksva)
1866 const int context;
1867 wcKanjiStatusWithValue *ksva;
1868 {
1869   context_table[context] = 0;
1870   return  XwcKanjiControl2(0, context, KC_CLOSEUICONTEXT, (BYTE *)ksva);
1871 }
1872 
1873 /* jrCloseKanjiContext ����ƥ����Ȥ����������Ρ� */
1874 
1875 exp(int)
1876 jrCloseKanjiContext(context,ksva)
1877 const int context;
1878 jrKanjiStatusWithValue *ksva;
1879 {
1880   context_table[context] = 0;
1881   return  XKanjiControl2(0, context, KC_CLOSEUICONTEXT, (BYTE *)ksva);
1882 }
1883 
1884 int
ToggleChikuji(d,flg)1885 ToggleChikuji(d, flg)
1886      uiContext d;
1887      int flg;
1888 {
1889   yomiContext	yc = (yomiContext)d->modec;
1890   extern KanjiModeRec empty_mode;
1891   extern struct CannaConfig cannaconf;
1892 
1893   if ((yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) &&
1894       yc->context != -1) {
1895     RkwEndBun(yc->context, 0);
1896     abandonContext(d, yc);
1897   }
1898   (void)escapeToBasicStat(d, CANNA_FN_Kakutei);
1899   d->kanji_status_return->info &= ~KanjiThroughInfo;
1900 
1901   if (flg) {
1902     /* �༡��ư���Ѥ��� */
1903     yc->generalFlags |= CANNA_YOMI_CHIKUJI_MODE;
1904     yc->majorMode = CANNA_MODE_HenkanMode;
1905     cannaconf.chikuji = 1;
1906   }
1907   else {
1908     /* Ϣʸ����Ѥ��� */
1909     yc->generalFlags &= ~CANNA_YOMI_CHIKUJI_MODE;
1910     yc->majorMode = CANNA_MODE_HenkanMode;
1911     cannaconf.chikuji = 0;
1912   }
1913   yc->minorMode = getBaseMode(yc);
1914   d->majorMode = d->minorMode = CANNA_MODE_AlphaMode; /* ���ߡ� */
1915   currentModeInfo(d);
1916   return 0;
1917 }
1918 
1919 static int
KC_lispInteraction(d,arg)1920 KC_lispInteraction(d, arg)
1921 uiContext d;
1922 int arg;
1923 /* ARGSUSED */
1924 {
1925   clisp_main();
1926   return 0;
1927 }
1928 
1929 /*
1930  * �����ФȤ���³���ڤ�
1931  */
1932 static int
KC_disconnectServer(d,arg)1933 KC_disconnectServer(d, arg)
1934 uiContext d;
1935 int arg;
1936 /* ARGSUSED */
1937 {
1938 
1939 #if defined(DEBUG)
1940   fprintf(stderr,"�����ФȤ���³���ڤ�\n");
1941 #endif
1942   jrKanjiPipeError();
1943   return 0;
1944 }
1945 
1946 static int
KC_setAppName(d,arg)1947 KC_setAppName(d, arg)
1948 uiContext d;
1949 unsigned char *arg;
1950 /* ARGSUSED */
1951 {
1952   extern int defaultContext;
1953 
1954   if (strlen((char *)arg) > CANNA_MAXAPPNAME) {
1955     strncpy(saveapname, (char *)arg, CANNA_MAXAPPNAME);
1956     saveapname[CANNA_MAXAPPNAME - 1] = '\0';
1957   }
1958   else {
1959     strcpy(saveapname, (char *)arg);
1960   }
1961   RkwSetAppName(defaultContext, saveapname);
1962 
1963   return(0);
1964 }
1965 
1966 static int
KC_debugmode(d,arg)1967 KC_debugmode(d, arg)
1968 uiContext d;
1969 int arg;
1970 /* ARGSUSED */
1971 {
1972   extern int iroha_debug;
1973 
1974   iroha_debug = arg;
1975   return 0;
1976 }
1977 
1978 static void
debug_yomibuf(yc)1979 debug_yomibuf(yc)
1980 yomiContext yc;
1981 /* ARGSUSED */
1982 {
1983 #if defined(DEBUG)
1984   char kana[1024], roma[1024], ka[1024], ya[1024], *kanap, *romap, *kap, *yap;
1985   int len, i, j, k, maxcol, columns, tmp;
1986   wchar_t xxx[1024];
1987 
1988 #define MANYSPACES "                                                  "
1989 
1990   kanap = kana; romap = roma; kap = ka; yap = ya;
1991 
1992   for (i = 0, j = 0 ; i < yc->kEndp || j < yc->rEndp ;) {
1993     maxcol = 0;
1994 
1995     if (i < yc->kEndp) {
1996       k = i + 1;
1997       columns = 0;
1998       tmp =
1999 	(WIsG0(yc->kana_buffer[i]) || WIsG2(yc->kana_buffer[i])) ? 1 : 2;
2000       if (i == yc->kRStartp && i != yc->kCurs) {
2001 	*kanap++ = '\'';
2002 	*kap++ = '\'';
2003 	columns++;
2004       }
2005       if (yc->kAttr[i] & HENKANSUMI) {
2006 	*kap++ = ' ';
2007       }
2008       else {
2009 	*kap++ = 'x';
2010       }
2011       if (tmp > 1) {
2012 	*kap++ = ' ';
2013       }
2014       columns += tmp;
2015       while (!(yc->kAttr[k] & SENTOU)) {
2016 	tmp = (WIsG0(yc->kana_buffer[k]) || WIsG2(yc->kana_buffer[k])) ? 1 : 2;
2017 	columns += tmp;
2018 	if (yc->kAttr[k] & HENKANSUMI) {
2019 	  *kap++ = ' ';
2020 	}
2021 	else {
2022 	  *kap++ = 'x';
2023 	}
2024 	if (tmp > 1) {
2025 	  *kap++ = ' ';
2026 	}
2027 	k++;
2028       }
2029       WStrncpy(xxx, yc->kana_buffer + i, k - i);
2030       xxx[k - i] = (wchar_t)0;
2031       sprintf(kanap, "%ws ", xxx);
2032       *kap++ = ' ';
2033       len = strlen(kanap);
2034       if (columns > maxcol) {
2035 	maxcol = columns;
2036       }
2037       else {
2038 	strncpy(kanap + len, MANYSPACES, maxcol - columns);
2039 	strncpy(kap, MANYSPACES, maxcol - columns);
2040 	kap += maxcol - columns;
2041 	len += maxcol - columns;
2042       }
2043       kanap += len;
2044       i = k;
2045     }
2046 
2047     if (j < yc->rEndp) {
2048       k = j + 1;
2049       columns =
2050 	(WIsG0(yc->romaji_buffer[j]) || WIsG2(yc->romaji_buffer[j])) ? 1 : 2;
2051       if (j == yc->rStartp && j != yc->rCurs) {
2052 	*romap++ = '\'';
2053 	columns++;
2054       }
2055       while (!(yc->rAttr[k] & SENTOU)) {
2056 	columns +=
2057 	  (WIsG0(yc->romaji_buffer[k]) || WIsG2(yc->romaji_buffer[k])) ? 1 : 2;
2058 	k++;
2059       }
2060       WStrncpy(xxx, yc->romaji_buffer + j, k - j);
2061       xxx[k - j] = (wchar_t)0;
2062       sprintf(romap, "%ws ", xxx);
2063       len = strlen(romap);
2064       if (columns > maxcol) {
2065 	strncpy(kanap, MANYSPACES, columns - maxcol);
2066 	kanap += columns - maxcol;
2067 	strncpy(kap, MANYSPACES, columns - maxcol);
2068 	kap += columns - maxcol;
2069 	maxcol = columns;
2070       }
2071       else {
2072 	strncpy(romap + len, MANYSPACES, maxcol - columns);
2073 	len += maxcol - columns;
2074       }
2075       romap += len;
2076       j = k;
2077     }
2078   }
2079   *kap = *kanap = *romap = '\0';
2080   printf("%s\n", roma);
2081   printf("%s\n", kana);
2082   printf("%s\n", ka);
2083 #endif /* DEBUG */
2084 }
2085 
2086 static int
KC_debugyomi(d,arg)2087 KC_debugyomi(d, arg)
2088 uiContext d;
2089 int arg;
2090 /* ARGSUSED */
2091 {
2092   if (((coreContext)(d)->modec)->id == YOMI_CONTEXT) {
2093     debug_yomibuf((yomiContext)d->modec);
2094   }
2095   return 0;
2096 }
2097 
2098 static int
KC_queryPhono(d,arg)2099 KC_queryPhono(d, arg)
2100 uiContext d;
2101 char *arg;
2102 /* ARGSUSED */
2103 {
2104   extern struct RkRxDic *romajidic;
2105   struct RkRxDic **foo = (struct RkRxDic **)arg;
2106 
2107   *foo = romajidic;
2108   return 0;
2109 }
2110 
2111 static int
KC_changeServer(d,arg)2112 KC_changeServer(d, arg)
2113 uiContext d;
2114 char *arg;
2115 /* ARGSUSED */
2116 {
2117   extern defaultContext;
2118   char *p;
2119 
2120   if (!arg) {
2121     RkSetServerName((char *)0);
2122     return 0;
2123   }
2124 
2125   jrKanjiPipeError();
2126   if (RkSetServerName((char *)arg) && (p = index((char *)arg, '@'))) {
2127 #ifndef USE_MALLOC_FOR_BIG_ARRAY
2128     char xxxx[512];
2129 #else
2130     char *xxxx = malloc(512);
2131     if (!xxxx) {
2132       return 0;
2133     }
2134 #endif
2135 
2136     *p = '\0';
2137 #ifndef CODED_MESSAGE
2138     sprintf(xxxx, "���ʴ����Ѵ������� %s �����ѤǤ��ޤ���", (char *)arg);
2139 #else
2140     sprintf(xxxx, "\244\253\244\312\264\301\273\372\312\321\264\271\245\250\245\363\245\270\245\363 %s \244\317\315\370\315\321\244\307\244\255\244\336\244\273\244\363\n",
2141 	    (char *)arg);
2142 #endif
2143     makeGLineMessageFromString(d, xxxx);
2144 
2145     RkSetServerName((char *)0);
2146 #ifdef USE_MALLOC_FOR_BIG_ARRAY
2147     (void)free(xxxx);
2148 #endif
2149     return 0;
2150   }
2151 
2152   if (defaultContext == -1) {
2153     if ((KanjiInit() != 0) || (defaultContext == -1)) {
2154 #ifndef CODED_MESSAGE
2155       jrKanjiError = "���ʴ����Ѵ������Ф��̿��Ǥ��ޤ���";
2156 #else
2157       jrKanjiError = "\244\253\244\312\264\301\273\372\312\321\264\271"
2158                      "\245\265\241\274\245\320\244\310\304\314\277\256"
2159                      "\244\307\244\255\244\336\244\273\244\363";
2160 #endif
2161       return 0;
2162     }
2163   }
2164   return (int)RkwGetServerName();
2165 }
2166 
2167 static int
KC_setUserInfo(d,arg)2168 KC_setUserInfo(d, arg)
2169 uiContext d;
2170 jrUserInfoStruct *arg;
2171 /* ARGSUSED */
2172 {
2173   extern jrUserInfoStruct *uinfo;
2174   int ret = -1;
2175   char *uname, *gname, *srvname, *topdir, *cannafile, *romkanatable;
2176 #ifndef USE_MALLOC_FOR_BIG_ARRAY
2177   char buf[256];
2178 #else
2179   char *buf = malloc(256);
2180   if (!buf) {
2181     return -1;
2182   }
2183 #endif
2184 
2185   if (arg) {
2186     uname = arg->uname ? strdup(arg->uname) : (char *)0;
2187     if (uname || !arg->uname) {
2188       gname = arg->gname ? strdup(arg->gname) : (char *)0;
2189       if (gname || !arg->gname) {
2190         srvname = arg->srvname ? strdup(arg->srvname) : (char *)0;
2191         if (srvname || !arg->srvname) {
2192 	  topdir = arg->topdir ? strdup(arg->topdir) : (char *)0;
2193           if (topdir || !arg->topdir) {
2194 	    cannafile = arg->cannafile ? strdup(arg->cannafile) : (char *)0;
2195             if (cannafile || !arg->cannafile) {
2196               romkanatable =
2197 		arg->romkanatable ? strdup(arg->romkanatable) : (char *)0;
2198               if (romkanatable || !arg->romkanatable) {
2199                 uinfo = (jrUserInfoStruct *)malloc(sizeof(jrUserInfoStruct));
2200                 if (uinfo) {
2201                   uinfo->uname = uname;
2202                   uinfo->gname = gname;
2203                   uinfo->srvname = srvname;
2204                   uinfo->topdir = topdir;
2205                   uinfo->cannafile = cannafile;
2206                   uinfo->romkanatable = romkanatable;
2207 
2208                   if (uinfo->srvname) {
2209 		    KC_setServerName(d, (unsigned char *)uinfo->srvname);
2210 		  }
2211                   if (uinfo->cannafile) {
2212                     char *p = uinfo->cannafile;
2213 
2214                     if (strlen(p) >= 3 && (p[0] == '\\' || p[0] == '/' ||
2215                         p[1] == ':' && p[2] == '\\' ||
2216                         p[1] == ':' && p[2] == '/'))
2217                       strcpy(buf, p);
2218                     else if (uinfo->uname)
2219                       sprintf(buf, "%s/%s/%s/%s/%s",
2220                               uinfo->topdir ? uinfo->topdir : "",
2221 			      "dic", "user",
2222                               uinfo->uname, uinfo->cannafile);
2223                     else
2224                       buf[0] = '\0';
2225                   }
2226                   else {
2227                     sprintf(buf, "%s/%s",
2228 			    uinfo->topdir ? uinfo->topdir : "", "default.can");
2229                   }
2230                   wcKanjiControl((int)d, KC_SETINITFILENAME, buf);
2231 		  RkwSetUserInfo(uinfo->uname, uinfo->gname, uinfo->topdir);
2232                   ret = 1;
2233 		  goto return_ret;
2234                 }
2235 		if (romkanatable) (void)free(romkanatable);
2236               }
2237               if (cannafile) (void)free(cannafile);
2238             }
2239             if (topdir) (void)free(topdir);
2240           }
2241           if (srvname) (void)free(srvname);
2242         }
2243         if (gname) (void)free(gname);
2244       }
2245       if (uname) (void)free(uname);
2246     }
2247 #ifndef CODED_MESSAGE
2248     jrKanjiError = "malloc (SetUserinfo) �Ǥ��ޤ���Ǥ���";
2249 #else
2250     jrKanjiError = "malloc (SetUserinfo) \244\307\244\255\244\336\244\273\244\363\244\307\244\267\244\277";
2251 #endif
2252   }
2253   ret = -1;
2254 
2255  return_ret:
2256 #ifdef USE_MALLOC_FOR_BIG_ARRAY
2257   (void)free(buf);
2258 #endif
2259   return ret;
2260 }
2261 
2262 static int
KC_queryCustom(d,arg)2263 KC_queryCustom(d, arg)
2264 uiContext d;
2265 jrCInfoStruct *arg;
2266 /* ARGSUSED */
2267 {
2268   extern struct CannaConfig cannaconf;
2269   static char *input_code[CANNA_MAX_CODE] = {"jis", "sjis", "kuten"};
2270 
2271   if (/* 0 <= cannaconf.code_input && // unsigned �ʤΤ�ɬ���� */
2272       cannaconf.code_input <= CANNA_MAX_CODE) {
2273     strcpy(arg->codeinput, input_code[cannaconf.code_input]);
2274   }
2275   arg->quicklyescape = cannaconf.quickly_escape;
2276   arg->indexhankaku = cannaconf.indexHankaku;
2277   arg->indexseparator = cannaconf.indexSeparator;
2278   arg->selectdirect = cannaconf.SelectDirect;
2279   arg->numericalkeysel = cannaconf.HexkeySelect;
2280   arg->kouhocount = cannaconf.kCount;
2281 
2282   return 0;
2283 }
2284 
2285 static int
KC_closeAllContext(d,arg)2286 KC_closeAllContext(d, arg)
2287 uiContext d;
2288 char *arg;
2289 /* ARGSUSED */
2290 {
2291   makeAllContextToBeClosed(1);
2292   return 0;
2293 }
2294 
2295 static int
KC_attributeInfo(d,arg)2296 KC_attributeInfo(d, arg)
2297 uiContext d;
2298 char *arg;
2299 {
2300   wcKanjiAttributeInternal **p = (wcKanjiAttributeInternal **)arg;
2301 
2302   if (p) {
2303     if (!d->attr) {
2304       d->attr = (wcKanjiAttributeInternal *)
2305 	malloc(sizeof(wcKanjiAttributeInternal));
2306       if (d->attr) {
2307 	d->attr->u.attr = malloc(ROMEBUFSIZE);
2308 	if (d->attr->u.attr) {
2309 	  d->attr->len = ROMEBUFSIZE;
2310 	  *p = d->attr;
2311 	  return 0;
2312 	}
2313 	(void)free((char *)d->attr);
2314 	d->attr = (wcKanjiAttributeInternal *)0;
2315       }
2316     }
2317     else { /* called twice */
2318       *p = d->attr;
2319       return 0;
2320     }
2321   }
2322   else if (d->attr) { /* && !p */
2323     (void)free(d->attr->u.attr);
2324     (void)free((char *)d->attr);
2325     d->attr = (wcKanjiAttributeInternal *)0;
2326     return 0;
2327   }
2328   return -1;
2329 }
2330 
2331 /* KanjiControl�θġ�������ؿ��ؤΥݥ��� */
2332 
2333 static int (*kctlfunc[MAX_KC_REQUEST])() = {
2334   KC_initialize,
2335   KC_finalize,
2336   KC_changeMode,
2337   KC_setWidth,
2338   KC_setUFunc,
2339   KC_setBunsetsuKugiri,
2340   KC_setModeInfoStyle,
2341   KC_setHexInputStyle,
2342   KC_inhibitHankakuKana,
2343   KC_defineKanji,
2344   KC_kakutei,
2345   KC_kill,
2346   KC_modekeys,
2347   KC_queryMode,
2348   KC_queryConnection,
2349   KC_setServerName,
2350   KC_parse,
2351   KC_yomiInfo,
2352   KC_storeYomi,
2353   KC_setInitFileName,
2354   KC_do,
2355   KC_getContext,
2356   KC_closeUIContext,
2357   KC_inhibitChangeMode,
2358   KC_letterRestriction,
2359   KC_queryMaxModeStr,
2360   KC_setListCallback,
2361   KC_setVerbose,
2362   KC_lispInteraction,
2363   KC_disconnectServer,
2364   KC_setAppName,
2365   KC_debugmode,
2366   KC_debugyomi,
2367   KC_keyconvCallback,
2368   KC_queryPhono,
2369   KC_changeServer,
2370   KC_setUserInfo,
2371   KC_queryCustom,
2372   KC_closeAllContext,
2373   KC_attributeInfo,
2374 };
2375 
kanjiControl(request,d,arg)2376 kanjiControl(request, d, arg)
2377 int request;
2378 uiContext d;
2379 caddr_t arg;
2380 {
2381   return kctlfunc[request](d, arg);
2382 }
2383 
2384 #ifndef wchar_t
2385 # error "wchar_t is already undefined"
2386 #endif
2387 #undef wchar_t
2388 /*********************************************************************
2389  *                       wchar_t replace end                         *
2390  *********************************************************************/
2391