/*
Copyright (c)
1987,1988,1989,1990,1991,1992,1993,1994 Electrotechnical Laboratory
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice and this permission notice
appear in all versions of this software.
Author: Yutaka Sato Electrotechnical Laboratory
<ysato@etl.go.jo>
*/
/*######################################################################*
* *
* Onew for Nihongo text Entry with Wnn *
* *
*######################################################################*/
#define STATIC static
#include <stdio.h>
#include <ctype.h>
#include "onew.h"
int ONEW_DEBUG;
int ONEW_MSGHOLD;
int ONEW_RK_THRU;
int ONEW_NN_THRU;
int ONEW_THRUSYMS_ON;
int ONEW_2BYTES_ONLY;
int ONEW_IN_ISO2022;
int ONEW_MODE_SWITCHER = Cntl('\\');
int ONEW_ROMKAN_TOGGLE = Cntl('@');
int ONEW_KANA_TOGGLE = Cntl('K');
int ONEW_ZENKAKU_TOGGLE = Cntl('L');
int ONEW_SELECT_YANK = Cntl('Y');
int ONEW_RKKSERV_SW = 'Q';
int ONEW_MODESW_CALL = Cntl('Z');
int ONEW_THRU_NEXTCH = Cntl('V');
int ONEW_HENKAN_START = Cntl('W');
int ONEW_THRUSYMS_SETUP = Cntl('@');
int THRUSYMS_TOGGLE = Cntl('^');
/* internally generated commands */
int ONEW_I_ESC = Cntl(']');
int ONEW_I_KAKUTEI = Cntl('_');
int ONEW_I_THRU_NEXTCH = Cntl('C');
int ONEW_I_SYNC_CHAR = 0xFF;
int ONEW_KK_OPDICT = 'x';
static definedKanamode();
static romkan_modesw();
static thru_char1();
static Onew_kakuteiInRomkan();
#define MODE_SWITCHER ONEW_MODE_SWITCHER
#define ZENKAKU_TOGGLE ONEW_ZENKAKU_TOGGLE
#define KANA_TOGGLE ONEW_KANA_TOGGLE
#define ROMKAN_TOGGLE ONEW_ROMKAN_TOGGLE
char *ONEW_HENKANKEYS = "[ ]";
char ONEW_HENKANKEYA[256];
#define IS_NOINS_HENKANKEY(ch) (ch == ONEW_HENKAN_START || ch == STD_HENKAN)
#define IS_INS_HENKANKEY(ch) (ch && ONEW_HENKANKEYA[ch])
#define IS_HENKANKEY(ch) (IS_NOINS_HENKANKEY(ch)||IS_INS_HENKANKEY(ch))
#define LET_IT_THRU(ch) (ONEW_THRUSYMS_ON && Onew_isTHRU(ch))
static romkan_ready(){
romkan_select();
return oeiRomkanReady(0);
}
static kanakan_ready(){
kanakan_select();
return oeiKanakanReady();
}
/*######################################################################*
* Jisyo MODE *
*######################################################################*/
extern int OM_JisyoMode;
extern int OM_JisyoGetYomi;
extern int OM_JisyoGetTsuduri; /* touroku string input mode */
extern int OM_JisyoGetKanjiFlush;
extern int OM_JisyoMassyou;
#define OM_JisyoGetModes (OM_JisyoGetYomi || OM_JisyoGetTsuduri)
/*######################################################################*
* ROMKAN INTERFACE *
*######################################################################*/
/* romkan mode mnemonics */
#define RK_HIRA 'h'
#define RK_KATA 'k'
#define RK_LARGE 'l'
#define RK_THRU '@'
#define RK_OFF '-'
static Linebuff rawc_inbuff;
clr_keyinQ(){ return strQclr(rawc_inbuff); }
ins_keyinQ(c){ return strQins(rawc_inbuff,c); }
enq_keyinQ(c){ return strQenq(rawc_inbuff,c); }
deq_keyinQ(){ return strQdeq(rawc_inbuff); }
ready_keyinQ(){ return rawc_inbuff[0] != 0; }
char *romkan_cmode();
int ONEW_getch_asis; /* never interpret as command keys */
ONEW_getch0(asis){
int ch;
if( (ch = deq_keyinQ()) == EOF ){
if( !asis && !ONEW_getch_asis )
Onew_putmode(romkan_cmode(),0);
ch = OnewGetchar();
}
return ch;
}
ONEW_getch1(){
int ch;
for(;;){
ch = ONEW_getch0(ONEW_getch_asis);
if( ONEW_getch_asis )
break;
if( ch == ROMKAN_TOGGLE ){ romkan_toggle(); break; }else
if( ch == MODE_SWITCHER ){ romkan_modesw(); ch = 0; break; }else
if( ch == THRUSYMS_TOGGLE ){ sym_thru_toggle(); }else
if( ch == ONEW_MODESW_CALL){ ch = ONEW_HENKAN_START; break; }else
if( romkan_on() ){
if( IS_HENKANKEY(ch) && !IS_NOINS_HENKANKEY(ch) )
enq_keyinQ(ONEW_HENKAN_START);
if( definedKanamode(ch) ){ continue; }else
if( ch == KANA_TOGGLE ){ katakana_toggle(); continue; }else
if( ch == ZENKAKU_TOGGLE){ zenkaku_toggle(); continue; }else
if( ch == DEL_CH ) { ch = BS_CH; }else
if( ch == ESC_CH ) { oeiRomkanClear(); ch = ONEW_I_ESC; }else
if( in_kana_mode() ){
if( LET_IT_THRU(ch) && !IS_NOINS_HENKANKEY(ch) ){
thru_char1(ch);
continue;
}else
if( ch == 'Q' ){
switch_rkserv();
ch = 0;/* let the current Romkan exit */
}else
if( ch == 'q' || ch == ONEW_MODESW_CALL ){
OM_mode_switches();
ch = 0;
}else
switch( ch ){
case 'Z':
ins_zenkaku_char1(0,0);
continue;
/*
default:
if( 'A' <= ch && ch <= 'Y' )
if( katakana_toggle() ){
enq_keyinQ(ch-('A'-'a'));
continue;
}
*/
}
}
break;
}else
if( ch == Cntl('G') ){
/*pushQ(ONEW_HENKAN_START);*/
ch = ONEW_HENKAN_START;
break;
}else break;
}
return ch;
}
static IFUNC KanamodeSw[128];
static int kanamodes[16];
static int kanamodex;
static definedKanamode(ch)
unsigned char ch;
{ IFUNC func;
if( 128 <= ch )
return 0;
if( func = KanamodeSw[ch] )
return (*func)(ch);
return 0;
}
Onew_defineKanamode(mode,ch,func)
IFUNC func;
{
kanamodes[kanamodex++] = mode;
KanamodeSw[ch] = func;
}
static romkan_modesw(){
int cmode;
cmode = ONEW_getch1();
romkan_mode_switch(cmode);
}
static thru_char1(ch){
ins_keyinQ(ch);
ins_keyinQ(ONEW_I_THRU_NEXTCH);
}
ins_zenkaku_char1(ch,kakutei)
{ char buf[8],*bp;
if( ch == 0 )
OM_zenkaku1(buf);
else ONEWromkan_zenkaku(ch,buf);
for( bp = buf; *bp; bp++ )
enq_keyinQ(*bp);
if( kakutei )
enq_keyinQ(ONEW_I_KAKUTEI);
}
ONEWromkan_zenkaku(ch,dst)
char *dst;
{ char *tab,*jis;
if( 0x200 <= ch ){
dst[0] = ch;
dst[1] = 0;
}else{
jis = &ONEW_ASCII_TO_JIS[ch*2];
dst[0] = jis[0];
dst[1] = jis[1];
dst[2] = 0;
}
}
ASCII_TO_JIS(asc,jis)
char *asc,*jis;
{ char *a,*j;
char *jc;
int ac;
j = jis;
for( a = asc; ac = *a; a++ ){
if( 0x20 <= ac && ac < 0x7F ){
jc = &ONEW_ASCII_TO_JIS[ac*2];
*j++ = jc[0];
*j++ = jc[1];
}else *j++ = ac;
}
*j = 0;
}
Onew_HENKANKEYS(syms)
char *syms;
{
strMAPset(syms,ONEW_HENKANKEYA,"ONEW_HENKANKEYS",
ONEW_HENKANKEYS,0);
}
static Linebuff kana_inbuff;
Onew_deqchar(commandmode){
int ch;
if( (ch = strQdeq(kana_inbuff)) != EOF )
return ch;
if( commandmode || ONEW_RK_THRU )
if( 0 < Onew_inready(stdin,-1) )
return OnewGetchar();
return EOF;
}
Onew_enqchar(ch){
strQenq(kana_inbuff,ch);
}
Onew_enqstr(str) char *str; {
char *sp,ch;
for(sp = str; ch = *sp; sp++)
Onew_enqchar(ch);
}
Onew_asis_romkan_next(){
int kc;
ONEW_getch_asis = 1;
kc = oeiRomkanNext();
ONEW_getch_asis = 0;
return kc;
}
static int ROMKAN_INIT_DONE;
Onew_RK_init(){
char *env;
if( ROMKAN_INIT_DONE == 0 ){
if( env = getenv("ONEW_MSGHOLD") )
ONEW_MSGHOLD = atoi(env);
if( env = getenv("ONEW_MAXWORDS") )
ONEW_MAXWORDS = atoi(env);
Onew_HENKANKEYS(0);
Onew_THRUSYMS(0);
ONEW_NN_THRU = getenv("ONEW_NN_THRU") != 0;
ONEW_IN_ISO2022 = getenv("ONEW_NO_ISO2022") == 0;
ONEW_DEBUG = getenv("ONEW_DEBUG") != 0;
ROMKAN_INIT_DONE = romkan_ready();
keisen_init();
}
return 0 < ROMKAN_INIT_DONE;
}
kget_char1(){
unsigned int kc;
if( !Onew_RK_init() ){
kc = OnewGetchar();
ouiTrace("kget_char1.1","(%x)",kc);
return kc;
}
start:
if( (kc = Onew_deqchar(0)) != EOF ){
ouiTrace("kget_char1.2","(%x)",kc);
return kc;
}
if( ONEW_RK_THRU ){
kc = OnewGetchar();
ouiTrace("kget_char1.3","(%x)",kc);
return kc;
}
do{
if( romkan_on() )
kc = oeiRomkanGetc();
else kc = oeiRomkanNext();
/*###### KAKUTEI ######*/
if( kc=='\r' || kc=='\n' || kc==ONEW_I_KAKUTEI )
if( romkan_on() || OM_JisyoGetModes ){
if( Onew_kakuteiInRomkan(kc) )
goto start;
if( kc==ONEW_I_KAKUTEI )
goto start;
}
/*###### YANK ######*/
if( kc == ONEW_SELECT_YANK ){
Onew_getword(kc);
goto start;
}else
/*###### SELECT ######*/
if( romkan_on() && kc == Cntl('G') ){
char code[4];
if( 0 < OM_get_jisspecial(code) )
Onew_enqstr(code);
goto start;
}else
/*###### HENKAN ######*/
if( romkan_on() && IS_NOINS_HENKANKEY(kc)
|| kc == ONEW_HENKAN_START ){
if( !kanakan_ready() )
goto start;
kc = OM_kanakan(kc);
if( kc == ONEW_HENKAN_START ){
/* maybe q-a for empty buffer */
goto start;
}
if( kc == STD_HENKAN ){
if( ONEW_THRUSYMS_ON && Onew_isTHRU(kc) )
enq_keyinQ(ONEW_I_KAKUTEI);
else{
ins_zenkaku_char1(kc,1);
goto start;
}
}
}else
if( kc == ONEW_THRU_NEXTCH || kc == ONEW_I_THRU_NEXTCH ){
int nkc;
if( kc == ONEW_THRU_NEXTCH ){
nkc = OM_get_thruchar(1);
Onew_enqchar(kc);
}else nkc = OM_get_thruchar(0);
Onew_enqchar(nkc);
goto start;
}else{
kc = oeiRomkanGotch(kc);
if( kc == 0 )
continue;
if( kc == ONEW_I_ESC ){
if( odmAbort_touroku() )
goto start;
kc = ESC_CH;
}
if( in_kana_mode() )
if( ONEW_THRUSYMS_ON ){
/* enqueue kakutei control code if
there has been no JIS input */
/*enq_keyinQ(ONEW_I_KAKUTEI);*/
}else{
if( ' ' < kc && kc < 0x7F && !isalpha(kc) ){
ins_zenkaku_char1(kc,0);
kc = 0;
continue;
}
}
if( kc & 0xFF00 )
if((kc & 0xFF000000) == 0)/* not a control-code */
{
Linebuff buff;
ouiGOT_2BCHAR(buff,kc>>8,kc&0xFF);
Onew_enqstr(buff);
goto start;
}
}
}while(kc == 0);
ouiTrace("kget_char1.4","(%x)",kc);
return kc;
}
Onew_romkan(){
return kget_char1();
}
/*######################################################################*
* Romaji-Kana henkan MODE SWITCH *
*######################################################################*/
/*
* MODE FLAGS
*/
int ONEW_kanamode;
romkan_on(){
return ONEW_kanamode;
}
Onew_RK_imode(){
return romkan_on();
}
Onew_RK_imode_setv(imode)
{
ONEW_kanamode = imode;
}
romkanmode_ch(){
switch( ONEW_kanamode ){
case ZENKAKU: return RK_HIRA;
case ZENKAKU|KATAKANA: return RK_KATA;
case ZENKAKU| NOTKANA: return RK_LARGE;
default: return RK_THRU;
}
}
Onew_RK_cmode(){
return romkanmode_ch();
}
Onew_RK_imode_set(imode)
{
return oeiRomkanModesw(imode);
}
romkan_mode_switch(mode){
int new_kana_mode = 0;
switch( mode ){
default : new_kana_mode = 0; break;
case RK_HIRA: new_kana_mode = ZENKAKU; break;
case RK_KATA: new_kana_mode = ZENKAKU | KATAKANA; break;
case RK_LARGE: new_kana_mode = ZENKAKU | NOTKANA; break;
case RK_THRU: new_kana_mode = 0; break;
}
if( ONEW_kanamode && new_kana_mode )
oeiRomkanModesw(0);
oeiRomkanModesw(new_kana_mode);
}
Onew_RK_cmode_set(mode){
Onew_RK_init();
return romkan_mode_switch(mode);
}
romkan_toggle(){
if( ONEW_kanamode )
oeiRomkanModesw(0);
else oeiRomkanModesw(ZENKAKU);
}
Onew_RK_toggle(){
return romkan_toggle();
}
zenkaku_toggle(){
if( ONEW_kanamode & ZENKAKU ){
oeiRomkanModesw( ONEW_kanamode ^ NOTKANA );
}
}
in_kana_mode(){
int Kmode,ki,mode;
if( ONEW_kanamode == ZENKAKU
|| ONEW_kanamode ==(ZENKAKU|KATAKANA) )
return 1;
for( ki = 0; ki < kanamodex; ki++ )
if( ONEW_kanamode == kanamodes[ki] )
return 1;
return 0;
}
katakana_toggle(){
if( in_kana_mode() ){
ONEW_kanamode &= (ZENKAKU | KATAKANA);
oeiRomkanModesw(ONEW_kanamode ^ KATAKANA);
return 1;
}
return 0;
}
sym_thru_toggle(){
ONEW_THRUSYMS_ON = !ONEW_THRUSYMS_ON;
}
char *
ONEWromkan_smode(){
static char rkmode[8];
if(ROMKAN_INIT_DONE && ONEW_kanamode)
sprintf(rkmode,oeiRomkanDispmode(),rkEngineID());
else strcpy(rkmode,"[---]");
if( ONEW_THRUSYMS_ON )
if( rkmode[4] == ']' )
strcpy(&rkmode[4],"-]");
return rkmode;
}
char *Onew_RK_smode(){
return ONEWromkan_smode();
}
char *romkan_cmode(){
return Onew_RK_smode();
}
char *romkan_help(){
if( romkan_on() )
return ONEW_menu_romkana;
else return ONEW_menu_roman;
}
/*######################################################################*
* KANA-KAN *
*######################################################################*/
Onew_kanakan(com,str,start,leng)
char *str;
{
return Onew_kana_to_kanji(com,str,start,leng);
}
char ONEW_CurrentYomi[256];
char ONEW_CurrentKanji[1024];
Uchar ONEW_DicYomi[256];
Onew_kana_to_kanji(startcom,str)
Uchar *str;
{ Mssgbuff buf;
Uchar sstr[2048];
int endcom;
if( OM_JisyoGetYomi && startcom != STD_HENKAN ){
if( odmStart_touroku(str) )
OM_JisyoGetYomi = 0;
return 0;
}
if( OM_JisyoGetKanjiFlush ){
strcpy(ONEW_CurrentKanji,str);
OM_JisyoGetKanjiFlush = 0;
odmJisyo_touroku();
str = ONEW_DicYomi;
}
if( startcom != ONEW_HENKAN_START && Onew_non_ascii(str) == 0 ){
if( ONEW_THRUSYMS_ON && Onew_isTHRU(startcom) )
sprintf(buf,"%s%c",str,startcom);
else strcpy(buf,str);
ouiDISP_KANAKANB(0,buf,"","");
ouiKAKUTEI(ONEW_I_KAKUTEI);
return 0;
}
strcpy(sstr,str);
strcpy(ONEW_CurrentYomi,sstr);
for(;;){
endcom = oeiKanakan(startcom,str);
if( endcom == ONEW_RKKSERV_SW ){
switch_kkserv();
str = sstr;
continue;
}
if( endcom == ONEW_KK_OPDICT || endcom == 'q' ){
if( odmJisyo_sousa() ){
endcom = 0;
break;
}else{
str = sstr;
continue;
}
}
if( endcom != BS_CH && endcom != DEL_CH ){
if( OM_JisyoGetYomi ){
if( odmStart_touroku(ONEW_CurrentKanji) ){
OM_JisyoGetYomi = 0;
break;
}
}
if( OM_JisyoGetTsuduri ){
odmJisyo_touroku();
strcpy(sstr,ONEW_DicYomi);
str = sstr;
continue;
}
}
break;
}
ONEW_CurrentKanji[0] = 0;
return endcom;
}
Onew_kakutei(kc) /* invoked in Kana-Kanji translation */
{
return ouiKAKUTEI(kc);
}
static Onew_kakuteiInRomkan(kc)
{
if( OM_JisyoGetYomi ){
enq_keyinQ(ONEW_HENKAN_START);
return 1;
}
if( OM_JisyoGetTsuduri ){
if( ONEW_CurrentKanji[0] == 0 ){
OM_JisyoGetKanjiFlush = 1;
enq_keyinQ(ONEW_HENKAN_START);
return 1;
}
odmJisyo_touroku();
}
return ouiKAKUTEI(kc);
}
Onew_dispKanakanBuf(so,left,cur,right)
char *left,*cur,*right;
{ char xleft[1024],xright[1024];
sprintf(ONEW_CurrentKanji,"%s%s%s",left,cur,right);
if( so && OM_JisyoGetTsuduri ){
sprintf(xleft,"[%s",left);
left = xleft;
sprintf(xright,"%s]",right);
right = xright;
}
ouiDISP_KANAKANB(so,left,cur,right);
}
Onew_setupYomistr(com,str,yomibuf)
char *str,*yomibuf;
{ int len;
int lastch;
strcpy(yomibuf,str);
if( ONEW_THRUSYMS_ON && com != STD_HENKAN )
if( len = strlen(str) ){
lastch = str[len-1];
if( Onew_isTHRU(lastch) )
strcat(yomibuf," ");
}
}
Onew_freqsave(){
oeiKanakanFreqsave();
}
Onew_KK_freqsave(){
return Onew_freqsave();
}
Onew_RK_thru(mode){
ONEW_RK_THRU = mode;
}
Onew_inready( fp, wait_usec )
FILE *fp;
{
if( *rawc_inbuff || *kana_inbuff )
return 1;
/*
if( OnewPeekchar(1) != EOF )
return 1;
*/
return Onew_fp_input_ready(fp,wait_usec);
}
/************************************************************************
*/
int ONEW_modedepth;
Onew_modef(modes,xmodes,helps,xhelps)
char **modes,*xmodes;
char **helps,*xhelps;
{ int modef;
modef = ONEW_kanamode
| (ONEW_INCHAR_WIDTH==2 ? KF_2BINPUT : 0)
| (ONEW_THRUSYMS_ON ? KF_THRUSYMS : 0)
| (ONEW_NN_THRU ? KF_NN_THRU : 0)
| (ONEW_getch_asis ? KF_NEXTCHAR : 0)
| (ONEW_select_mode ? KF_SELECT : 0)
| (ONEW_kanakan_mode ? KF_KANAKAN : 0)
| (OM_JisyoMode ? KF_JISYO : 0)
| (OM_JisyoGetYomi ? KF_GETYOMI : 0)
| (OM_JisyoGetTsuduri ? KF_GETTSUDURI : 0)
| (OM_JisyoMassyou ? KF_MASSYOU : 0)
| ONEW_modedepth << 24;
if( *modes == 0 ) *modes = Onew_RK_smode();
if( *helps == 0 ) *helps = romkan_help();
if( OM_JisyoGetYomi ){
sprintf(xmodes,"%s%s",ONEW_mode_touroku_yomi,*modes);
*modes = xmodes;
}
if( OM_JisyoGetTsuduri ){
sprintf(xmodes,"%s%s",ONEW_mode_touroku_kanji,*modes);
*modes = xmodes;
sprintf(xhelps,"(%s) %s",ONEW_DicYomi,*helps);
*helps = xhelps;
}
return modef;
}
/************************************************************************
* OBSOLETE
*/
kana_init(){
return Onew_RK_init();
}
kana_to_kanji(str,start,leng)
{
return Onew_kana_to_kanji(0,str,start,leng);
}
syntax highlighted by Code2HTML, v. 0.9.1