// OVIMChewing03.cpp // This package is released under the Artistic License, // please refer to LICENSE.txt for the terms of use and distribution // #define OV_DEBUG #include #include #include #include #include #include #include #include #include #include // #include #include "chewingio.h" #include "mod_aux.h" int ChewingFileExist(const char *path, const char *file) { char buf[PATH_MAX]; sprintf(buf, "%s/%s", path, file); struct stat st; if (stat(buf, &st)) return 0; // doesn't exist return 1; } int ChewingCheckData(const char *path) { char *files[5]={"ch_index.dat", "dict.dat", "fonetree.dat", "ph_index.dat", "us_freq.dat"}; for (int i=0; i<5; i++) if (!ChewingFileExist(path, files[i])) return 0; return 1; } class OVIMChewing03; class OVIMChewing03Context : public OVInputMethodContext { public: OVIMChewing03Context(OVIMChewing03 *p, ChewingContext *ctx) { p=parent; im=ctx; } virtual void start(OVBuffer *key, OVCandidate *textbar, OVService *srv) { } virtual void clear() { chewing_handle_Enter(im); } virtual void end() { chewing_handle_Enter(im); } virtual int keyEvent(OVKeyCode *key, OVBuffer *buf, OVCandidate *textbar, OVService *srv) { if(key->isCommand()) return 0; KeyPress(key,buf,textbar,srv); // if(im->KeystrokeIgnore()) return 0; CandidateWindow(textbar, srv); Redraw(buf, srv); return 1; } protected: void KeyPress(OVKeyCode *key, OVBuffer *buf, OVCandidate *textbar, OVService *srv) { int k = key->code(); Capslock(key,buf,textbar,srv); if(k == ovkSpace) { chewing_handle_Space(im); } else if (k == ovkLeft) { chewing_handle_Left(im); } else if (k == ovkRight) { chewing_handle_Right(im); } else if (k == ovkDown) { chewing_handle_Down(im); } else if (k == ovkEsc) { chewing_handle_Esc(im); } else if (k == ovkTab) { chewing_handle_Tab(im); } else if (k == ovkHome) { chewing_handle_Home(im); } else if (k == ovkEnd) { chewing_handle_End(im); } else if (k == ovkDelete || k == ovkBackspace) { chewing_handle_Del(im) ; } else if (k == ovkReturn) { chewing_handle_Enter(im); } else { DefaultKey(key,buf,textbar,srv); } } void DefaultKey(OVKeyCode *key, OVBuffer *buf, OVCandidate *textbar, OVService *srv) { if(key->isCtrl()) { if((key->code() >= '0') && (key->code() <= '9')) { chewing_handle_CtrlNum( im, (key->code())); } return; } chewing_handle_Default(im ,(key->isShift())?toupper(key->code()):tolower(key->code())); } void Capslock(OVKeyCode *key, OVBuffer *buf, OVCandidate *textbar, OVService *srv) { if(key->isCapslock()) { chewing_handle_Capslock( im ); } } void Redraw(OVBuffer *buf, OVService *srv) { //const char *s1,*s2,*s3; /* if(im->CommitReady()) { const char *s = im->CommitStr(); buf->clear()->append(s)->send(); } */ if ( chewing_commit_Check( im ) ) { const char *s = chewing_commit_String( im ); buf->clear()->append(s)->send(); } /* int ps=-1, pe=-1, ips=im->PointStart(), ipe=im->PointEnd(); if (ips > -1 && ipe !=0) { if (ipe > 0) { ps=ips; pe=ps+ipe; } else { ps=ips+ipe; pe=ips; } } */ const char *s= chewing_buffer_String( im ); buf->clear()->append(s)->update(); // murmur("ips=%d, ipe=%d, ps=%d, pe=%d\n", ips, ipe, ps, pe); /* s1 = srv->toUTF8("big5", im->Buffer(0,im->CursorPos()-1)); buf->clear()->append(s1); s2 = srv->toUTF8("big5", im->ZuinStr()); buf->append(s2); s3 = srv->toUTF8("big5", im->Buffer(im->CursorPos())); buf->append(s3)->update(im->CursorPos(), ps, pe); */ // murmur("==> %s%s%s",s1,s2,s3); } void CandidateWindow(OVCandidate *textbar, OVService *srv) { if(chewing_cand_TotalPage(im) > 0) { /* char s[64]; char *ch, selkey; */ int i=1; char str[ 20 ]; char *cand_string; textbar->clear(); chewing_cand_Enumerate( im ); while ( chewing_cand_hasNext( im ) ) { if ( i == chewing_cand_ChoicePerPage( im ) ) break; sprintf( str, "%d.", i ); textbar->append( str ); cand_string = chewing_cand_String( im ); sprintf( str, " %s ", cand_string ); textbar->append( str ); free( cand_string ); i++; } /* sprintf(s," %d/%d",im->CurrentPage() + 1,im->TotalPage()); textbar->append((char*)s); */ textbar->update(); textbar->show(); } else { textbar->hide(); } } protected: OVIMChewing03 *parent; ChewingContext *im; }; class OVIMChewing03 : public OVInputMethod { public: OVIMChewing03() { ctx=NULL; } virtual ~OVIMChewing03() { delete ctx; } virtual int initialize(OVDictionary* l, OVService* s, const char* modulePath) { char chewingpath[PATH_MAX]; char hashdir[PATH_MAX]; ChewingConfigData config; // no more need to create hash dir ourselves sprintf(hashdir, "%s%s", s->userSpacePath(identifier()), s->pathSeparator()); sprintf(chewingpath, "%sOVIMChewing03", modulePath); if (!ChewingCheckData(chewingpath)) { murmur("OVIMChewing: chewing data missing at %s", modulePath); return 0; } murmur ("OVIMChewing: initialize, chewing data=%s, userhash=%s", chewingpath, hashdir); // BECAUSE THE {SACRILEGIOUS WORDS HERE} libchewing HAS NO // EXCEPTION HANDLING HERE (BLAME OLD C-style assert() !!) // WE HAVE TO DO ERROR CHECKING OURSELVES, OTHERWISE WE ARE // DOOMED IF CHEWING DATA DOESN'T EXIST. THIS MAKES OUR LIFE // HARD BUT WE SHOULD TRY NOT TO COMPLAIN // chew = new Chewing(chewingpath, hashdir); chewing_Init(chewingpath, hashdir); ctx = chewing_new(); if(!l->keyExist("keyboardLayout")) l->setInteger("keyboardLayout", 0); chewing_set_KBType( ctx, l->getInteger("keyboardLayout")); //chew->SetKeyboardLayout(l->getInteger("keyboardLayout")); config.selectAreaLen = 20; config.maxChiSymbolLen = 16; // int i; /* for ( i = 0; i < 10; i++ ) config.selKey[ i ] = selKey_define[ i ]; */ /* Enable configurations */ chewing_Configure( ctx, &config ); return 1; } virtual void update(OVDictionary* localconfig, OVService*) { chewing_set_KBType( ctx, localconfig->getInteger("keyboardLayout")); // chew->SetKeyboardLayout(localconfig->getInteger("keyboardLayout")); } virtual const char *identifier() { return "OVIMChewing03"; } virtual const char *localizedName(const char *locale) { if (!strcasecmp(locale, "zh_TW")) return "酷音 0.3"; if (!strcasecmp(locale, "zh_CN")) return "繁体酷音 0.3"; return "Chewing (Smart Phonetics)"; } virtual OVInputMethodContext* newContext() { return new OVIMChewing03Context(this, ctx); } protected: ChewingContext *ctx; }; // the module wrapper OV_SINGLE_MODULE_WRAPPER(OVIMChewing03);