Mercurial > kinput2.yaz
view lib/Xsj3clib/conv.c @ 0:92745d501b9a
initial import from kinput2-v3.1
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 08 Mar 2010 04:44:30 +0900 |
parents | |
children |
line wrap: on
line source
#ifndef lint static char *rcsid = "$Id: conv.c,v 2.12 1993/09/21 09:43:15 nao Exp $"; #endif /* * Copyright 1991 Sony Corporation * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Sony not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Sony makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * SONY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SONY * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Author: Naoshi Suzuki, SONY Corporation. (nao@sm.sony.co.jp) */ #include <ctype.h> #include "common.h" #include "sj3ctype.h" #include "util.h" #include "segment.h" #include "mode.h" #include "func.h" extern Xsj3cCVServerIF serverIF[SERVER_NUM]; unsigned char *Xsj3cGetPreeditArea(); Xsj3cEvent Xsj3cKeyConv(); int _Xsj3cRomaConv(); int _Xsj3cKanaConv(); static Xsj3cEvent _Xsj3cStrConv(); static Xsj3cEvent _Xsj3cCtrlConv(); static Xsj3cEvent _Xsj3cThrough(); static Xsj3cEvent _Xsj3cDirect(); static int _Xsj3cCodeConv(); /* * Xsj3cGetPreeditArea() * Get area for pre-edit string. */ unsigned char * Xsj3cGetPreeditArea(buf, len) register Xsj3cBuf buf; register int *len; { register Xsj3cSeg seg; if (buf->convmode == DictModeMask) { /* $B<-=q%b!<%I$N>l9g$O<-=qFI$_MQ$NF~NO$r9T$&(B */ seg = buf->dict->seg; } else if (buf->convmode != SelectModeMask) { if (buf->input[buf->curseg] && buf->input[buf->curseg]->status == SEG_CONVED) { /* $B8=J8@a$,JQ49:Q$_$N>l9g(B */ buf->convmode = ConvedModeMask; switch (buf->flushiconv) { case ON: /* FlushInConversion on $B$N;~$O8=:_JQ49Cf$N(B */ /* $BJ8$r3NDj$7$F?75,$NJ8$NF~NO$r9T$&(B */ if (!buf->backup) { if ((buf->backup = (Xsj3cSeg *)calloc(BUNBUFSIZ, sizeof(Xsj3cSeg))) == NULL) { Xsj3cError("Cannot allocate for backup buffers"); } } if (seg = buf->backup[0]) { *seg->str = '\0'; seg->sp = seg->str; *seg->oldstr = '\0'; seg->oldlen = 0; seg->n_roma = 0; seg->n_kana = -1; } else seg = buf->backup[0] = (Xsj3cSeg)Xsj3cCreateSegment(buf); break; case EDIT: /* FlushInConversion edit $B$N;~$O%+%l%s%H(B */ /* $BJ8@a$X$NF~NO$r9T$&(B */ if (!(seg = buf->input[buf->curseg])) { seg = buf->input[buf->curseg] = (Xsj3cSeg)Xsj3cCreateSegment(buf); } else { *seg->str = '\0'; seg->sp = seg->str; *seg->oldstr = '\0'; seg->oldlen = 0; seg->n_roma = 0; seg->n_kana = -1; } break; case OFF: case NONE: default: /* FlushInConversion none/off $B$N>l9g!"?7$?$J(B*/ /* $BJ8@a$NFI$_J8;zNs$NF~NO$r9T$&(B */ if (seg = buf->input[buf->segnum]) { Xsj3cClearSegment(buf, buf->input[buf->segnum]); } else { seg = buf->input[buf->segnum] = (Xsj3cSeg)Xsj3cCreateSegment(buf); } break; } } else if (buf->segnum > 0) { /* $B8=J8@a$,L$JQ49$GF~NOJ8;z$,$"$k>l9g(B */ buf->convmode = InputModeMask; if (buf->input[buf->curseg] && (buf->input[buf->curseg]->edit & SEG_NOEDIT)) { /* $BJ8;zF~NO$r5v$5$l$F$$$J$$J8@a$N>l9g(B */ switch (buf->flushiconv) { case ON: /* FlushInConversion on $B$N;~$O8=:_JQ49Cf$N(B */ /* $BJ8$r3NDj$7$F?75,$NJ8$NF~NO$r9T$&(B */ if (!buf->backup) { if ((buf->backup = (Xsj3cSeg *)calloc(BUNBUFSIZ, sizeof(Xsj3cSeg))) == NULL) { Xsj3cError("Cannot allocate for backup buffers"); } } if (seg = buf->backup[0]) { *seg->str = '\0'; seg->sp = seg->str; *seg->oldstr = '\0'; seg->oldlen = 0; seg->n_roma = 0; seg->n_kana = -1; } else seg = buf->backup[0] = (Xsj3cSeg)Xsj3cCreateSegment(buf); break; case EDIT: if (!(seg = buf->input[buf->curseg])) seg = buf->input[buf->curseg] = (Xsj3cSeg)Xsj3cCreateSegment(buf); break; case OFF: case NONE: default: if (seg = buf->input[buf->segnum]) { Xsj3cClearSegment(buf, buf->input[buf->segnum]); } else seg = buf->input[buf->segnum] = (Xsj3cSeg)Xsj3cCreateSegment(buf); } } else { /* $B%+%l%s%HJ8@a$X$NF~NO$r9T$&(B */ if (!(seg = buf->input[buf->curseg])) seg = buf->input[buf->curseg] = (Xsj3cSeg)Xsj3cCreateSegment(buf); } } else { /* $BF~NOJ8;z$,$J$$>l9g(B */ buf->convmode = NoInputModeMask; /* New segment(first segment) */ if (seg = buf->input[buf->curseg]) Xsj3cClearSegment(buf, buf->input[buf->curseg]); else seg = buf->input[buf->curseg] = (Xsj3cSeg)Xsj3cCreateSegment(buf); } } else { /* SelectMode */ switch (buf->selectstatus) { case SELECT_CAND: /* $B8uJdA*Br$N>l9g(B */ switch (buf->flushsconv) { case ON: /* FlushSelectConversion on $B$N;~$O8=:_JQ49(B */ /* $BCf$NJ8$r3NDj$7$F?75,$NJ8$NF~NO$r9T$&(B */ if (!buf->backup) { if ((buf->backup = (Xsj3cSeg *)calloc(BUNBUFSIZ, sizeof(Xsj3cSeg))) == NULL) { Xsj3cError("Cannot allocate for backup buffers"); } } if (seg = buf->backup[0]) { *seg->str = '\0'; seg->sp = seg->str; *seg->oldstr = '\0'; seg->oldlen = 0; seg->n_roma = 0; seg->n_kana = -1; } else { seg = buf->backup[0] = (Xsj3cSeg)Xsj3cCreateSegment(buf); } break; case EDIT: /* FlushSelectConversion edit $B$N>l9g!"L5(B */ /* $BJQ49>uBV$K$7$F%+%l%s%HJ8@a$X$NF~NO$r9T$&(B */ if (!(seg = buf->input[buf->curseg])) { seg = buf->input[buf->curseg] = (Xsj3cSeg)Xsj3cCreateSegment(buf); } else { *seg->str = '\0'; seg->sp = seg->str; *seg->oldstr = '\0'; seg->oldlen = 0; seg->n_roma = 0; seg->n_kana = -1; } break; case OFF: case NONE: default: /* FlushSelectConversion none/off $B$N>l9g!"(B */ /* $B?7$?$JJ8@a$NFI$_J8;zNs$NF~NO$r9T$&(B */ if (seg = buf->input[buf->segnum]) { Xsj3cClearSegment(buf, buf->input[buf->segnum]); } else { seg = buf->input[buf->segnum] = (Xsj3cSeg)Xsj3cCreateSegment(buf); } break; } break; case SELECT_HINSI: /* $BIJ;lA*Br$N>l9g(B */ seg = buf->dict->seg; break; case SELECT_SYMBOL: default: /* $B5-9fA*Br$N>l9g(B */ if (seg = buf->input[buf->segnum]) { Xsj3cClearSegment(buf, buf->input[buf->segnum]); } else { seg = buf->input[buf->segnum] = (Xsj3cSeg)Xsj3cCreateSegment(buf); } break; } } *len = RBUFSIZ - (seg->sp - seg->str); buf->current = seg; return (seg->sp); } #define IsKanaKey(ks) ((unsigned)(ks) < 0xff00 && ((unsigned)(ks) & 0x0400)) #define IsLatin1Key(ks) ((unsigned)(ks) < 0x0100) /* * Xsj3cKeyConv() * Convert string or keysym and do function. */ Xsj3cEvent Xsj3cKeyConv(buf, n, mod, ks) Xsj3cBuf buf; int n; unsigned long mod; KeySym ks; { register Xsj3cKeyTable *keytp; Xsj3cSeg seg = buf->current; Xsj3cEvent ret = KEY_NULL; unsigned char *tmpsp; register int i, doflg; /* KeySym/Modifier$B!"8=:_$NJQ49%b!<%I$H3F%U%!%s%/%7%g%s(B */ /* $B$NBP1~%F!<%V%k$r%5!<%A$7$F9gCW$9$k$b$N$,$"$l$P%U%!%s(B */ /* $B%/%7%g%s$r<B9T$9$k!#(B */ for (keytp = buf->key, doflg = 0; keytp != NULL; keytp = keytp->next) { /* KeySym */ if (ks == keytp->ksym && /* Modifier Key */ (keytp->modmask & ~AllModeMask) == mod && /* Conversion mode */ (keytp->modmask & buf->convmode) == buf->convmode) { /* Do function */ doflg++; /* .key.func $B$NBh#3%U%#!<%k%I$,(B off $B$N;~$O%U%!%s%/%7%g%s(B */ /* $B$N$_<B9T$7!"(Bnone $B$N;~$O(B .InputSameTime $B$N;XDj$K0MB8$9$k(B */ /* InputSameTime off $B$N;~$O%U%!%s%/%7%g%s<B9T$9$k(B */ if (!buf->inputsame) { if (keytp->inputsame != ON) goto dofunc; } else { if (!keytp->inputsame) goto dofunc; } break; } } /* LookupString $B$N7k2L$O(B NULL terminate */ /* $B$7$F$$$J$$$N$G(B NULL terminate $B$5$;$k(B */ tmpsp = seg->sp; i = n; while(i--) { if (iscntrl(*tmpsp)) { if (buf->throughflg == QUOTE) { ret |= KEY_CONTROL; tmpsp++; continue; } /* ControlSameTime off $B$N>l9g$O(B */ /* $B%U%!%s%/%7%g%s$N$_<B9T(B */ if (doflg && !buf->cntrlsame) goto dofunc; else { ret = _Xsj3cCtrlConv(buf, *tmpsp); if (buf->cntrlsame) goto dofunc; else return (ret); } } tmpsp++; } *tmpsp = '\0'; if (!n || !(IsKanaKey(ks)||(IsLatin1Key(ks)))) { /* $B%F%-%9%H$KJQ49$G$-$J$+$C$?>l9g$O(B */ /* $B%U%!%s%/%7%g%s$N$_<B9T(B */ goto dofunc; } switch (buf->convmode) { case SelectModeMask: switch (buf->selectstatus) { case SELECT_CAND: /* $B8uJdA*Br$N>l9g(B */ switch (buf->flushsconv) { case ON: ret |= (KEY_SELECT_END|KEY_TEXT_CHANGE); for (i = 1; i < buf->backsegnum + 1; i++) { Xsj3cFreeSegment(buf->backup[i]); buf->backup[i] = NULL; } seg->yomi[0] = '\0'; seg->disp[0] = '\0'; seg->num = 0; seg->cur = 0; seg->dnum = 0; seg->status = SEG_NOCONV; seg->cursegmode = buf->inputmode; seg->change = OFF; seg->edit = SEG_NOEDIT; bzero(&seg->dcid, sizeof(seg->dcid)); buf->backsegnum = 1; ret |= KEY_TEXT_FLUSH; if (buf->dispmodechange) { buf->dispmode = buf->inputmode; ret |= KEY_MODE_CHANGE; } break; case EDIT: ret |= (KEY_SELECT_END|KEY_TEXT_CHANGE); if (buf->curseg == buf->segnum) buf->segnum++; else { ret |= _Xsj3cUnConvSeg(buf, ONE, buf->editcurlast); _Xsj3cStoreYomi(buf, buf->input[buf->curseg], 0); } break; case OFF: ret |= (KEY_SELECT_END|KEY_TEXT_CHANGE); if (buf->dispmodechange) { buf->dispmode = buf->convedsegnum ? MODE_EDIT : buf->inputmode; ret |= KEY_MODE_CHANGE; } break; case NONE: default: goto dofunc; } break; case SELECT_HINSI: /* $BIJ;lA*Br$N>l9g(B */ ret |= (KEY_DICT_CHANGE|KEY_SELECT_ABORT); buf->dict->status = DICT_INPUT; if (buf->dispmodechange) { buf->dispmode = (buf->dict->mode == REG_STATE ? MODE_TOROKU : MODE_SYOUKYO); ret |= KEY_MODE_CHANGE; } break; case SELECT_SYMBOL: default: /* $B5-9fA*Br$N>l9g(B */ goto dofunc; } break; case DictModeMask: if (buf->dict->status != DICT_INPUT) { /* $B<-=qEPO?!?>C5n%b!<%I$G$h$_F~NO;~$G$J$$(B */ /* $B$H$-$O$rJV$7$F$J$K$b$7$J$$!#(B */ goto dofunc; } ret |= KEY_DICT_CHANGE; seg->edit = SEG_EDIT; ret = _Xsj3cStrConv(buf, seg, ks, n, ret); _Xsj3cFlushDictMsg(buf); goto dofunc; case ConvedModeMask: ret |= KEY_TEXT_CHANGE; if (buf->candidate) Xsj3cEndCandidate(buf, ON); switch (buf->flushiconv) { case ON: for (i = 1; i < buf->backsegnum + 1; i++) { Xsj3cFreeSegment(buf->backup[i]); buf->backup[i] = NULL; } seg->yomi[0] = '\0'; seg->disp[0] = '\0'; seg->num = 0; seg->cur = 0; seg->dnum = 0; seg->status = SEG_NOCONV; seg->cursegmode = buf->inputmode; seg->change = OFF; seg->edit = SEG_NOEDIT; bzero(&seg->dcid, sizeof(seg->dcid)); buf->backsegnum = 1; ret |= KEY_TEXT_FLUSH; if (buf->dispmodechange) { buf->dispmode = buf->inputmode; ret |= KEY_MODE_CHANGE; } break; case OFF: buf->curseg = buf->segnum; buf->segnum++; if (buf->dispmodechange) { buf->dispmode = (buf->convedsegnum ? MODE_EDIT : buf->inputmode); ret |= KEY_MODE_CHANGE; } break; case EDIT: if (buf->curseg == buf->segnum) buf->segnum++; else { ret |= _Xsj3cUnConvSeg(buf, ONE, buf->editcurlast); _Xsj3cStoreYomi(buf, seg, 0); } break; case NONE: default: goto dofunc; } break; case InputModeMask: ret |= KEY_TEXT_CHANGE; if (buf->input[buf->curseg]->edit & SEG_NOEDIT) { switch (buf->flushiconv) { case ON: for (i = 1; i < buf->backsegnum + 1; i++) { Xsj3cFreeSegment(buf->backup[i]); buf->backup[i] = NULL; } seg->yomi[0] = '\0'; seg->disp[0] = '\0'; seg->num = 0; seg->cur = 0; seg->dnum = 0; seg->status = SEG_NOCONV; seg->cursegmode = buf->inputmode; seg->change = OFF; seg->edit = SEG_NOEDIT; bzero(&seg->dcid, sizeof(seg->dcid)); buf->backsegnum = 1; ret |= KEY_TEXT_FLUSH; break; case OFF: buf->curseg = buf->segnum; buf->segnum++; if (buf->dispmodechange) { buf->dispmode = buf->convedsegnum ? MODE_EDIT : buf->inputmode; ret |= KEY_MODE_CHANGE; } break; case EDIT: if (buf->curseg == buf->segnum) buf->segnum++; break; case NONE: default: goto dofunc; } } else if (buf->curseg == buf->segnum) buf->segnum++; break; case NoInputModeMask: if (buf->curseg == buf->segnum) buf->segnum++; if (buf->throughflg == THROUGH) { ret |= _Xsj3cThrough(buf, seg, n); buf->throughflg = OFF; goto dofunc; } ret |= KEY_TEXT_CHANGE; break; default: Xsj3cWarning ("Unknown conversion mode"); goto dofunc; } seg->edit = SEG_EDIT; ret = _Xsj3cStrConv(buf, seg, ks, n, ret); dofunc: if (doflg && !(ret & KEY_TEXT_FLUSH)) { ret |= ((*(keytp->func))(buf)); if (!buf->cntrlsame) ret |= KEY_FUNC; } return (ret); } /* * _Xsj3cStrConv() * Convert pre-edit strings and store results to yomi/disp buffer. */ static Xsj3cEvent _Xsj3cStrConv(buf, seg, ks, n, ret) Xsj3cBuf buf; Xsj3cSeg seg; KeySym ks; int n; Xsj3cEvent ret; { register unsigned char *tmpsp; unsigned char tmp1[YBUFSIZ]; unsigned char tmp2[YBUFSIZ]; unsigned char kanabuf[YBUFSIZ]; wchar wcs[RBUFSIZ]; register int i; int change_pos; int change_roma = 0; if (buf->throughflg == QUOTE) { ret |= _Xsj3cDirect(buf, seg, n); buf->throughflg = OFF; return (ret); } if (seg->num > seg->size - YBUFSIZ) Xsj3cResizeSegment(seg, seg->size + KANABUFSIZ); switch (buf->inputmode) { case MODE_HIRA: case MODE_ZKATA: case MODE_HKATA: /* $B$R$i$,$J!?A43Q%+%?%+%J!?H>3Q%+%?%+%JF~NO%b!<%I$N>l9g(B */ if (IsKanaKey(ks) || (IsLatin1Key(ks) && buf->kanaonly)) { /* $B$+$JF~NO$N>l9g(B */ int len; if (seg->n_roma) { /* $B$+$J%P%C%U%!(B(seg->str)$B$K%m!<%^;zF~NO;~$N(B */ /* $BJ8;zNs$,;D$C$F$$$k>l9g$O$=$l$r:o=|$9$k(B */ i = n; tmpsp = seg->sp; while (i--) { *(tmpsp - seg->n_roma) = *tmpsp; tmpsp++; } *(tmpsp - seg->n_roma) = '\0'; seg->sp = seg->sp - seg->n_roma; seg->n_roma = 0; } if (buf->inputmode == MODE_HKATA) { /* $BH>3Q%+%?%+%JF~NO%b!<%I$N$H$-$O(B */ /* $BJQ49$r9T$o$J$$$GFI$_%P%C%U%!$K%3%T!<(B */ if (IsKanaKey(ks)) strcpy(tmp1, seg->sp); else _Xsj3cHAlphaToHKata(buf, tmp1, seg->sp); seg->sp = seg->str; *seg->oldstr= '\0'; seg->n_kana = -1; change_pos = seg->cur; _Xsj3cInsertChar(buf, seg, tmp1, strlen(tmp1)); } else { /* $B$R$i$,$J!?A43Q%+%?%+%JF~NO%b!<%I$N;~$OH>3Q(B */ /* $B%+%?%+%J"*$R$i$,$J!?A43Q%+%?%+%JJQ49$r9T$&(B */ if (IsLatin1Key(ks)) { strcpy(tmp2, seg->sp); _Xsj3cHAlphaToHKata(buf, seg->sp, tmp2); } if ((seg->value = _Xsj3cKanaConv(buf, seg, seg->str, tmp1, buf->inputmode)) > 0) { /* $BH>3Q%+%?%+%J"*$R$i$,$JJQ49$,@.8y$7$?>l9g(B */ /* $BBy2;!?H>By2;$N>l9g(B */ seg->sp = seg->str; if (seg->n_kana > 0) { _Xsj3cExtractChar(buf, seg, tmp2, seg->n_kana); strcpy(seg->oldstr, seg->str); tmpsp = seg->oldstr; while(*tmpsp != '\0') tmpsp++; *(tmpsp - seg->n_kana) = '\0'; } else { *seg->oldstr = '\0'; } seg->n_kana = 0; } else if (seg->value == 0) { /* $BH>3Q%+%?%+%J"*$R$i$,$J!?A43Q%+%?%+%J(B */ /* $BJQ49$N7k2L$,ITDj$N>l9g(B */ if (seg->n_kana > 0) _Xsj3cExtractChar(buf, seg, tmp2, seg->n_kana); tmpsp = seg->sp + n - 1; seg->sp = seg->str; *seg->sp = *tmpsp; *(++seg->sp) = '\0'; seg->n_kana = 1; *seg->oldstr = '\0'; } else { /* $BH>3Q%+%?%+%J"*$R$i$,$JJQ49$,@.8y$7$?>l9g(B */ /* $BBy2;!?H>By2;$G$J$$>l9g(B */ if (seg->n_kana > 0) _Xsj3cExtractChar(buf, seg, tmp2, seg->n_kana); seg->sp = seg->str; *seg->oldstr = '\0'; seg->n_kana = 0; } change_pos = seg->cur; len = _Xsj3cmPStowPS(buf, wcs, tmp1); _Xsj3cInsertWchar(seg, wcs, len); } seg->n_roma = 0; } else if (IsLatin1Key(ks)) { /* $B%m!<%^;zF~NO$N>l9g(B */ if (seg->n_kana > 0) { /* $B%m!<%^;z%P%C%U%!(B(seg->str)$B$K$+$JF~NO;~$N(B */ /* $BJ8;zNs$,;D$C$F$$$k>l9g$O$=$l$r:o=|$9$k(B */ i = n; tmpsp = seg->sp; while (i--) { *(tmpsp - seg->n_kana) = *tmpsp; tmpsp++; } *(tmpsp - seg->n_kana) = '\0'; seg->sp = seg->sp - seg->n_kana; seg->n_kana = -1; } /* $BF~NO%b!<%I$K4X78$J$/$+$JJQ49$r9T$&(B */ if ((seg->value = _Xsj3cRomaConv(buf->rktable, seg->str, kanabuf)) > 0) { /* ROMA->$B$+$J(B $BJQ49$,@.8y$7$?>l9g(B */ if (buf->alphaconv) { /* AlphabetConversion $B%j%=!<%9$,(B on */ /* $B$@$C$?$iA43Q$rH>3Q$KJQ49$9$k(B */ _Xsj3cExtractChar(buf, seg, tmp1, seg->n_roma); _Xsj3cZAlphaToHAlpha(buf, seg->oldstr, tmp1); } else { _Xsj3cExtractChar(buf, seg, seg->oldstr, seg->n_roma); } change_pos = seg->cur; if (buf->inputmode == MODE_HIRA) { /* $B$R$i$,$JF~NO%b!<%I$N$H$-$O$=$N$^$^(B */ /* $BFI$_%P%C%U%!$K%3%T!<(B */ seg->oldlen = _Xsj3cmPStowPS(buf, wcs, kanabuf); } else if (buf->inputmode == MODE_ZKATA) { /* $BA43Q%+%?%+%JF~NO%b!<%I$N$H$-$O(B */ /* $B$R$i$,$J$rA43Q%+%?%+%J$KJQ49(B */ _Xsj3cHiraToZKata(buf, tmp1, kanabuf); seg->oldlen = _Xsj3cmPStowPS(buf, wcs, tmp1); } else { /* $BH>3Q%+%?%+%JF~NO%b!<%I$N;~$O$R$i$,$J(B */ /* $B!?A43Q%+%?%+%J$rH>3Q%+%?%+%J$KJQ49(B */ _Xsj3cZKanaToHKata(buf, tmp1, kanabuf); seg->oldlen = _Xsj3cmPStowPS(buf, wcs, tmp1); } _Xsj3cInsertWchar(seg, wcs, seg->oldlen); seg->n_roma = 0; /* $BJQ49$G$-$J$$J8;z$,%m!<%^;z%P%C%U%!$K;D$C$F(B */ /* $B$$$?$i!JNc!V$C!W$KJQ49$5$l$k>l9gEy!K(B */ /* $B$+$J%P%C%U%!$N:G8e$K$=$NJ8;z$rIUM?$9$k(B */ if (*seg->str != '\0') { _Xsj3cInsertChar(buf, seg, seg->str, strlen(seg->str)); seg->sp = seg->str; while (*seg->sp != '\0') { seg->sp++; seg->n_roma++; } change_roma = seg->n_roma; } else { seg->sp = seg->str; } } else if (seg->value == 0) { /* ROMA$B"*$+$JJQ49$N7k2L$,ITDj$N>l9g(B */ change_pos = seg->cur; _Xsj3cInsertChar(buf, seg, seg->sp, n); i = n; while (i--) { seg->sp++; seg->n_roma++; } change_roma = n; } else { /* ROMA$B"*$+$J(B $BJQ49$N7k2L$,IT@.8y$N>l9g(B */ /* $B:G8e$NF~NO$,%m!<%^$+$JJQ49$N8uJd$H(B */ /* $B$7$FM-8z$+$I$&$+D4$Y$k(B */ change_pos = seg->cur; if ((seg->value = _Xsj3cRomaConv(buf->rktable, seg->sp, kanabuf)) > 0) { /* $B:G8e$NF~NO$,%m!<%^$+$JJQ49$N8uJd$H$7$F(B */ /* $BM-8z$J>l9g(B */ if (buf->inputmode == MODE_HIRA) { /* $B$R$i$,$JF~NO%b!<%I$N$H$-$O$=$N$^$^(B */ /* $BFI$_%P%C%U%!$K%3%T!<(B */ seg->oldlen = _Xsj3cmPStowPS(buf, wcs, kanabuf); } else if (buf->inputmode == MODE_ZKATA) { /* $BA43Q%+%?%+%JF~NO%b!<%I$N$H$-$O(B */ /* $B$R$i$,$J$rA43Q%+%?%+%J$KJQ49(B */ _Xsj3cHiraToZKata(buf, tmp1, kanabuf); seg->oldlen = _Xsj3cmPStowPS(buf, wcs, tmp1); } else { /* $BH>3Q%+%?%+%JF~NO%b!<%I$N;~$O$R$i$,$J(B */ /* $B!?A43Q%+%?%+%J$rH>3Q%+%?%+%J$KJQ49(B */ _Xsj3cZKanaToHKata(buf, tmp1, kanabuf); seg->oldlen = _Xsj3cmPStowPS(buf, wcs, tmp1); } _Xsj3cInsertWchar(seg, wcs, seg->oldlen); seg->n_roma = 0; /* $BJQ49$G$-$J$$J8;z$,%m!<%^;z%P%C%U%!$K;D$C$F(B */ /* $B$$$?$i!JNc!V$C!W$KJQ49$5$l$k>l9gEy!K(B */ /* $B$+$J%P%C%U%!$N:G8e$K$=$NJ8;z$rIUM?$9$k(B */ if (*seg->str != '\0') { _Xsj3cInsertChar(buf, seg, seg->str, strlen(seg->str)); seg->sp = seg->str; while (*seg->sp != '\0') { seg->sp++; seg->n_roma++; } change_roma = seg->n_roma; } else { seg->sp = seg->str; } } else if (seg->value == 0) { /* $B%m!<%^$+$JJQ49$N8uJd$H$7$FL$Dj$N>l9g(B */ /* $B:G8e$NF~NOJ8;z$r%m!<%^"*$+$JJQ49MQ$N(B */ /* $B%P%C%U%!(B(seg->str)$B$K;D$9(B */ change_pos = seg->cur; _Xsj3cInsertChar(buf, seg, seg->sp, n); *seg->oldstr = '\0'; tmpsp = seg->str; *seg->str = *seg->sp; seg->sp = seg->str; i = n; while (i--) *tmpsp++ = *seg->sp++; *tmpsp = '\0'; seg->n_roma = n; change_roma = seg->n_roma; } else { /* $B%m!<%^$+$JJQ49$N8uJd$H$7$FL58z$J>l9g(B */ _Xsj3cInsertChar(buf, seg, seg->sp, n); *seg->oldstr = '\0'; seg->n_roma = 0; *seg->str = '\0'; seg->sp = seg->str; /* rkbell $B%j%=!<%9$,(B on $B$K@_Dj$5$l$F(B */ /* $B$$$k>l9g%Y%k$rLD$i$9(B */ if (buf->rkbell) ret |= KEY_BELL; change_roma = n; } } /* AlphabetConversion $B%j%=!<%9$,(B on */ /* $B$@$C$?$iH>3Q%m!<%^;z$rA43Q%m!<%^;z$KJQ49$9$k(B */ if (buf->alphaconv && buf->inputmode != MODE_HKATA && change_roma) { _Xsj3cExtractChar(buf, seg, tmp1, change_roma); _Xsj3cHAlphaToZKana(buf, tmp2, tmp1); _Xsj3cInsertChar(buf, seg, tmp2, change_roma); } /* $B$+$JF~NO%b!<%I$G$J$$$H$-$O(B -1 */ seg->n_kana = -1; } else { return (KEY_NULL); } break; case MODE_HALPHA: /* $BH>3Q%"%k%U%!%Y%C%H(B $BF~NO%b!<%I$N>l9g(B */ if (IsKanaKey(ks)) return (KEY_BELL); change_pos = seg->cur; _Xsj3cInsertChar(buf, seg, seg->sp, n); seg->sp = seg->str; seg->n_roma = 0; seg->n_kana = -1; break; case MODE_ZALPHA: /* $BA43Q%"%k%U%!%Y%C%H(B $BF~NO%b!<%I$N>l9g(B */ if (IsKanaKey(ks)) return (KEY_BELL); _Xsj3cHAlphaToZAlpha(buf, tmp1, seg->sp); seg->sp = seg->str; change_pos = seg->cur; _Xsj3cInsertChar(buf, seg, tmp1, n); seg->n_roma = 0; seg->n_kana = -1; break; case MODE_SJIS: case MODE_EUC: case MODE_JIS: case MODE_KUTEN: /* $B%3!<%IF~NO%b!<%I$N>l9g(B */ tmpsp = seg->str; while (*tmpsp != '\0') { if (!isxdigit(*tmpsp) || (buf->inputmode == MODE_KUTEN && !isdigit(*tmpsp))) return (KEY_BELL); tmpsp++; } /* $B%3!<%I"*$R$i$,$J!?A43Q%+%?%+%J!?5-9f!?4A;z$NJQ49$r9T$&(B */ if ((seg->value = _Xsj3cCodeConv(buf, seg->str, kanabuf, buf->inputmode)) > 0) { /* $B%3!<%IJQ49$K@.8y$7$?>l9g(B */ if (buf->alphaconv) { /* AlphabetConversion $B%j%=!<%9$,(B on $B$@$C$?$i(B */ /* $BA43Q?t;z$rH>3Q?t;z$KJQ49$9$k(B */ _Xsj3cExtractChar(buf, seg, tmp1, seg->n_roma); _Xsj3cZAlphaToHAlpha(buf, seg->oldstr, tmp1); } else { _Xsj3cExtractChar(buf, seg, seg->oldstr, seg->n_roma); } change_pos = seg->cur; seg->oldlen = (strlen(kanabuf) + 1)/ sizeof(wchar); _Xsj3cInsertChar(buf, seg, kanabuf, seg->oldlen); seg->cursegmode = MODE_HIRA; seg->n_roma = 0; seg->sp = seg->str; } else if (seg->value == 0) { /* $B%3!<%IJQ49$N7k2L$,ITDj$N>l9g(B */ change_pos = seg->cur; if (buf->alphaconv) { /* AlphabetConversion $B%j%=!<%9$,(B on $B$@$C$?$i(B */ /* $BH>3Q?t;z$rA43Q?t;z$KJQ49$9$k(B */ _Xsj3cHAlphaToZKana(buf, tmp1, seg->sp); _Xsj3cInsertChar(buf, seg, tmp1, n); } else { _Xsj3cInsertChar(buf, seg, seg->sp, n); } i = n; while (i--) { seg->n_roma++; seg->sp++; } } else { /* $B%3!<%IJQ49$N7k2L$,<:GT$N>l9g(B */ _Xsj3cExtractChar(buf, seg, tmp1, seg->n_roma); change_pos = seg->cur; seg->sp = seg->str; seg->n_roma = 0; if (seg->num == 0 && buf->convmode != DictModeMask) { Xsj3cFreeSegment(seg); seg = NULL; buf->segnum--; for (i = buf->curseg; i < buf->segnum; i++) { buf->input[i] = buf->input[i + 1]; } buf->input[buf->segnum] = NULL; return ret; } if (buf->rkbell) ret |= KEY_BELL; } seg->n_kana = -1; break; default: Xsj3cWarning("Illegal current mode"); return (KEY_BELL); } /* $BI=<(MQJ8;zNs$X%3%T!<$9$k(B */ _Xsj3cStoreYomi(buf, seg, change_pos); return ret; } /* * _Xsj3cKanaConv() * Kana input mode dispatch routine. */ int _Xsj3cKanaConv(buf, seg, hkana, zkana, mode) Xsj3cBuf buf; Xsj3cSeg seg; unsigned char *hkana, *zkana; Xsj3csMode mode; { register int len, zlen; register wchar s; if (mode == MODE_HIRA) { if (buf->alphaconv) _Xsj3cHankakuToHira(buf, zkana, hkana); else _Xsj3cHKataToHira(buf, zkana, hkana); } else { if (buf->alphaconv) _Xsj3cHankakuToZKata(buf, zkana, hkana); else _Xsj3cHKataToZKata(buf, zkana, hkana); } len = 0; while (*hkana != '\0') { hkana++; len++; } if (isdakuon(*(hkana - 1))) { return 0; } else { zlen = 0; while (*zkana != '\0') { zkana++; zlen++; } if (zlen > 1) { s = (*(zkana - 2) << 8) + (*(zkana - 1) & 0xff); if (seg->n_kana && (iszdakuten(s, serverIF[buf->server].lang) || !isdakuten(*(hkana - 1)))) return -1; else return len; } else { return -1; } } } /* * _Xsj3cCodeConv() * Code input mode dispatch routine. */ static int _Xsj3cCodeConv(buf, code, kanji, mode) Xsj3cBuf buf; register unsigned char *code; register unsigned char *kanji; Xsj3csMode mode; { register int i, j, len; register wchar k, (*conv)(); register unsigned char c1, c2; unsigned char kbuf[4]; if ((len = strlen(code)) < 4 && (mode == MODE_EUC || mode == MODE_KUTEN)) return CONV_UNFIXED; else if ((len < 2 || len == 3) && (mode == MODE_SJIS || mode == MODE_JIS)) return CONV_UNFIXED; k = 0; for (j = 0; j < 4 && *code != '\0'; code++, j++) { if (isdigit(*code)) i = *code - '0'; else if (islower(*code)) i = 10 + *code - 'a'; else if (isupper(*code)) i = 10 + *code - 'A'; else return CONV_FAILED; kbuf[j] = i; k += i << ((3 - j) * 4); } switch (mode) { case MODE_SJIS: if (len == 4 && issjis1(c1 = (k >> 8)) && issjis2(c2 = (k & 0xff))) { if (conv = CodeConvFunc[JP_SJIS][serverIF[buf->server].lang]) { k = conv(k); *kanji++ = k >> 8; *kanji++ = k & 0xff; *kanji = '\0'; } else { *kanji++ = c1; *kanji++ = c2; *kanji = '\0'; } } else if (iskana(k >> 8)) { *kanji++ = k >> 8; *kanji = '\0'; } else { if (len < 4) return CONV_UNFIXED; else return CONV_FAILED; } break; case MODE_EUC: if (iseuc(k >> 8) && iseuc(k & 0xff)) { if (conv = CodeConvFunc[JP_EUC][serverIF[buf->server].lang]) k = conv(k); *kanji++ = k >> 8; *kanji++ = k & 0xff; *kanji = '\0'; } else if (iseuckana(k >> 8) && iskana2(k & 0xff)) { *kanji++ = k & 0xff; *kanji = '\0'; } else { return CONV_FAILED; } break; case MODE_JIS: if (len == 4 && isjis(c1 = (k >> 8)) && isjis(c2 = (k & 0xff))) { if (conv = CodeConvFunc[JP_JIS8][serverIF[buf->server].lang]) { k = conv(k); *kanji++ = k >> 8; *kanji++ = k & 0xff; *kanji = '\0'; } else { *kanji++ = c1; *kanji++ = c2; *kanji = '\0'; } } else if (iskana(k >> 8)) { *kanji++ = k >> 8; *kanji = '\0'; } else { if (len < 4) return CONV_UNFIXED; else return CONV_FAILED; } break; case MODE_KUTEN: conv = CodeConvFunc[JP_JIS8][serverIF[buf->server].lang]; c1 = kbuf[0] * 10 + kbuf[1]; c2 = kbuf[2] * 10 + kbuf[3]; k = (c1 << 8) + c2; k = conv(k + 0x2020); if (iskan1(c1 = (k >> 8), serverIF[buf->server].lang) && iskan2(c2 = (k & 0xff), serverIF[buf->server].lang)) { *kanji++ = c1; *kanji++ = c2; *kanji = '\0'; } else { return CONV_FAILED; } break; default: Xsj3cWarning("Illegal mode"); return CONV_FAILED; } return CONV_FIXED; } #define MATCH 0 #define NOT 1 /* * _Xsj3cRomaConv() * Get roman characters from the second argument and put back hiragana or * katakana characters to the third argument in conversion table. * If roman characters (third argument) mach with the "roma" entry in table, * put back the "str" entry to the third argument and the "yomi" entry * to the third argument, then it returns number of converted roman * characters. * If not but any letters of roman characters is match with the "roma" * entry in table and the number of roman characters is less than * the number of the letters of "roma" entry, put back the same to * the third argument and nothing to the third argument, then it returns * zero. * Then last (not converted case) it returns minus 1. * Any arguments must be null('\0') terminated. * First argument is pointer to conversion table; */ int _Xsj3cRomaConv(rktable, roma, yomi) Xsj3cRKTable *rktable; register unsigned char *roma; register unsigned char *yomi; { Xsj3cRKTable *rktp; register unsigned char *p, *q; unsigned char tmp[RBUFSIZ]; int match, result = CONV_FAILED; register int len; if (!roma || (len = strlen(roma)) == 0) return (CONV_FAILED); for (rktp = rktable; rktp != NULL; rktp = rktp->next) { if (!rktp->roma) { continue; } p = roma; q = rktp->roma; if (len > rktp->rlen) { if (*q++ == *p++) { match = MATCH; while (*q != '\0') { if (*q != *p) { match = NOT; break; } q++; p++; } if (match == NOT) { continue; } if (result < 0) { result = rktp->rlen; strcpy(yomi, rktp->yomi); strcpy(tmp, p); } else { continue; } } else { continue; } } else { if (*p++ == *q++) { match = MATCH; while (*p != '\0') { if (*p++ != *q++) { match = NOT; break; } } if (match == NOT) { continue; } if (*q != '\0') { result = CONV_UNFIXED; continue; } else if (result == CONV_UNFIXED) { continue; } else { result = rktp->rlen; strcpy(yomi, rktp->yomi); strcpy(tmp, rktp->str); } } else { continue; } } } if (result > 0) strcpy(roma, tmp); return (result); } /* * _Xsj3cCtrlConv() * * <NoInputMode> Through all control events. * <InputMode> Put the control code (now only HT & NL) after current position, * then fix all segments. * <ConvedMode> Put the control code (now only HT & NL) after current segment, * then fix all segments and end convertion. * <SelectMode/DictMode> Does Nothing. * * DisplayModeChange on: Change the display mode string. * ThroughNext code: * SetNormal code: */ static Xsj3cEvent _Xsj3cCtrlConv(buf, code) Xsj3cBuf buf; unsigned char code; { unsigned char ch[2]; register unsigned char *c; int change_pos; register int i; if (code == '\t' || code == '\n') goto compound_text; if (buf->throughnext) { c = buf->throughnext; while (*c != '\0') { if (*c == code) { buf->throughflg = THROUGH; if (buf->dispmodechange) { buf->dispmode = buf->inputmode; #ifdef THROUGH_CONT return (KEY_TEXT_CLEAR|KEY_CONTROL|KEY_MODE_CHANGE); } else { return (KEY_TEXT_CLEAR|KEY_CONTROL); #else /* THROUGH_CONT */ return (KEY_NULL); } else { return (KEY_NULL); #endif /* THROUGH_CONT */ } } c++; } } if (buf->setnormal) { c = buf->setnormal; while (*c != '\0') { if (*c == code) { if (buf->dispmodechange) { buf->dispmode = buf->inputmode; #ifdef THROUGH_CONT return (KEY_TEXT_FIXED|KEY_CONTROL|KEY_HENKAN_END |KEY_MODE_CHANGE); } else { return (KEY_TEXT_FIXED|KEY_CONTROL|KEY_HENKAN_END); #else /* THROUGH_CONT */ return (KEY_NULL); } else { return (KEY_NULL); #endif /* THROUGH_CONT */ } } c++; } } /* Through all control events by XtNunusedEventCallback */ return (KEY_NULL); /* Push by compound text */ compound_text: switch (buf->convmode) { case NoInputModeMask: buf->convmode = InputModeMask; case InputModeMask: if (buf->segnum == buf->curseg) buf->segnum++; ch[0] = code; ch[1] = '\0'; change_pos = buf->input[buf->curseg]->cur; _Xsj3cInsertChar(buf, buf->input[buf->curseg], ch, 1); _Xsj3cStoreYomi(buf, buf->input[buf->curseg], change_pos); if (buf->dispmodechange) { buf->dispmode = buf->inputmode; return (KEY_TEXT_FIXED|KEY_TEXT_CHANGE|KEY_MODE_CHANGE); } else return (KEY_TEXT_FIXED|KEY_TEXT_CHANGE); case ConvedModeMask: i = buf->input[buf->curseg]->dnum; buf->input[buf->curseg]->disp[i++] = code; buf->input[buf->curseg]->disp[i] = '\0'; buf->input[buf->curseg]->dnum++; if (buf->dispmodechange) { buf->dispmode = buf->inputmode; return (KEY_TEXT_FIXED|KEY_TEXT_CHANGE|KEY_MODE_CHANGE); } else return (KEY_TEXT_FIXED|KEY_TEXT_CHANGE); case DictModeMask: case SelectModeMask: default: return (KEY_NULL); } } /* * _Xsj3cThrough() * Store characters to yomi/disp buffer and fix. */ static Xsj3cEvent _Xsj3cThrough(buf, seg, n) Xsj3cBuf buf; Xsj3cSeg seg; int n; { int change_pos; change_pos = seg->cur; _Xsj3cInsertChar(buf, seg, seg->str, n); _Xsj3cStoreYomi(buf, seg, change_pos); return (KEY_TEXT_FIXED); } /* * _Xsj3cDirect() * Store characters to yomi/disp buffer. * * DisplayModeChange on: Change the display mode string. */ static Xsj3cEvent _Xsj3cDirect(buf, seg, n) Xsj3cBuf buf; Xsj3cSeg seg; int n; { Xsj3cEvent ret = KEY_TEXT_CHANGE; int change_pos; change_pos = seg->cur; _Xsj3cInsertChar(buf, seg, seg->str, n); _Xsj3cStoreYomi(buf, seg, change_pos); *seg->str = '\0'; seg->sp = seg->str; *seg->oldstr = '\0'; seg->oldlen = 0; seg->n_roma = 0; seg->n_kana = -1; if (buf->dispmodechange) { buf->dispmode = (buf->convedsegnum == buf->segnum ? MODE_KANJI : (buf->convedsegnum ? MODE_EDIT : buf->inputmode)); ret |= KEY_MODE_CHANGE; } return (ret); }