// OVIMBig5.cpp: Big-5 Code Input Method // 2005-2006 By Weizhong Yang // // This program is Zonble-ware and adopts Zonble's License // -- "How could a person who doesn't even believe in law adopt any license?" #include #include #include #include #ifndef WIN32 #include #include #else #include "OpenVanilla.h" #include "OVLibrary.h" #define strcasecmp stricmp #endif extern unsigned short OVIMBig5Table[19582][2]; unsigned int convert(unsigned int in) { //Convert Big5 to Unicode int i; for (i =0; i< 19582 ; i++) { if(OVIMBig5Table[i][0] == in) return OVIMBig5Table[i][1]; } return 0; } class OVIMBig5; const size_t ebMaxKeySeq=4; class KeySeq { public: KeySeq() { clear(); } void add(char c) { if (len == ebMaxKeySeq) return; buf[len++]=c; buf[len]=0; } void remove() { if (!len) return; buf[--len]=0; } void clear() { len=0; buf[0]=0; } char buf[ebMaxKeySeq]; size_t len; }; class OVBig5Context : public OVInputMethodContext { public: virtual void start(OVBuffer*, OVCandidate*, OVService*) { clear(); } virtual void clear() { keyseq.clear(); } virtual int keyEvent(OVKeyCode *key, OVBuffer *buf, OVCandidate *textbar, OVService *srv) { if (key->isOpt() || key->isCommand() || key->isCtrl()) return 0; if (key->code()==ovkReturn || key->code()==ovkSpace) { if (!(strlen(keyseq.buf))) return 0; // empty buffer, do nothing unsigned short i = convert(strtol(keyseq.buf, (char **) NULL, 16)); keyseq.clear(); if(i) { buf->clear()->append(srv->UTF16ToUTF8(&i, 1))->send()->clear(); textbar->clear()->hide(); } else { buf->clear()->update(); textbar->clear()->hide(); srv->notify("Sorry. No such code!"); srv->beep(); } return 1; // key processed } if (key->code()==ovkEsc) { keyseq.clear(); buf->clear()->update();; textbar->clear()->hide(); return 1; } if (key->code()==ovkDelete || key->code()==ovkBackspace) { if(!strlen(keyseq.buf)) return 0; keyseq.remove(); if(!strlen(keyseq.buf)) textbar->clear()->hide(); else textbar->clear()->append((char *)"[Big5 Hex] ")->append(keyseq.buf)->update()->show(); buf->clear()->append(keyseq.buf)->update(); return 1; } if(strlen(keyseq.buf) >= ebMaxKeySeq) return 1; // Max to 4 letters. if (isprint(key->code())) { if((key->code()>='a'&&key->code()<='f') || (key->code()>='0'&&key->code()<='9')) { keyseq.add(key->code()); buf->clear()->append(keyseq.buf)->update(); textbar->clear()->append((char *)"[Big5 Hex] ")->append(keyseq.buf)->update()->show(); } else { srv->beep(); } return 1; // key processed } return 0; // key not processed } protected: KeySeq keyseq; }; class OVIMBig5 : public OVInputMethod { public: virtual const char* identifier() { return "OVIMBig5"; } virtual const char* localizedName(const char *locale) { if (!strcasecmp(locale, "zh_TW")) return "Big5 內碼"; else if (!strcasecmp(locale, "zh_CN")) return "Big5 内码"; return "Big5 Hexadecimal"; } virtual OVInputMethodContext* newContext() { return new OVBig5Context; } }; OV_SINGLE_MODULE_WRAPPER(OVIMBig5);