/*************************************************************************** * Copyright (C) 2004 by TAM(Teppei Tamra) * * tam-t@par.odn.ne.jp * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "nicolainput.h" #include <sys/time.h> #ifdef HAVE_CONFIG_H #include <config.h> #endif // 国際化のおまじない。 #ifdef HAVE_GETTEXT #include <libintl.h> #define _(String) dgettext(GETTEXT_PACKAGE,String) #define N_(String) (String) #else #define _(String) (String) #define N_(String) (String) #define bindtextdomain(Package,Directory) #define textdomain(domain) #define bind_textdomain_codeset(domain,codeset) #endif // プライグイン化のおまじないです。 HonokaPluginRegister(NicolaInput); HonokaPluginSetup(NicolaInput); HonokaSetupCorePage *NicolaInput::setup() { HonokaSetupPage *page = new HonokaSetupPage(_("Nicola-plugin"),"",""); page->append(new HonokaSetupKeyItem( _("_Left KANA-Shift keys:"), HONOKA_CONFIG_NICOLAINPUT_LSHIFT, "", HONOKA_DEFAULT_NICOLAINPUT_LSHIFT )); page->append(new HonokaSetupKeyItem( _("_Right KANA-Shift keys:"), HONOKA_CONFIG_NICOLAINPUT_RSHIFT, "", HONOKA_DEFAULT_NICOLAINPUT_RSHIFT )); page->append(new HonokaSetupIntItem( _("_Simultaneously press timer:"), HONOKA_CONFIG_NICOLAINPUT_SPTIMER, "", HONOKA_DEFAULT_NICOLAINPUT_SPTIMER, 0,199 )); page->append(new HonokaSetupFileItem( _("Nicola _table: "), HONOKA_CONFIG_NICOLAINPUT_TABLE_FILE, _("input the path of Nicola table file."), HONOKA_DEFAULT_NICOLAINPUT_TABLE_FILE )); HonokaSetupPage *sc = new HonokaSetupPage(_("shortcut keys: "),"",""); sc->append(new HonokaSetupKeyItem( _("Nicola input: "), String(HONOKA_CONFIG_KEY_PREEDITOR_PREFIX) + String("/Nicola"), "", "" )); page->append(sc); return page; }; namespace Honoka { struct { KeyCode key; char noShift[6]; char leftShift[6]; char rightShift[6]; } _nicolaTable[] = { {SCIM_KEY_1,"1","?",""}, {SCIM_KEY_2,"2","/",""}, {SCIM_KEY_3,"3","~",""}, {SCIM_KEY_4,"4","「",""}, {SCIM_KEY_5,"5","」",""}, {SCIM_KEY_6,"6","","["}, {SCIM_KEY_7,"7","","]"}, {SCIM_KEY_8,"8","","("}, {SCIM_KEY_9,"9","",")"}, {SCIM_KEY_0,"0","","『"}, {SCIM_KEY_minus,"-","","』"}, {SCIM_KEY_backslash,"\\","",""}, {SCIM_KEY_q,"。","ぁ",""}, {SCIM_KEY_w,"か","え","が"}, {SCIM_KEY_e,"た","り","だ"}, {SCIM_KEY_r,"こ","ゃ","ご"}, {SCIM_KEY_t,"さ","れ","ざ"}, {SCIM_KEY_y,"ら","ぱ","よ"}, {SCIM_KEY_u,"ち","ぢ","に"}, {SCIM_KEY_i,"く","ぐ","る"}, {SCIM_KEY_o,"つ","づ","ま"}, {SCIM_KEY_p,",","ぴ","ぇ"}, {SCIM_KEY_at,"、","",""}, {SCIM_KEY_bracketleft,"゛","","゜"}, {SCIM_KEY_a,"う","を",""}, {SCIM_KEY_s,"し","あ","じ"}, {SCIM_KEY_d,"て","な","で"}, {SCIM_KEY_f,"け","ゅ","げ"}, {SCIM_KEY_g,"せ","も","ぜ"}, {SCIM_KEY_h,"は","ば","み"}, {SCIM_KEY_j,"と","ど","お"}, {SCIM_KEY_k,"き","ぎ","の"}, {SCIM_KEY_l,"い","ぽ","ょ"}, {SCIM_KEY_semicolon,"ん","","っ"}, {SCIM_KEY_z,".","ぅ",""}, {SCIM_KEY_x,"ひ","ー","び"}, {SCIM_KEY_c,"す","ろ","ず"}, {SCIM_KEY_v,"ふ","や","ぶ"}, {SCIM_KEY_b,"へ","ぃ","べ"}, {SCIM_KEY_n,"め","ぷ","ぬ"}, {SCIM_KEY_m,"そ","","ゆ"}, {SCIM_KEY_comma,"ね","ぺ","む"}, {SCIM_KEY_period,"ほ","ぼ","わ"}, {SCIM_KEY_slash,"・","","ぉ"}, {SCIM_KEY_NullKey,"","",""} // terminator }; } NicolaInput::NicolaInput(ConfigPointer cfg) : PreEditor(cfg) { bkt = 0; delay = cfg->read(HONOKA_CONFIG_NICOLAINPUT_SPTIMER,HONOKA_DEFAULT_NICOLAINPUT_SPTIMER); scim_string_to_key_list(LShiftKey,cfg->read(HONOKA_CONFIG_NICOLAINPUT_LSHIFT,String(HONOKA_DEFAULT_NICOLAINPUT_LSHIFT))); scim_string_to_key_list(RShiftKey,cfg->read(HONOKA_CONFIG_NICOLAINPUT_RSHIFT,String(HONOKA_DEFAULT_NICOLAINPUT_RSHIFT))); String table = cfg->read(HONOKA_CONFIG_NICOLAINPUT_TABLE_FILE,String(HONOKA_DEFAULT_NICOLAINPUT_TABLE_FILE)); LShift = false; RShift = false; if (table.length()) loadTable(table); if (!keymap.size()) { for(unsigned int i = 0;_nicolaTable[i].key != SCIM_KEY_NullKey;i ++) { NicolaKey k; k.noShift = utf8_mbstowcs(_nicolaTable[i].noShift); k.leftShift = utf8_mbstowcs(_nicolaTable[i].leftShift); k.rightShift = utf8_mbstowcs(_nicolaTable[i].rightShift); keymap.insert(pair<KeyEvent,NicolaKey>(_nicolaTable[i].key,k)); } } vsc = utf8_mbstowcs(String("゛")); svsc = utf8_mbstowcs(String("゜")); vs1 = utf8_mbstowcs(String("かきくけこさしすせそたちつてとはひふへほぱぴぷぺぽ")); vs2 = utf8_mbstowcs(String("がぎぐげござじずぜぞだぢづでどばびぶべぼばびぶべぼ")); svs1 = utf8_mbstowcs(String("はひふへほばびぶべぼ")); svs2 = utf8_mbstowcs(String("ぱぴぷぺぽぱぴぷぺぽ")); } NicolaInput::~NicolaInput() { } /*! \fn Honoka::NicolaInput::loadTable(const String &filename) */ bool Honoka::NicolaInput::loadTable(const String &filename) { FILE *f = fopen(filename.c_str(),"r"); if (!f) { #ifdef HONOKA_DATADIR String fn = HONOKA_DATADIR; fn += "/" + filename; f = fopen(fn.c_str(),"r"); if (!f) return false; #else return false; #endif } while(-1) { char s[256]; if(fgets(s,256,f) == NULL) break; String l = s; unsigned int p = 0; vector<String> t; for(unsigned int i = 0;i < l.length();i ++) { if ((l[i] == '\t') || (l[i] == '\n')) { t.push_back(l.substr(p,i - p)); p = i + 1; } } if (p < l.length()) t.push_back(l.substr(p)); if (t.size() != 4) continue; KeyEvent k; NicolaKey n; n.noShift = utf8_mbstowcs(t[1]); n.leftShift = utf8_mbstowcs(t[2]); n.rightShift = utf8_mbstowcs(t[3]); scim_string_to_key(k,t[0]); keymap.insert(pair<KeyEvent,NicolaKey>(k,n)); } fclose(f); if (keymap.size()) return true; return false; } /*! \fn NicolaInput::getModeName() */ String NicolaInput::getModeName() { return String(_("KANA")); } /*! \fn NicolaInput::getName() */ String NicolaInput::getName() { return String("Nicola"); } /*! \fn NicolaInput::getPropertyName() */ String NicolaInput::getPropertyName() { return String(_("NICOLA")); } /*! \fn NicolaInput::inputEvent(const KeyEvent &key) */ bool NicolaInput::inputEvent(const KeyEvent &key) { // 喰っておくべきもの。 if ((key.code == SCIM_KEY_Shift_L) || (key.code == SCIM_KEY_Shift_R) || (key.code == SCIM_KEY_Control_L) || (key.code == SCIM_KEY_Control_R) || (key.code == SCIM_KEY_Alt_L) || (key.code == SCIM_KEY_Alt_R) || (key.code == SCIM_KEY_Super_L) || (key.code == SCIM_KEY_Super_R) || (key.code == SCIM_KEY_Hyper_L) || (key.code == SCIM_KEY_Hyper_R) || (key.code == SCIM_KEY_Mode_switch) || (key.code == SCIM_KEY_ISO_Next_Group)) return true; map<KeyEvent,NicolaKey>::iterator it = keymap.find(key); if (it == keymap.end()) { if (isPrintable(key)) { text = text.substr(0,pos) + key.get_unicode_code() + text.substr(pos); pos ++; return true; } else return false; } WideString w; if (LShift) w = it->second.leftShift; else if (RShift) w = it->second.rightShift; else w = it->second.noShift; bk = key; if (w == vsc) { for(unsigned int i = 0;i < vs1.length();i ++) { if (vs1[i] == text[pos - 1]) text = text.substr(0,pos - 1) + vs2[i] + text.substr(pos); } } else if (w == svsc) { for(unsigned int i = 0;i < svs1.length();i ++) { if (svs1[i] == text[pos - 1]) text = text.substr(0,pos - 1) + svs2[i] + text.substr(pos); } } else if (w.length()) { struct timeval tv; gettimeofday(&tv, NULL); bkt = (tv.tv_sec * 1000000) + tv.tv_usec; text = text.substr(0,pos) + w + text.substr(pos); pos ++; } return true; //return false; } /*! \fn NicolaInput::keyEventHook(const KeyEvent &key) */ bool NicolaInput::keyEventHook(const KeyEvent &key) { for(unsigned int i = 0;i < RShiftKey.size();i ++) { if (key.code == RShiftKey[i].code) { if (key.is_key_press()) { RShift = true; struct timeval tv; gettimeofday(&tv, NULL); long t = (tv.tv_sec * 1000000) + tv.tv_usec; if ((t - bkt) < (delay * 1000)) { backspace(); return(inputEvent(bk)); } } else if (key.is_key_release()) RShift = false; return true; } } for(unsigned int i = 0;i < LShiftKey.size();i ++) { if (key.code == LShiftKey[i].code) { if (key.is_key_press()) { LShift = true; struct timeval tv; gettimeofday(&tv, NULL); long t = (tv.tv_sec * 1000000) + tv.tv_usec; if ((t - bkt) < (delay * 1000)) { backspace(); return(inputEvent(bk)); } } else if (key.is_key_release()) LShift = false; return true; } } return false; }