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/************************************************************************/
24/* THIS SOURCE CODE IS MODIFIED FOR TKO BY T.MURAI 1997
25/************************************************************************/
26
27
28#if !defined(lint) && !defined(__CODECENTER__)
29static	char	rcs_id[] = "@(#) 102.1 $Id: ichiran.c 14875 2005-11-12 21:25:31Z bonefish $";
30#endif /* lint */
31
32#include	<errno.h>
33#include	"canna.h"
34#include "RK.h"
35#include "RKintern.h"
36
37extern int TanNextKouho();
38
39static void clearIchiranContext();
40static int IchiranKakutei();
41static void getIchiranPreviousKouhoretsu();
42static void getIchiranNextKouhoretsu();
43
44
45#define ICHISIZE 9
46
47static void makeIchiranEchoStrCurChange(yomiContext yc);
48static void makeIchiranKanjiStatusReturn(uiContext d, mode_context env, yomiContext yc);
49static int ichiranEveryTimeCatch(uiContext d, int retval, mode_context env);
50static int ichiranExitCatch(uiContext d, int retval, mode_context env);
51static int ichiranQuitCatch(uiContext d, int retval, mode_context env);
52static void popIchiranMode(uiContext d);
53static void clearIchiranContext(ichiranContext p);
54static int makeKouhoIchiran(uiContext d, int nelem, int bangomax, unsigned char inhibit, int currentkouho);
55static int IchiranKakuteiThenDo(uiContext d, int func);
56static int IchiranQuitThenDo(uiContext d, int func);
57static int IchiranConvert(uiContext d);
58static void getIchiranPreviousKouhoretsu(uiContext d);
59static int IchiranNextPage(uiContext d);
60static int IchiranPreviousPage(uiContext d);
61static void getIchiranNextKouhoretsu(uiContext d);
62static int IchiranBangoKouho(uiContext d);
63static int getIchiranBangoKouho(uiContext d);
64static int IchiranKakutei(uiContext d);
65static int IchiranExtendBunsetsu(uiContext d);
66static int IchiranShrinkBunsetsu(uiContext d);
67static int IchiranAdjustBunsetsu(uiContext d);
68static int IchiranKillToEndOfLine(uiContext d);
69static int IchiranDeleteNext(uiContext d);
70static int IchiranBubunMuhenkan(uiContext d);
71static int IchiranHiragana(uiContext d);
72static int IchiranKatakana(uiContext d);
73static int IchiranZenkaku(uiContext d);
74static int IchiranHankaku(uiContext d);
75static int IchiranRomaji(uiContext d);
76static int IchiranToUpper(uiContext d);
77static int IchiranToLower(uiContext d);
78static int IchiranCapitalize(uiContext d);
79static int IchiranKanaRotate(uiContext d);
80static int IchiranRomajiRotate(uiContext d);
81static int IchiranCaseRotateForward(uiContext d);
82static char *sbango =
83  "\243\261\241\241\243\262\241\241\243\263\241\241\243\264\241\241\243\265"
84  "\241\241\243\266\241\241\243\267\241\241\243\270\241\241\243\271\241\241"
85  "\243\341\241\241\243\342\241\241\243\343\241\241\243\344\241\241\243\345"
86  "\241\241\243\346";
87     /* £±¡¡£²¡¡£³¡¡£´¡¡£µ¡¡£¶¡¡£·¡¡£¸¡¡£¹¡¡£á¡¡£â¡¡£ã¡¡£ä¡¡£å¡¡£æ */
88                                                /* ¸õÊä¹Ô¤Î¸õÊäÈÖ¹æ¤Îʸ»úÎó */
89static WCHAR_T *bango;
90
91/*  "1.","¡¡2.","¡¡3.","¡¡4.","¡¡5.","¡¡6.","¡¡7.","¡¡8.","¡¡9.",*/
92static char  *sbango2[] = {
93  "1","\241\2412","\241\2413","\241\2414","\241\2415",
94  "\241\2416","\241\2417","\241\2418","\241\2419",
95  };
96
97static WCHAR_T *bango2[ICHISIZE];
98
99static char *skuuhaku = "\241\241";
100			/* ¡¡ */
101static WCHAR_T *kuuhaku;
102
103int initIchiran(void)
104{
105  int i, retval = 0;
106  char buf[16];
107
108  retval = setWStrings(&bango, &sbango, 1);
109  if (retval != NG) {
110    for(i = 0; i < ICHISIZE; i++) {
111
112      /* ¥»¥Ñ¥ì¡¼¥¿¡¼¤Î½èÍý */
113      if (cannaconf.indexSeparator &&
114	  0x20 <= cannaconf.indexSeparator &&
115	  0x80 > cannaconf.indexSeparator)
116        sprintf(buf, "%s%c", sbango2[i], (char)cannaconf.indexSeparator);
117      else
118        sprintf(buf, "%s%c", sbango2[i], (char)DEFAULTINDEXSEPARATOR);
119
120      bango2[i] = WString(buf);
121    }
122
123    retval = setWStrings(&kuuhaku, &skuuhaku, 1);
124  }
125  return retval;
126}
127
128
129/*
130 * °ìÍ÷¹Ôɽ¼¨Ãæ¤Î¥«¥ì¥ó¥ÈʸÀá¤Î¸õÊä¤ò¹¹¿·¤¹¤ë
131 *
132 * ¡¦¥«¥ì¥ó¥È¸õÊä¤òÊѤ¨¤ë¡£
133 * ¡¦¤³¤ì¤Ë¤È¤â¤Ê¤¤ kugiri ¤â¹¹¿·¤µ¤ì¤ë
134 *
135 * °ú¤­¿ô	uiContext
136 *              yomiContext
137 */
138static void
139makeIchiranEchoStrCurChange(yomiContext yc)
140{
141  RkwXfer(yc->context, yc->curIkouho);
142}
143
144/*
145 * ¤«¤Ê´Á»úÊÑ´¹ÍѤι½Â¤ÂΤÎÆâÍƤò¹¹¿·¤¹¤ë(¤½¤Î¾ì¤Î¤ß)
146 *
147 * ¡¦°ìÍ÷¤ò¸Æ¤Ó½Ð¤¹Á°¤Î¾õÂ֤ˤĤ¤¤Æ¤Îɽ¼¨Ê¸»úÎó¤òºî¤ë
148 *
149 * °ú¤­¿ô	uiContext
150 *              yomiContext
151 */
152static void
153makeIchiranKanjiStatusReturn(uiContext d, mode_context env, yomiContext yc)
154{
155  mode_context sv;
156
157  sv = d->modec;
158  d->modec = env;
159  makeKanjiStatusReturn(d, yc);
160  d->modec = sv;
161}
162
163#define DEC_COLUMNS(n) ((n) < 10 ? 1 : (n) < 100 ? 2 : (n) < 1000 ? 3 : 4)
164
165/*
166 * ¸õÊä¹Ô¤Ë´Ø¤¹¤ë¹½Â¤ÂΤÎÆâÍƤò¹¹¿·¤¹¤ë
167 *
168 * ¡¦glineinfo ¤È kouhoinfo ¤«¤é¸õÊä¹Ô¤òºîÀ®¤·¡¢¥«¥ì¥ó¥È¸õÊäÈÖ¹æ¤òȿž¤¹¤ë
169 *
170 * °ú¤­¿ô	uiContext
171 * Ìá¤êÃÍ	¤Ê¤·
172 */
173void
174makeGlineStatus(uiContext d)
175{
176  ichiranContext ic = (ichiranContext)d->modec;
177  WCHAR_T *p;
178  char str[16];
179  int i, cur;
180
181  if (cannaconf.kCount) {
182    cur = *(ic->curIkouho) + 1;
183  }
184
185  d->kanji_status_return->info |= KanjiGLineInfo;
186  d->kanji_status_return->gline.line =
187    ic->glineifp[ic->kouhoifp[*(ic->curIkouho)].khretsu].gldata;
188  d->kanji_status_return->gline.length =
189    ic->glineifp[ic->kouhoifp[*(ic->curIkouho)].khretsu].gllen;
190  d->kanji_status_return->gline.revPos =
191    ic->kouhoifp[*(ic->curIkouho)].khpoint;
192  if (cannaconf.ReverseWord && ic->inhibit & NUMBERING) {
193    p = ic->glineifp[ic->kouhoifp[*(ic->curIkouho)].khretsu].gldata +
194      ic->kouhoifp[*(ic->curIkouho)].khpoint;
195    for (i = 0;
196         *p != *kuuhaku && *p != ((WCHAR_T)' ') && *p != ((WCHAR_T)0)
197	 && i < ic->glineifp[ic->kouhoifp[*(ic->curIkouho)].khretsu].gllen;
198	 i++) {
199      p++;
200    }
201    d->kanji_status_return->gline.revLen = i;
202  } else
203    d->kanji_status_return->gline.revLen = 1;
204
205  if (cannaconf.kCount && d->kanji_status_return->gline.length) {
206    register int a = ic->nIkouho, b = DEC_COLUMNS(cur) + DEC_COLUMNS(a) + 2;
207    sprintf(str, " %d/%d", cur, a);
208    MBstowcs(d->kanji_status_return->gline.line +
209	     d->kanji_status_return->gline.length - b, str, b + 1);
210    /* °Ê²¼¤Ï¤¤¤é¤Ê¤¤¤Î¤Ç¤Ï¡© */
211    d->kanji_status_return->gline.length
212      = WStrlen(d->kanji_status_return->gline.line);
213  }
214}
215
216static int ichiranEveryTimeCatch (uiContext, int, mode_context);
217
218static int
219ichiranEveryTimeCatch(uiContext d, int retval, mode_context env)
220{
221  yomiContext yc;
222
223  yc = (yomiContext)env;
224
225  makeIchiranEchoStrCurChange(yc);
226  makeIchiranKanjiStatusReturn(d, env, yc);
227
228  return(retval);
229}
230
231static int ichiranExitCatch (uiContext, int, mode_context);
232
233static int
234ichiranExitCatch(uiContext d, int retval, mode_context env)
235{
236  yomiContext yc;
237
238  yc = (yomiContext)env;
239  yc->kouhoCount = 0;
240  /* d->curIkouho¤ò¥«¥ì¥ó¥È¸õÊä¤È¤¹¤ë */
241  if ((retval = RkwXfer(yc->context, yc->curIkouho)) == NG) {
242    if (errno == EPIPE) {
243      jrKanjiPipeError();
244    }
245    jrKanjiError = "\245\253\245\354\245\363\245\310\270\365\312\344\244\362"
246	"\274\350\244\352\275\320\244\273\244\336\244\273\244\363\244\307"
247	"\244\267\244\277";
248      /* ¥«¥ì¥ó¥È¸õÊä¤ò¼è¤ê½Ð¤»¤Þ¤»¤ó¤Ç¤·¤¿ */
249    /* ¥«¥ì¥ó¥È¸õÊ䤬¼è¤ê½Ð¤»¤Ê¤¤¤¯¤é¤¤¤Ç¤Ï²¿¤È¤â¤Ê¤¤¤¾ */
250  }
251  else {
252    retval = d->nbytes = 0;
253  }
254
255  makeIchiranEchoStrCurChange(yc);
256  makeIchiranKanjiStatusReturn(d, env, yc);
257
258  freeGetIchiranList(yc->allkouho);
259
260  popCallback(d);
261
262  if (!cannaconf.stayAfterValidate && !d->more.todo) {
263    d->more.todo = 1;
264    d->more.ch = 0;
265    d->more.fnum = CANNA_FN_Forward;
266  }
267  currentModeInfo(d);
268
269  return(retval);
270}
271
272static int ichiranQuitCatch (uiContext, int, mode_context);
273
274static int
275ichiranQuitCatch(uiContext d, int retval, mode_context env)
276{
277  yomiContext yc;
278
279  yc = (yomiContext)env;
280  yc->kouhoCount = 0;
281
282  if ((retval = RkwXfer(yc->context, yc->curIkouho)) == NG) {
283    if(errno == EPIPE) {
284      jrKanjiPipeError();
285    }
286    jrKanjiError = "\245\253\245\354\245\363\245\310\270\365\312\344\244\362"
287	"\274\350\244\352\275\320\244\273\244\336\244\273\244\363\244\307"
288	"\244\267\244\277";
289           /* ¥«¥ì¥ó¥È¸õÊä¤ò¼è¤ê½Ð¤»¤Þ¤»¤ó¤Ç¤·¤¿ */
290    /* ¥«¥ì¥ó¥È¸õÊ䤬¼è¤ê½Ð¤»¤Ê¤¤¤¯¤é¤¤¤Ç¤Ï²¿¤È¤â¤Ê¤¤¤¾ */
291  }
292  else {
293    retval = d->nbytes = 0;
294  }
295
296  makeIchiranEchoStrCurChange(yc);
297  makeIchiranKanjiStatusReturn(d, env, yc);
298
299  freeGetIchiranList(yc->allkouho);
300
301  popCallback(d);
302  currentModeInfo(d);
303  return(retval);
304}
305
306void
307freeIchiranBuf(ichiranContext ic)
308{
309  if(ic->glinebufp)
310    free(ic->glinebufp);
311  if(ic->kouhoifp)
312    free(ic->kouhoifp);
313  if(ic->glineifp)
314    free(ic->glineifp);
315}
316
317void
318freeGetIchiranList(WCHAR_T **buf)
319{
320  /* ¸õÊä°ìÍ÷ɽ¼¨¹ÔÍѤΥ¨¥ê¥¢¤ò¥Õ¥ê¡¼¤¹¤ë */
321  if(buf) {
322    if(*buf) {
323      free(*buf);
324    }
325    free(buf);
326  }
327}
328
329static void
330popIchiranMode(uiContext d)
331{
332  ichiranContext ic = (ichiranContext)d->modec;
333
334  d->modec = ic->next;
335  d->current_mode = ic->prevMode;
336  freeIchiranContext(ic);
337}
338
339/*
340 * ¤¹¤Ù¤Æ¤Î¸õÊä¤ò¼è¤ê½Ð¤·¤Æ¡¢ÇÛÎó¤Ë¤¹¤ë
341 */
342
343
344WCHAR_T **
345getIchiranList(int context, int *nelem, int *currentkouho)
346{
347  WCHAR_T *work, *wptr, **bptr, **buf;
348  RkStat st;
349  int i;
350
351  /* RkwGetKanjiList ¤ÇÆÀ¤ë¡¢¤¹¤Ù¤Æ¤Î¸õÊä¤Î¤¿¤á¤ÎÎΰè¤òÆÀ¤ë */
352  if ((work = (WCHAR_T *)malloc(ROMEBUFSIZE * sizeof(WCHAR_T)))
353                                               == (WCHAR_T *)NULL) {
354#ifndef WIN
355    jrKanjiError = "malloc (getIchiranList) ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿";
356#else
357    jrKanjiError = "malloc (getIchiranList) \244\307\244\255\244\336\244\273\244\363\244\307\244\267\244\277";
358#endif
359    return (WCHAR_T **)NULL;
360  }
361
362  /* ¤¹¤Ù¤Æ¤Î¸õÊä¤òÆÀ¤ë¡£
363     Îã: ¤±¤¤¤«¤ó ¢ª ·Ù´±@·Ê´Ñ@³Ý´§@@ (@¤ÏNULL) */
364  if((*nelem = RkwGetKanjiList(context, work, ROMEBUFSIZE)) < 0) {
365    jrKanjiError = "\244\271\244\331\244\306\244\316\270\365\312\344\244\316"
366	"\274\350\244\352\275\320\244\267\244\313\274\272\307\324\244\267"
367	"\244\336\244\267\244\277";
368                   /* ¤¹¤Ù¤Æ¤Î¸õÊä¤Î¼è¤ê½Ð¤·¤Ë¼ºÇÔ¤·¤Þ¤·¤¿ */
369    free(work);
370    return (WCHAR_T **)NULL;
371  }
372
373#ifdef	INHIBIT_DUPLICATION
374  if (*nelem == 3) {
375    WCHAR_T *w1, *w2, *w3;
376
377    w1 = work;
378    w2 = w1 + WStrlen(w1);
379    w3 = w2 + WStrlen(w2);
380    if (!WStrcmp(w1, ++w3)) {
381      if (!WStrcmp(w1, ++w2))
382	*nelem = 1;
383      else
384	*nelem = 2;
385    }
386  }
387#endif	/* INHIBIT_DUPLICATION */
388
389  /* makeKouhoIchiran()¤ËÅϤ¹¥Ç¡¼¥¿ */
390  if((buf = (WCHAR_T **)calloc
391      (*nelem + 1, sizeof(WCHAR_T *))) == (WCHAR_T **)NULL) {
392    jrKanjiError = "malloc (getIchiranList) \244\307\244\255\244\336\244\273"
393	"\244\363\244\307\244\267\244\277";
394                                            /* ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿ */
395    free(work);
396    return (WCHAR_T **)NULL;
397  }
398  for(wptr = work, bptr = buf, i = 0; *wptr && i++ < *nelem; bptr++) {
399    *bptr = wptr;
400    while(*wptr++)
401      /* EMPTY */
402      ;
403  }
404  *bptr = (WCHAR_T *)0;
405
406  if(RkwGetStat(context, &st) == -1) {
407    jrKanjiError = "\245\271\245\306\245\244\245\277\245\271\244\362\274\350"
408	"\244\352\275\320\244\273\244\336\244\273\244\363\244\307\244\267"
409	"\244\277";
410                   /* ¥¹¥Æ¥¤¥¿¥¹¤ò¼è¤ê½Ð¤»¤Þ¤»¤ó¤Ç¤·¤¿ */
411    free(work);
412    free(buf);
413    return (WCHAR_T **)NULL;
414  }
415  *currentkouho = st.candnum; /* ¥«¥ì¥ó¥È¸õÊä¤Ï²¿ÈÖÌÜ¡© */
416
417  return(buf);
418}
419
420/* cfunc ichiranContext
421 *
422 * ichiranContext ¸õÊä°ìÍ÷ÍѤι½Â¤ÂΤòºî¤ê½é´ü²½¤¹¤ë
423 *
424 */
425ichiranContext
426newIchiranContext(void)
427{
428  ichiranContext icxt;
429
430  if ((icxt = (ichiranContext)malloc(sizeof(ichiranContextRec)))
431                                          == (ichiranContext)NULL) {
432#ifndef WIN
433    jrKanjiError = "malloc (newIchiranContext) ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿";
434#else
435    jrKanjiError = "malloc (newIchiranContext) \244\307\244\255\244\336"
436	"\244\273\244\363\244\307\244\267\244\277";
437#endif
438    return (ichiranContext)NULL;
439  }
440  clearIchiranContext(icxt);
441
442  return icxt;
443}
444
445/*
446 * ¸õÊä°ìÍ÷¹Ô¤òºî¤ë
447 */
448
449int
450selectOne(uiContext d, WCHAR_T **buf, int *ck, int nelem, int bangomax, unsigned inhibit, int currentkouho, int allowcallback, canna_callback_t everyTimeCallback, canna_callback_t exitCallback, canna_callback_t quitCallback, canna_callback_t auxCallback)
451{
452  extern KanjiModeRec ichiran_mode;
453  ichiranContext ic;
454
455  if (allowcallback != WITHOUT_LIST_CALLBACK &&
456      d->list_func == NULL) {
457    allowcallback = WITHOUT_LIST_CALLBACK;
458  }
459
460  if(pushCallback(d, d->modec,
461	everyTimeCallback, exitCallback, quitCallback, auxCallback) == 0) {
462    jrKanjiError = "malloc (pushCallback) \244\307\244\255\244\336\244\273"
463	"\244\363\244\307\244\267\244\277";
464                                          /* ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿ */
465    return(NG);
466  }
467
468  if((ic = newIchiranContext()) == (ichiranContext)NULL) {
469    popCallback(d);
470    return(NG);
471  }
472  ic->majorMode = d->majorMode;
473  ic->next = d->modec;
474  d->modec = (mode_context)ic;
475
476  ic->prevMode = d->current_mode;
477  d->current_mode = &ichiran_mode;
478  d->flags &= ~(PLEASE_CLEAR_GLINE | PCG_RECOGNIZED);
479  /* ¤³¤³¤Ë¤¯¤ëľÁ°¤Ë C-t ¤È¤«¤¬ Gline ¤Ëɽ¼¨¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¾å¤Î£±¹Ô¤ò
480     ¤ä¤ëɬÍפ¬½Ð¤Æ¤¯¤ë¡£ */
481
482  ic->allkouho = buf;
483  ic->curIkouho = ck;
484  ic->inhibit = inhibit;
485  ic->nIkouho = nelem;
486
487  if (allowcallback != WITHOUT_LIST_CALLBACK) {
488    ic->flags |= ICHIRAN_ALLOW_CALLBACK;
489    /* listcallback ¤Ç¤ÏÈÖ¹æ¤Ï¤Ä¤±¤Ê¤¤ */
490    ic->inhibit |= NUMBERING;
491  }
492
493  if (allowcallback == WITHOUT_LIST_CALLBACK) {
494    if (makeKouhoIchiran(d, nelem, bangomax, inhibit, currentkouho)   == NG) {
495      popIchiranMode(d);
496      popCallback(d);
497      return(NG);
498    }
499  }
500  else {
501    if (cannaconf.kCount) {
502      *(ic->curIkouho) += currentkouho;
503      if (*(ic->curIkouho) >= ic->nIkouho)
504        ic->svIkouho = *(ic->curIkouho) = 0;
505    }
506    d->list_func(d->client_data, CANNA_LIST_Start, buf, nelem, ic->curIkouho);
507  }
508
509  return(0);
510}
511
512/*
513 * IchiranContext ¤Î½é´ü²½
514 */
515static void
516clearIchiranContext(ichiranContext p)
517{
518  p->id = ICHIRAN_CONTEXT;
519  p->svIkouho = 0;
520  p->curIkouho = 0;
521  p->nIkouho = 0;
522  p->tooSmall = 0;
523  p->curIchar = 0;
524  p->allkouho = 0;
525  p->glinebufp = 0;
526  p->kouhoifp = (kouhoinfo *)0;
527  p->glineifp = (glineinfo *)0;
528  p->flags = (unsigned char)0;
529}
530
531/*
532 * ¸õÊä°ìÍ÷¤Î¥Ç¡¼¥¿¹½Â¤ÂΤòºî¤ë¤¿¤á¤ÎÎΰè¤ò³ÎÊݤ¹¤ë
533 */
534int allocIchiranBuf(uiContext d)
535{
536  ichiranContext ic = (ichiranContext)d->modec;
537  int size;
538
539  /* ¥µ¥¤¥º¤Îʬ¤ÈÈÖ¹æ¤Îʬ¤ÎÎΰè¤òÆÀ¤ë*/
540  size = ic->nIkouho * (d->ncolumns + 1) * WCHARSIZE; /* ¤¨¤¤¤ä¤Ã */
541  if((ic->glinebufp = (WCHAR_T *)malloc(size)) ==  (WCHAR_T *)NULL) {
542    jrKanjiError = "malloc (allocIchiranBuf) \244\307\244\255\244\336\244\273"
543	"\244\363\244\307\244\267\244\277";
544                                             /* ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿ */
545    return(NG);
546  }
547
548  /* kouhoinfo¤ÎÎΰè¤òÆÀ¤ë */
549  size = (ic->nIkouho + 1) * sizeof(kouhoinfo);
550  if((ic->kouhoifp = (kouhoinfo *)malloc(size)) == (kouhoinfo *)NULL) {
551    jrKanjiError = "malloc (allocIchiranBuf) \244\307\244\255\244\336\244\273"
552	"\244\363\244\307\244\267\244\277";
553                                             /* ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿ */
554    free(ic->glinebufp);
555    return(NG);
556  }
557
558  /* glineinfo¤ÎÎΰè¤òÆÀ¤ë */
559  size = (ic->nIkouho + 1) * sizeof(glineinfo);
560  if((ic->glineifp = (glineinfo *)malloc(size)) == (glineinfo *)NULL) {
561    jrKanjiError = "malloc (allocIchiranBuf) \244\307\244\255\244\336\244\273"
562	"\244\363\244\307\244\267\244\277";
563                                             /* ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿ */
564    free(ic->glinebufp);
565    free(ic->kouhoifp);
566    return(NG);
567  }
568  return(0);
569}
570
571/*
572 * ¸õÊä°ìÍ÷¹Ô¤òɽ¼¨ÍѤΥǡ¼¥¿¤ò¥Æ¡¼¥Ö¥ë¤ËºîÀ®¤¹¤ë
573 *
574 * ¡¦glineinfo ¤È kouhoinfo¤òºîÀ®¤¹¤ë
575 *
576 * °ú¤­¿ô	uiContext
577 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
578 */
579static int
580makeKouhoIchiran(uiContext d, int nelem, int bangomax, unsigned char inhibit, int currentkouho)
581{
582  ichiranContext ic = (ichiranContext)d->modec;
583  WCHAR_T **kkptr, *kptr, *gptr, *svgptr;
584  int           ko, lnko, cn = 0, svcn, line = 0, dn = 0, svdn;
585  int netwidth;
586
587  netwidth = d->ncolumns -
588    (cannaconf.kCount ? (DEC_COLUMNS(nelem) * 2 + 2/* 2¤Ï/¤ÈSP¤Îʬ */) : 0);
589
590  ic->nIkouho = nelem;	/* ¸õÊä¤Î¿ô */
591
592  /* ¥«¥ì¥ó¥È¸õÊä¤ò¥»¥Ã¥È¤¹¤ë */
593  ic->svIkouho = *(ic->curIkouho);
594  *(ic->curIkouho) += currentkouho;
595  if(*(ic->curIkouho) >= ic->nIkouho)
596    ic->svIkouho = *(ic->curIkouho) = 0;
597
598  if(allocIchiranBuf(d) == NG)
599    return(NG);
600
601  if(d->ncolumns < 1) {
602    ic->tooSmall = 1;
603    return(0);
604  }
605
606  /* glineinfo¤Èkouhoinfo¤òºî¤ë */
607  /*
608   ¡öglineinfo¡ö
609      int glkosu   : int glhead     : int gllen  : WCHAR_T *gldata
610      £±¹Ô¤Î¸õÊä¿ô : ÀèƬ¸õÊ䤬     : £±¹Ô¤ÎŤµ : ¸õÊä°ìÍ÷¹Ô¤Îʸ»úÎó
611                   : ²¿ÈÖÌܤθõÊ䤫 :
612   -------------------------------------------------------------------------
613   0 | 6           : 0              : 24         : £±¿·£²¿´£³¿Ê£´¿¿£µ¿À£¶¿®
614   1 | 4           : 6              : 16         : £±¿Ã£²¿²£³¿­£´¿Ä
615
616    ¡ökouhoinfo¡ö
617      int khretsu  : int khpoint  : WCHAR_T *khdata
618      ¤Ê¤óÎóÌÜ¤Ë   : ¹Ô¤ÎÀèƬ¤«¤é : ¸õÊä¤Îʸ»úÎó
619      ¤¢¤ë¸õÊ䤫   : ²¿¥Ð¥¤¥ÈÌܤ« :
620   -------------------------------------------------------------------------
621   0 | 0           : 0            : ¿·
622   1 | 0           : 4            : ¿´
623             :                :             :
624   7 | 1           : 0            : ¿Ã
625   8 | 1           : 4            : ¿²
626  */
627
628  kkptr = ic->allkouho;
629  kptr = *(ic->allkouho);
630  gptr = ic->glinebufp;
631
632  /* line -- ²¿ÎóÌܤ«
633     ko   -- Á´ÂΤÎÀèƬ¤«¤é²¿ÈÖÌܤθõÊ䤫
634     lnko -- Îó¤ÎÀèƬ¤«¤é²¿ÈÖÌܤθõÊ䤫
635     cn   -- Îó¤ÎÀèƬ¤«¤é²¿¥Ð¥¤¥ÈÌܤ« */
636
637  for(line=0, ko=0; ko<ic->nIkouho; line++) {
638    ic->glineifp[line].gldata = gptr; /* ¸õÊä¹Ô¤òɽ¼¨¤¹¤ë¤¿¤á¤Îʸ»úÎó */
639    ic->glineifp[line].glhead = ko;   /* ¤³¤Î¹Ô¤ÎÀèƬ¸õÊä¤Ï¡¢Á´ÂΤǤÎkoÈÖÌÜ */
640
641    ic->tooSmall = 1;
642    for (lnko = cn = dn = 0 ;
643	dn < netwidth && lnko < bangomax && ko < ic->nIkouho ; lnko++, ko++) {
644      ic->tooSmall = 0;
645      kptr = kkptr[ko];
646      ic->kouhoifp[ko].khretsu = line; /* ²¿¹ÔÌܤ˸ºß¤¹¤ë¤«¤òµ­Ï¿ */
647      ic->kouhoifp[ko].khpoint = cn + (lnko ? 1 : 0);
648      ic->kouhoifp[ko].khdata = kptr;  /* ¤½¤Îʸ»úÎó¤Ø¤Î¥Ý¥¤¥ó¥¿ */
649      svgptr = gptr;
650      svcn = cn;
651      svdn = dn;
652      /* £²¼ïÎà¤Îɽ¼¨¤òʬ¤±¤ë */
653      if(!(inhibit & (unsigned char)NUMBERING)) {
654	/* ÈÖ¹æ¤ò¥³¥Ô¡¼¤¹¤ë */
655	if (!cannaconf.indexHankaku) {/* Á´³Ñ */
656	  if(lnko == 0) {
657	    *gptr++ = *bango; cn ++; dn +=2;
658	  } else {
659	    WStrncpy(gptr, bango + 1 + BANGOSIZE * (lnko - 1), BANGOSIZE);
660	    cn += BANGOSIZE; gptr += BANGOSIZE, dn += BANGOSIZE*2;
661	  }
662	}
663	else{ /* Ⱦ³Ñ */
664	  WStrcpy(gptr, bango2[lnko]);
665	  if(lnko == 0) {
666	    dn +=2;
667	  } else {
668	    dn +=4;
669	  }
670	  cn += WStrlen(bango2[lnko]);
671	  gptr += WStrlen(bango2[lnko]);
672	}
673      } else {
674	/* ¶õÇò¤ò¥³¥Ô¡¼¤¹¤ë */
675	if(lnko) {
676	  *gptr++ = *kuuhaku; cn ++; dn +=2;
677	}
678      }
679      /* ¸õÊä¤ò¥³¥Ô¡¼¤¹¤ë */
680      for (; *kptr && dn < netwidth ; gptr++, kptr++, cn++) {
681	*gptr = *kptr;
682	if (WIsG0(*gptr))
683	  dn++;
684	else if (WIsG1(*gptr))
685	  dn += 2;
686	else if (WIsG2(*gptr))
687	  dn ++;
688	else if (WIsG3(*gptr))
689	  dn += 2;
690      }
691
692      /* ¥«¥é¥à¿ô¤è¤ê¤Ï¤ß¤À¤·¤Æ¤·¤Þ¤¤¤½¤¦¤Ë¤Ê¤Ã¤¿¤Î¤Ç£±¤ÄÌ᤹ */
693      if (dn >= netwidth) {
694	if (lnko) {
695	  gptr = svgptr;
696	  cn = svcn;
697	  dn = svdn;
698	}
699	else {
700	  ic->tooSmall = 1;
701	}
702	break;
703      }
704    }
705    if (ic->tooSmall) {
706      return 0;
707    }
708    if (cannaconf.kCount) {
709      for (;dn < d->ncolumns - 1; dn++)
710	*gptr++ = ' ';
711    }
712    /* £±¹Ô½ª¤ï¤ê */
713    *gptr++ = 0;
714    ic->glineifp[line].glkosu = lnko;
715    ic->glineifp[line].gllen = WStrlen(ic->glineifp[line].gldata);
716  }
717
718  /* ºÇ¸å¤ËNULL¤òÆþ¤ì¤ë */
719  ic->kouhoifp[ko].khretsu = 0;
720  ic->kouhoifp[ko].khpoint = 0;
721  ic->kouhoifp[ko].khdata  = (WCHAR_T *)NULL;
722  ic->glineifp[line].glkosu  = 0;
723  ic->glineifp[line].glhead  = 0;
724  ic->glineifp[line].gllen   = 0;
725  ic->glineifp[line].gldata  = (WCHAR_T *)NULL;
726
727#if defined(DEBUG) && !defined(WIN)
728  if (iroha_debug) {
729    int i;
730    for(i=0; ic->glineifp[i].glkosu; i++)
731      printf("%d: %s\n", i, ic->glineifp[i].gldata);
732  }
733#endif
734
735  return(0);
736}
737
738int tanKouhoIchiran(uiContext d, int step)
739{
740  yomiContext yc = (yomiContext)d->modec;
741  ichiranContext ic;
742  int nelem, currentkouho, retval = 0;
743  unsigned inhibit = 0;
744  unsigned char listcallback = (unsigned char)(d->list_func ? 1 : 0);
745  int netwidth;
746
747  netwidth = d->ncolumns -
748    (cannaconf.kCount ? (DEC_COLUMNS(9999) * 2 + 2/* 2¤Ï / ¤È SP ¤Îʬ */) : 0);
749
750  /* ¸õÊä°ìÍ÷¹Ô¤¬¶¹¤¯¤Æ¸õÊä°ìÍ÷¤¬½Ð¤»¤Ê¤¤ */
751  if (listcallback == 0 && netwidth < 2) {
752    /* tooSmall */
753    return TanNextKouho(d);
754  }
755
756  /* Ã༡´ØÏ¢ */
757  yc->status |= CHIKUJI_OVERWRAP;
758
759  /* ¤¹¤Ù¤Æ¤Î¸õÊä¤ò¼è¤ê½Ð¤¹ */
760  yc->allkouho = getIchiranList(yc->context, &nelem, &currentkouho);
761  if (yc->allkouho == 0) {
762    if (errno == EPIPE) {
763      jrKanjiPipeError();
764    }
765    TanMuhenkan(d);
766    makeGLineMessageFromString(d, jrKanjiError);
767    return 0;
768  }
769
770  if (!cannaconf.HexkeySelect) {
771    inhibit |= (unsigned char)NUMBERING;
772  }
773
774  yc->curIkouho = currentkouho;	/* ¸½ºß¤Î¥«¥ì¥ó¥È¸õÊäÈÖ¹æ¤òÊݸ¤¹¤ë */
775  currentkouho = step;	/* ¥«¥ì¥ó¥È¸õÊ䤫¤é²¿ÈÖÌܤò¥«¥ì¥ó¥È¸õÊä¤È¤¹¤ë¤« */
776
777  /* ¸õÊä°ìÍ÷¤Ë°Ü¹Ô¤¹¤ë */
778  if ((retval = selectOne(d, yc->allkouho, &yc->curIkouho, nelem, BANGOMAX,
779			  inhibit, currentkouho, WITH_LIST_CALLBACK,
780			  ichiranEveryTimeCatch, ichiranExitCatch,
781			  ichiranQuitCatch, NO_CALLBACK)) == NG) {
782    freeGetIchiranList(yc->allkouho);
783    return GLineNGReturn(d);
784  }
785
786  ic = (ichiranContext)d->modec;
787  if (ic->tooSmall) {
788    freeGetIchiranList(yc->allkouho);
789    popIchiranMode(d);
790    popCallback(d);
791    return TanNextKouho(d);
792  }
793
794  ic->minorMode = CANNA_MODE_IchiranMode;
795  currentModeInfo(d);
796
797  if ( !(ic->flags & ICHIRAN_ALLOW_CALLBACK) ) {
798    makeGlineStatus(d);
799  }
800  /* d->status = EVERYTIME_CALLBACK; */
801
802  return(retval);
803}
804
805/*
806 * ¸õÊä°ìÍ÷¹Ô¤Îɽ¼¨¤ò¶¯À©½ªÎ»¤¹¤ë
807 */
808int IchiranQuit(uiContext d)
809{
810  ichiranContext ic = (ichiranContext)d->modec;
811  int retval = 0;
812
813  if (ic->flags & ICHIRAN_ALLOW_CALLBACK &&
814      d->list_func) {
815    if (ic->flags & ICHIRAN_NEXT_EXIT) {
816      d->list_func(d->client_data,
817                     CANNA_LIST_Select, (WCHAR_T **)0, 0, (int *)0);
818    }
819    else {
820      d->list_func(d->client_data,
821                     CANNA_LIST_Quit, (WCHAR_T **)0, 0, (int *)0);
822    }
823  }
824
825  if (ic->flags & ICHIRAN_NEXT_EXIT) {
826    ichiranFin(d);
827    d->status = EXIT_CALLBACK;
828  }
829  else {
830    *(ic->curIkouho) = ic->nIkouho - 1; /* ¤Ò¤é¤¬¤Ê¸õÊä¤Ë¤¹¤ë */
831    ichiranFin(d);
832    d->status = QUIT_CALLBACK;
833  }
834  return(retval);
835}
836
837int
838IchiranNop(uiContext d)
839{
840  ichiranContext ic = (ichiranContext)d->modec;
841
842  if ((ic->flags & ICHIRAN_ALLOW_CALLBACK) && d->list_func) {
843    (*d->list_func)
844      (d->client_data, CANNA_LIST_Query, (WCHAR_T **)0, 0, (int *)0);
845  }
846
847  /* currentModeInfo ¤Ç¥â¡¼¥É¾ðÊó¤¬É¬¤ºÊÖ¤ë¤è¤¦¤Ë¥À¥ß¡¼¤Î¥â¡¼¥É¤òÆþ¤ì¤Æ¤ª¤¯ */
848  d->majorMode = d->minorMode = CANNA_MODE_AlphaMode;
849  currentModeInfo(d);
850
851  if (!(ic->flags & ICHIRAN_ALLOW_CALLBACK)) {
852    makeGlineStatus(d);
853  }
854  return 0;
855}
856
857/*
858   IchiranKakuteiThenDo
859
860     -- Do determine from the candidate list, then do one more function.
861 */
862
863static int
864IchiranKakuteiThenDo(uiContext d, int func)
865{
866  ichiranContext ic = (ichiranContext)d->modec;
867  int retval;
868  BYTE ifl = ic->flags;
869
870  if (!ic->prevMode || !ic->prevMode->func ||
871      !(*ic->prevMode->func)((uiContext)0/*dummy*/, ic->prevMode, KEY_CHECK,
872			     0/*dummy*/, func)) {
873    return NothingChangedWithBeep(d);
874  }
875  retval = IchiranKakutei(d);
876  if (ifl & ICHIRAN_STAY_LONG) {
877    (void)IchiranQuit(d);
878  }
879  d->more.todo = 1;
880  d->more.ch = d->ch;
881  d->more.fnum = func;
882  return retval;
883}
884
885static
886int IchiranQuitThenDo(uiContext d, int func)
887{
888  ichiranContext ic = (ichiranContext)d->modec;
889  int retval;
890
891  if (!ic->prevMode || !ic->prevMode->func ||
892      !(*ic->prevMode->func)((uiContext)0/*dummy*/, ic->prevMode, KEY_CHECK,
893			     0/*dummy*/, func)) {
894    return NothingChangedWithBeep(d);
895  }
896  retval = IchiranQuit(d);
897  d->more.todo = 1;
898  d->more.ch = d->ch;
899  d->more.fnum = func;
900  return retval;
901}
902
903/*
904 * ¼¡¸õÊä¤Ë°ÜÆ°¤¹¤ë
905 *
906 * ¡¦¥«¥ì¥ó¥È¸õÊ䤬ºÇ½ª¸õÊä¤À¤Ã¤¿¤éÀèƬ¸õÊä¤ò¥«¥ì¥ó¥È¸õÊä¤È¤¹¤ë
907 *
908 * °ú¤­¿ô	uiContext
909 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
910 */
911int IchiranForwardKouho(uiContext d)
912{
913  ichiranContext ic = (ichiranContext)d->modec;
914
915  if (ic->flags & ICHIRAN_ALLOW_CALLBACK &&
916      d->list_func) {
917    int res;
918
919    res = (*d->list_func)
920      (d->client_data, CANNA_LIST_Forward, (WCHAR_T **)0, 0, (int *)0);
921    if (res) {
922      return 0;
923    }
924    else { /* CANNA_LIST_Forward was not prepared at the callback func */
925      return IchiranKakuteiThenDo(d, CANNA_FN_Forward);
926    }
927  }
928
929  /* ¼¡¸õÊä¤Ë¤¹¤ë (ñ¸ì¸õÊä°ìÍ÷¾õÂ֤ǡ¢ºÇ¸å¤Î¸õÊä¤À¤Ã¤¿¤é°ìÍ÷¤ò¤ä¤á¤ë) */
930  *(ic->curIkouho) += 1;
931  if(*(ic->curIkouho) >= ic->nIkouho) {
932    if (cannaconf.QuitIchiranIfEnd
933       && (((coreContext)d->modec)->minorMode == CANNA_MODE_IchiranMode)) {
934      return(IchiranQuit(d));
935    }
936    else if (cannaconf.CursorWrap) {
937      *(ic->curIkouho) = 0;
938    } else {
939      *(ic->curIkouho) -= 1;
940      return NothingChangedWithBeep(d);
941    }
942  }
943
944  if(ic->tooSmall) { /* for bushu */
945    d->status = AUX_CALLBACK;
946    return 0;
947  }
948
949  makeGlineStatus(d);
950  /* d->status = EVERYTIME_CALLBACK; */
951
952  return 0;
953}
954
955/*
956 * Á°¸õÊä¤Ë°ÜÆ°¤¹¤ë
957 *
958 * ¡¦¥«¥ì¥ó¥È¸õÊ䤬ÀèƬ¸õÊä¤À¤Ã¤¿¤éºÇ½ª¸õÊä¤ò¥«¥ì¥ó¥È¸õÊä¤È¤¹¤ë
959 *
960 * °ú¤­¿ô	uiContext
961 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
962 */
963int IchiranBackwardKouho(uiContext d)
964{
965  ichiranContext ic = (ichiranContext)d->modec;
966  BYTE mode;
967
968  if (ic->flags & ICHIRAN_ALLOW_CALLBACK &&
969      d->list_func) {
970    int res;
971    res = (*d->list_func)
972      (d->client_data, CANNA_LIST_Backward, (WCHAR_T **)0, 0, (int *)0);
973    if (res) {
974      return 0;
975    }
976    else { /* CANNA_LIST_Backward was not prepared at the callback func */
977      return IchiranKakuteiThenDo(d, CANNA_FN_Backward);
978    }
979  }
980
981  /* ¸½ºß¤Î¥â¡¼¥É¤òµá¤á¤ë */
982  if (cannaconf.QuitIchiranIfEnd)
983    mode = ((coreContext)d->modec)->minorMode;
984
985  /* Á°¸õÊä¤Ë¤¹¤ë (ñ¸ì¸õÊä°ìÍ÷¾õÂ֤ǡ¢ºÇ½é¤Î¸õÊä¤À¤Ã¤¿¤é°ìÍ÷¤ò¤ä¤á¤ë) */
986  if(*(ic->curIkouho))
987    *(ic->curIkouho) -= 1;
988  else {
989    if (cannaconf.QuitIchiranIfEnd && (mode == CANNA_MODE_IchiranMode)) {
990      return(IchiranQuit(d));
991    }
992    else if (cannaconf.CursorWrap) {
993      *(ic->curIkouho) = ic->nIkouho - 1;
994    } else {
995      *(ic->curIkouho) = 0;
996      return NothingChangedWithBeep(d);
997    }
998  }
999
1000  if(ic->tooSmall) { /* for bushu */
1001    d->status = AUX_CALLBACK;
1002    return 0;
1003  }
1004
1005  makeGlineStatus(d);
1006  /* d->status = EVERYTIME_CALLBACK; */
1007
1008  return 0;
1009}
1010
1011/*
1012   IchiranConvert() will be called when `convert' key is pressed
1013 */
1014
1015static int IchiranConvert (uiContext);
1016
1017static
1018int IchiranConvert(uiContext d)
1019{
1020  ichiranContext ic = (ichiranContext)d->modec;
1021
1022  if (ic->flags & ICHIRAN_ALLOW_CALLBACK && d->list_func) {
1023    (*d->list_func)
1024      (d->client_data, CANNA_LIST_Convert, (WCHAR_T **)0, 0, (int *)0);
1025    return 0;
1026  }
1027  else {
1028    return IchiranForwardKouho(d);
1029  }
1030}
1031
1032/*
1033 * Á°¸õÊäÎó¤Ë°ÜÆ°¤¹¤ë
1034 *
1035 * ¡¦¥«¥ì¥ó¥È¸õÊä¤òµá¤á¤Æ¸õÊä°ìÍ÷¤È¤½¤Î¾ì¤Î¸õÊä¤òɽ¼¨¤¹¤ë
1036 *
1037 * °ú¤­¿ô	uiContext
1038 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
1039 */
1040int IchiranPreviousKouhoretsu(uiContext d)
1041{
1042  ichiranContext ic = (ichiranContext)d->modec;
1043
1044  if (ic->flags & ICHIRAN_ALLOW_CALLBACK &&
1045      d->list_func) {
1046    int res;
1047    res = (*d->list_func)
1048      (d->client_data, CANNA_LIST_Prev, (WCHAR_T **)0, 0, (int *)0);
1049    if (res) {
1050      return 0;
1051    }
1052    else { /* CANNA_LIST_Backward was not prepared at the callback func */
1053      return IchiranKakuteiThenDo(d, CANNA_FN_Prev);
1054    }
1055  }
1056
1057  if(ic->tooSmall) { /* for bushu */
1058    return(IchiranBackwardKouho(d));
1059  }
1060
1061  /* Á°¸õÊäÎó¤Ë¤¹¤ë (*(ic->curIkouho)¤òµá¤á¤ë)*/
1062  getIchiranPreviousKouhoretsu(d);
1063
1064  makeGlineStatus(d);
1065  /* d->status = EVERYTIME_CALLBACK; */
1066
1067  return 0;
1068}
1069
1070/*
1071 * Á°¸õÊäÎó¤Î¥«¥ì¥ó¥È¸õÊä¤òµá¤á¤ë
1072 *
1073 * ¡¦Á°¸õÊäÎóÃæ¤ÎƱ¤¸¸õÊäÈÖ¹æ¤Î¤â¤Î¤ò¥«¥ì¥ó¥È¸õÊä¤È¤¹¤ë
1074 * ¡¦¸õÊäÈÖ¹æ¤ÎƱ¤¸¤â¤Î¤¬¤Ê¤¤»þ¤Ï¡¢¤½¤Î¸õÊäÃæ¤ÎºÇ½ª¸õÊä¤ò¥«¥ì¥ó¥È¸õÊä¤È¤¹¤ë
1075 *
1076 * °ú¤­¿ô	uiContext
1077 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
1078 */
1079static void
1080getIchiranPreviousKouhoretsu(uiContext d)
1081{
1082  ichiranContext ic = (ichiranContext)d->modec;
1083  int kindex;
1084  int curretsu, nretsu;
1085
1086  /* ¥«¥ì¥ó¥È¸õÊä¹Ô¤Î¤Ê¤«¤Ç²¿ÈÖÌܤθõÊ䤫¤Ê¤Î¤«¤òÆÀ¤ë */
1087  kindex = *(ic->curIkouho) -
1088    ic->glineifp[ic->kouhoifp[*(ic->curIkouho)].khretsu].glhead;
1089  /* Á°¸õÊäÎó¤òÆÀ¤ë */
1090  curretsu = ic->kouhoifp[*(ic->curIkouho)].khretsu;
1091  nretsu = ic->kouhoifp[ic->nIkouho - 1].khretsu + 1;
1092  if(curretsu == 0) {
1093    if (cannaconf.CursorWrap)
1094      curretsu = nretsu;
1095    else {
1096      NothingChangedWithBeep(d);
1097      return;
1098    }
1099  }
1100  curretsu -= 1;
1101  /* kindex ¤¬¥«¥ì¥ó¥È¸õÊäÎó¤Î¸õÊä¿ô¤è¤êÂ礭¤¯¤Ê¤Ã¤Æ¤·¤Þ¤Ã¤¿¤é
1102     ºÇ±¦¸õÊä¤ò¥«¥ì¥ó¥È¸õÊä¤È¤¹¤ë */
1103  if(ic->glineifp[curretsu].glkosu <= kindex)
1104    kindex = ic->glineifp[curretsu].glkosu - 1;
1105  /* Á°¸õÊäÎó¤ÎƱ¤¸ÈÖ¹æ¤Ë°ÜÆ°¤¹¤ë */
1106  *(ic->curIkouho) = kindex + ic->glineifp[curretsu].glhead;
1107  return;
1108}
1109
1110/*
1111 * ¼¡¸õÊäÎó¤Ë°ÜÆ°¤¹¤ë
1112 *
1113 * °ú¤­¿ô	uiContext
1114 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
1115 */
1116int IchiranNextKouhoretsu(uiContext d)
1117{
1118  ichiranContext ic = (ichiranContext)d->modec;
1119
1120  if (ic->flags & ICHIRAN_ALLOW_CALLBACK &&
1121      d->list_func) {
1122    int res;
1123    res = (*d->list_func)
1124      (d->client_data, CANNA_LIST_Next, (WCHAR_T **)0, 0, (int *)0);
1125    if (res) {
1126      return 0;
1127    }
1128    else { /* CANNA_LIST_Backward was not prepared at the callback func */
1129      return IchiranKakuteiThenDo(d, CANNA_FN_Next);
1130    }
1131  }
1132
1133  if(ic->tooSmall) {
1134    return(IchiranForwardKouho(d));
1135  }
1136
1137  /* ¼¡¸õÊäÎó¤Ë¤¹¤ë (*(ic->curIkouho) ¤òµá¤á¤ë) */
1138  getIchiranNextKouhoretsu(d);
1139
1140  makeGlineStatus(d);
1141  /* d->status = EVERYTIME_CALLBACK; */
1142
1143  return 0;
1144}
1145
1146/*
1147 * ¼¡¸õÊäÊǤ˰ÜÆ°¤¹¤ë
1148 *
1149 * °ú¤­¿ô	uiContext
1150 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
1151 */
1152
1153static int IchiranNextPage (uiContext);
1154
1155static
1156int IchiranNextPage(uiContext d)
1157{
1158  ichiranContext ic = (ichiranContext)d->modec;
1159
1160  if (ic->flags & ICHIRAN_ALLOW_CALLBACK &&
1161      d->list_func) {
1162    int res;
1163    res = (*d->list_func)
1164      (d->client_data, CANNA_LIST_PageDown, (WCHAR_T **)0, 0, (int *)0);
1165    if (res) {
1166      return 0;
1167    }
1168    else { /* CANNA_LIST_Backward was not prepared at the callback func */
1169      return IchiranKakuteiThenDo(d, CANNA_FN_PageDown);
1170    }
1171  }
1172
1173  return IchiranNextKouhoretsu(d);
1174}
1175
1176/*
1177 * Á°¸õÊäÊǤ˰ÜÆ°¤¹¤ë
1178 *
1179 * °ú¤­¿ô	uiContext
1180 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
1181 */
1182
1183static int IchiranPreviousPage (uiContext);
1184
1185static
1186int IchiranPreviousPage(uiContext d)
1187{
1188  ichiranContext ic = (ichiranContext)d->modec;
1189
1190  if (ic->flags & ICHIRAN_ALLOW_CALLBACK &&
1191      d->list_func) {
1192    int res;
1193    res = (*d->list_func)
1194      (d->client_data, CANNA_LIST_PageUp, (WCHAR_T **)0, 0, (int *)0);
1195    if (res) {
1196      return 0;
1197    }
1198    else { /* CANNA_LIST_Backward was not prepared at the callback func */
1199      return IchiranKakuteiThenDo(d, CANNA_FN_PageUp);
1200    }
1201  }
1202
1203  return IchiranPreviousKouhoretsu(d);
1204}
1205
1206/*
1207 * ¼¡¸õÊäÎó¤Ë°ÜÆ°¤¹¤ë
1208 *
1209 * ¡¦¼¡¸õÊäÎóÃæ¤ÎƱ¤¸¸õÊäÈÖ¹æ¤Î¤â¤Î¤ò¥«¥ì¥ó¥È¸õÊä¤È¤¹¤ë
1210 * ¡¦¸õÊäÈÖ¹æ¤ÎƱ¤¸¤â¤Î¤¬¤Ê¤¤»þ¤Ï¡¢¤½¤Î¸õÊäÃæ¤ÎºÇ½ª¸õÊä¤ò¥«¥ì¥ó¥È¸õÊä¤È¤¹¤ë
1211 *
1212 * °ú¤­¿ô	uiContext
1213 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
1214 */
1215static void
1216getIchiranNextKouhoretsu(uiContext d)
1217{
1218  ichiranContext ic = (ichiranContext)d->modec;
1219  int kindex;
1220  int curretsu, nretsu;
1221
1222  /* ¥«¥ì¥ó¥È¸õÊä¹Ô¤Î¤Ê¤«¤Ç²¿ÈÖÌܤθõÊ䤫¤Ê¤Î¤«¤òÆÀ¤ë */
1223  kindex = *(ic->curIkouho) -
1224    ic->glineifp[ic->kouhoifp[*(ic->curIkouho)].khretsu].glhead;
1225  /* ¼¡¸õÊäÎó¤òÆÀ¤ë */
1226  curretsu = ic->kouhoifp[*(ic->curIkouho)].khretsu;
1227  nretsu = ic->kouhoifp[ic->nIkouho - 1].khretsu + 1;
1228  curretsu += 1;
1229  if(curretsu >= nretsu) {
1230    if (cannaconf.CursorWrap)
1231      curretsu = 0;
1232    else {
1233      NothingChangedWithBeep(d);
1234      return;
1235    }
1236  }
1237  /* kindex ¤¬¥«¥ì¥ó¥È¸õÊäÎó¤Î¸õÊä¿ô¤è¤êÂ礭¤¯¤Ê¤Ã¤Æ¤·¤Þ¤Ã¤¿¤é
1238     ºÇ±¦¸õÊä¤ò¥«¥ì¥ó¥È¸õÊä¤È¤¹¤ë */
1239  if(ic->glineifp[curretsu].glkosu <= kindex)
1240    kindex = ic->glineifp[curretsu].glkosu - 1;
1241  /* Á°¸õÊäÎó¤ÎƱ¤¸ÈÖ¹æ¤Ë°ÜÆ°¤¹¤ë */
1242  *(ic->curIkouho) = kindex + ic->glineifp[curretsu].glhead;
1243  return;
1244}
1245
1246/*
1247 * ¸õÊä¹ÔÃæ¤ÎÀèƬ¸õÊä¤Ë°ÜÆ°¤¹¤ë
1248 *
1249 * °ú¤­¿ô	uiContext
1250 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
1251 */
1252int IchiranBeginningOfKouho(uiContext d)
1253{
1254  ichiranContext ic = (ichiranContext)d->modec;
1255
1256  if (ic->flags & ICHIRAN_ALLOW_CALLBACK &&
1257      d->list_func) {
1258    int res;
1259    res = (*d->list_func)
1260      (d->client_data, CANNA_LIST_BeginningOfLine, (WCHAR_T **)0, 0,(int *)0);
1261    if (res) {
1262      return 0;
1263    }
1264    else { /* CANNA_LIST_Backward was not prepared at the callback func */
1265      return IchiranKakuteiThenDo(d, CANNA_FN_BeginningOfLine);
1266    }
1267  }
1268
1269  if(ic->tooSmall) {
1270    d->status = AUX_CALLBACK;
1271    return 0;
1272  }
1273
1274  /* ¸õÊäÎó¤ÎÀèƬ¸õÊä¤ò¥«¥ì¥ó¥È¸õÊä¤Ë¤¹¤ë */
1275  *(ic->curIkouho) =
1276    ic->glineifp[ic->kouhoifp[*(ic->curIkouho)].khretsu].glhead;
1277
1278  makeGlineStatus(d);
1279  /* d->status = EVERYTIME_CALLBACK; */
1280
1281  return 0;
1282}
1283
1284/*
1285 * ¸õÊä¹ÔÃæ¤ÎºÇ±¦¸õÊä¤Ë°ÜÆ°¤¹¤ë
1286 *
1287 * °ú¤­¿ô	uiContext
1288 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
1289 */
1290int IchiranEndOfKouho(uiContext d)
1291{
1292  ichiranContext ic = (ichiranContext)d->modec;
1293
1294  if (ic->flags & ICHIRAN_ALLOW_CALLBACK &&
1295      d->list_func) {
1296    int res;
1297    res = (*d->list_func)
1298      (d->client_data, CANNA_LIST_EndOfLine, (WCHAR_T **)0, 0, (int *)0);
1299    if (res) {
1300      return 0;
1301    }
1302    else { /* CANNA_LIST_Backward was not prepared at the callback func */
1303      return IchiranKakuteiThenDo(d, CANNA_FN_EndOfLine);
1304    }
1305  }
1306
1307  if(ic->tooSmall) {
1308    d->status = AUX_CALLBACK;
1309    return 0;
1310  }
1311
1312  /* ¸õÊäÎó¤ÎºÇ±¦¸õÊä¤ò¥«¥ì¥ó¥È¸õÊä¤Ë¤¹¤ë */
1313  *(ic->curIkouho) =
1314    ic->glineifp[ic->kouhoifp[*(ic->curIkouho)].khretsu].glhead
1315    + ic->glineifp[ic->kouhoifp[*(ic->curIkouho)].khretsu].glkosu - 1;
1316
1317  makeGlineStatus(d);
1318  /* d->status = EVERYTIME_CALLBACK; */
1319
1320  return 0;
1321}
1322
1323/*
1324 * ¸õÊä¹ÔÃæ¤ÎÆþÎϤµ¤ì¤¿ÈÖ¹æ¤Î¸õÊä¤Ë°ÜÆ°¤¹¤ë
1325 *
1326 * °ú¤­¿ô	uiContext
1327 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
1328 */
1329
1330static int getIchiranBangoKouho (uiContext);
1331static int IchiranBangoKouho (uiContext);
1332
1333static
1334int IchiranBangoKouho(uiContext d)
1335{
1336  ichiranContext ic = (ichiranContext)d->modec;
1337  int zflag, retval = 0;
1338
1339  if(ic->tooSmall) {
1340    d->status = AUX_CALLBACK;
1341    return(retval);
1342  }
1343
1344  /* d->status = EVERYTIME_CALLBACK; */
1345
1346  if (cannaconf.HexkeySelect && !(ic->inhibit & NUMBERING)) {
1347    /* ÆþÎϤµ¤ì¤¿ÈÖ¹æ¤Î¸õÊä¤ò¥«¥ì¥ó¥È¸õÊä¤È¤¹¤ë */
1348    if((zflag = getIchiranBangoKouho(d)) == NG)
1349      goto insert;
1350
1351    /* SelectDirect ¤Î¥«¥¹¥¿¥Þ¥¤¥º¤Î½èÍý */
1352  do_selection:
1353    if (cannaconf.SelectDirect) /* ON */ {
1354      if(zflag) /* £°¤¬ÆþÎϤµ¤ì¤¿ */
1355	retval = IchiranQuit(d);
1356      else
1357	retval = IchiranKakutei(d);
1358    } else {          /* OFF */
1359      makeGlineStatus(d);
1360      /* d->status = EVERYTIME_CALLBACK; */
1361    }
1362    return(retval);
1363  }
1364  else {
1365#ifdef CANNA_LIST_Insert /* ÀäÂÐÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤ó¤À¤±¤É¤Í */
1366    if (ic->flags & ICHIRAN_ALLOW_CALLBACK && d->list_func) {
1367      int res = (*d->list_func) /* list_func ¤ò¸Æ¤Ó½Ð¤¹ */
1368	(d->client_data, CANNA_LIST_Insert, (WCHAR_T **)0, d->ch, (int *)0);
1369      if (res) { /* d->ch ¤¬¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¦¤Ç½èÍý¤µ¤ì¤¿ */
1370	if (res == CANNA_FN_FunctionalInsert) {
1371	  zflag = 1; /* 0 ¤¸¤ã¤Ê¤±¤ì¤Ð¤¤¤¤ */
1372	  goto do_selection;
1373	}
1374	else if (res != CANNA_FN_Nop) {
1375	  /* ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¦¤«¤éÍ׵ᤷ¤ÆÍ褿µ¡Ç½¤ò³¤±¤Æ¼Â¹Ô¤¹¤ë */
1376	  d->more.todo = 1;
1377	  d->more.ch = d->ch;
1378	  d->more.fnum = CANNA_FN_FunctionalInsert;
1379	}
1380	return 0;
1381      }else{ /* CANNA_LIST_Insert was not processed at the callback func */
1382	/* continue to the 'insert:' tag.. */
1383      }
1384    }
1385#endif
1386
1387  insert:
1388    if(!(ic->inhibit & CHARINSERT) && cannaconf.allowNextInput) {
1389      BYTE ifl = ic->flags;
1390      retval = IchiranKakutei(d);
1391      if (ifl & ICHIRAN_STAY_LONG) {
1392	(void)IchiranQuit(d);
1393      }
1394      d->more.todo = 1;
1395      d->more.ch = d->ch;
1396      d->more.fnum = CANNA_FN_FunctionalInsert;
1397    } else {
1398      NothingChangedWithBeep(d);
1399    }
1400    return(retval);
1401  }
1402}
1403
1404/*
1405 * ¸õÊä¹ÔÃæ¤ÎÆþÎϤµ¤ì¤¿ÈÖ¹æ¤Î¸õÊä¤Ë°ÜÆ°¤¹¤ë
1406 *
1407 *
1408 * °ú¤­¿ô	uiContext
1409 * Ìá¤êÃÍ	£°¤¬ÆþÎϤµ¤ì¤¿¤é              £±¤òÊÖ¤¹
1410 * 		£±¡Á£¹¡¢£á¡Á£æ¤¬ÆþÎϤµ¤ì¤¿¤é  £°¤òÊÖ¤¹
1411 * 		¥¨¥é¡¼¤À¤Ã¤¿¤é              ¡¼£±¤òÊÖ¤¹
1412 */
1413static int
1414getIchiranBangoKouho(uiContext d)
1415{
1416  ichiranContext ic = (ichiranContext)d->modec;
1417  int num, kindex;
1418
1419  /* ÆþÎϥǡ¼¥¿¤Ï £°¡Á£¹ £á¡Á£æ ¤«¡© */
1420  if(((0x30 <= d->ch) && (d->ch <= 0x39))
1421     || ((0x61 <= d->ch) && (d->ch <= 0x66))) {
1422    if((0x30 <= d->ch) && (d->ch <= 0x39))
1423      num = (int)(d->ch & 0x0f);
1424    else if((0x61 <= d->ch) && (d->ch <= 0x66))
1425      num = (int)(d->ch - 0x57);
1426  }
1427  else {
1428    /* ÆþÎϤµ¤ì¤¿ÈÖ¹æ¤ÏÀµ¤·¤¯¤¢¤ê¤Þ¤»¤ó */
1429    return(NG);
1430  }
1431  /* ÆþÎϥǡ¼¥¿¤Ï ¸õÊä¹Ô¤ÎÃæ¤Ë¸ºß¤¹¤ë¿ô¤«¡© */
1432  if(num > ic->glineifp[ic->kouhoifp[*(ic->curIkouho)].khretsu].glkosu) {
1433    /* ÆþÎϤµ¤ì¤¿ÈÖ¹æ¤ÏÀµ¤·¤¯¤¢¤ê¤Þ¤»¤ó */
1434    return(NG);
1435  }
1436
1437  /* ÆþÎϤµ¤ì¤¿¿ô¤¬£°¤Ç SelectDirect ¤¬ ON ¤Ê¤éÆɤߤËÌᤷ¤Æ£±¤òÊÖ¤¹ */
1438  if(num == 0) {
1439    if (cannaconf.SelectDirect)
1440      return(1);
1441    else {
1442      /* ÆþÎϤµ¤ì¤¿ÈÖ¹æ¤ÏÀµ¤·¤¯¤¢¤ê¤Þ¤»¤ó */
1443      return(NG);
1444    }
1445  } else {
1446    /* ¸õÊäÎó¤ÎÀèƬ¸õÊä¤òÆÀ¤ë */
1447    kindex = ic->glineifp[ic->kouhoifp[*(ic->curIkouho)].khretsu].glhead;
1448    *(ic->curIkouho) = kindex + (num - 1);
1449  }
1450
1451  return(0);
1452}
1453
1454/*
1455 * ¸õÊä¹ÔÃ椫¤éÁªÂò¤µ¤ì¤¿¸õÊä¤ò¥«¥ì¥ó¥È¸õÊä¤È¤¹¤ë
1456 *
1457 * °ú¤­¿ô	uiContext
1458 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
1459 */
1460
1461// static IchiranKakutei (uiContext);
1462
1463static int
1464IchiranKakutei(uiContext d)
1465{
1466  ichiranContext ic = (ichiranContext)d->modec;
1467  int retval = 0;
1468  WCHAR_T *kakuteiStrings;
1469
1470  if ((ic->flags & ICHIRAN_ALLOW_CALLBACK) && d->list_func) {
1471    if (ic->flags & ICHIRAN_STAY_LONG) {
1472      d->list_func(d->client_data,
1473                     CANNA_LIST_Query, (WCHAR_T **)0, 0, (int *)0);
1474    }
1475    else {
1476      d->list_func(d->client_data,
1477                     CANNA_LIST_Select, (WCHAR_T **)0, 0, (int *)0);
1478    }
1479  }
1480
1481  kakuteiStrings = ic->allkouho[*(ic->curIkouho)];
1482  retval = d->nbytes = WStrlen(kakuteiStrings);
1483  WStrcpy(d->buffer_return, kakuteiStrings);
1484
1485  if (ic->flags & ICHIRAN_STAY_LONG) {
1486    ic->flags |= ICHIRAN_NEXT_EXIT;
1487    d->status = EVERYTIME_CALLBACK;
1488  }
1489  else {
1490    ichiranFin(d);
1491
1492    d->status = EXIT_CALLBACK;
1493  }
1494
1495  return(retval);
1496}
1497
1498/*
1499 * ¸õÊä¹Ôɽ¼¨¥â¡¼¥É¤«¤éÈ´¤±¤ë
1500 *
1501 * °ú¤­¿ô	uiContext
1502 * Ìá¤êÃÍ	Àµ¾ï½ªÎ»»þ 0	°Û¾ï½ªÎ»»þ -1
1503 */
1504void
1505ichiranFin(uiContext d)
1506{
1507  ichiranContext ic = (ichiranContext)d->modec;
1508
1509  /* ¸õÊä°ìÍ÷ɽ¼¨¹ÔÍѤΥ¨¥ê¥¢¤ò¥Õ¥ê¡¼¤¹¤ë */
1510  freeIchiranBuf(ic);
1511
1512  popIchiranMode(d);
1513
1514  /* gline ¤ò¥¯¥ê¥¢¤¹¤ë */
1515  GlineClear(d);
1516}
1517
1518static int IchiranExtendBunsetsu (uiContext);
1519
1520static
1521int IchiranExtendBunsetsu(uiContext d)
1522{
1523  return IchiranQuitThenDo(d, CANNA_FN_Extend);
1524}
1525
1526static int IchiranShrinkBunsetsu (uiContext);
1527
1528static
1529int IchiranShrinkBunsetsu(uiContext d)
1530{
1531  return IchiranQuitThenDo(d, CANNA_FN_Shrink);
1532}
1533
1534static int IchiranAdjustBunsetsu (uiContext);
1535
1536static
1537int IchiranAdjustBunsetsu(uiContext d)
1538{
1539  return IchiranQuitThenDo(d, CANNA_FN_AdjustBunsetsu);
1540}
1541
1542static int IchiranKillToEndOfLine (uiContext);
1543
1544static
1545int IchiranKillToEndOfLine(uiContext d)
1546{
1547  return IchiranKakuteiThenDo(d, CANNA_FN_KillToEndOfLine);
1548}
1549
1550static int IchiranDeleteNext (uiContext);
1551
1552static
1553int IchiranDeleteNext(uiContext d)
1554{
1555  return IchiranKakuteiThenDo(d, CANNA_FN_DeleteNext);
1556}
1557
1558static int IchiranBubunMuhenkan (uiContext);
1559
1560static
1561int IchiranBubunMuhenkan(uiContext d)
1562{
1563  return IchiranQuitThenDo(d, CANNA_FN_BubunMuhenkan);
1564}
1565
1566static int IchiranHiragana (uiContext);
1567
1568static
1569int IchiranHiragana(uiContext d)
1570{
1571  return IchiranQuitThenDo(d, CANNA_FN_Hiragana);
1572}
1573
1574static int IchiranKatakana (uiContext);
1575
1576static
1577int IchiranKatakana(uiContext d)
1578{
1579  return IchiranQuitThenDo(d, CANNA_FN_Katakana);
1580}
1581
1582static int IchiranZenkaku (uiContext);
1583
1584static
1585int IchiranZenkaku(uiContext d)
1586{
1587  return IchiranQuitThenDo(d, CANNA_FN_Zenkaku);
1588}
1589
1590static int IchiranHankaku (uiContext);
1591
1592static
1593int IchiranHankaku(uiContext d)
1594{
1595  return IchiranQuitThenDo(d, CANNA_FN_Hankaku);
1596}
1597
1598static int IchiranRomaji (uiContext);
1599
1600static
1601int IchiranRomaji(uiContext d)
1602{
1603  return IchiranQuitThenDo(d, CANNA_FN_Romaji);
1604}
1605
1606static int IchiranToUpper (uiContext);
1607
1608static
1609int IchiranToUpper(uiContext d)
1610{
1611  return IchiranQuitThenDo(d, CANNA_FN_ToUpper);
1612}
1613
1614static int IchiranToLower (uiContext);
1615
1616static
1617int IchiranToLower(uiContext d)
1618{
1619  return IchiranQuitThenDo(d, CANNA_FN_ToLower);
1620}
1621
1622static int IchiranCapitalize (uiContext);
1623
1624static
1625int IchiranCapitalize(uiContext d)
1626{
1627  return IchiranQuitThenDo(d, CANNA_FN_Capitalize);
1628}
1629
1630static int IchiranKanaRotate (uiContext);
1631
1632static
1633int IchiranKanaRotate(uiContext d)
1634{
1635  return IchiranQuitThenDo(d, CANNA_FN_KanaRotate);
1636}
1637
1638static int IchiranRomajiRotate (uiContext);
1639
1640static
1641int IchiranRomajiRotate(uiContext d)
1642{
1643  return IchiranQuitThenDo(d, CANNA_FN_RomajiRotate);
1644}
1645
1646static int IchiranCaseRotateForward (uiContext);
1647
1648static
1649int IchiranCaseRotateForward(uiContext d)
1650{
1651  return IchiranQuitThenDo(d, CANNA_FN_CaseRotate);
1652}
1653
1654#include	"ichiranmap.h"
1655