Diffstat (limited to 'noncore/applets/keyhelper/keyhelperapplet/misc') (more/less context) (show whitespace changes)
16 files changed, 2075 insertions, 0 deletions
diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/ConfigEx.cpp b/noncore/applets/keyhelper/keyhelperapplet/misc/ConfigEx.cpp new file mode 100644 index 0000000..3693dff --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/ConfigEx.cpp @@ -0,0 +1,112 @@ +#include "ConfigEx.h" + +ConfigEx::ConfigEx(const QString& name, Domain domain) + : Config(name, domain) +{ + m_charset = "utf8"; + decode(); + m_lastRead = QDateTime::currentDateTime(); +} + +#if 0 +void ConfigEx::removeComment() +{ + for(QMap<QString,ConfigGroup>::Iterator it=groups.begin(); + it!=groups.end(); ++it){ + QStringList removeList; + for(ConfigGroup::Iterator it2=(*it).begin(); + it2!=(*it).end(); ++it2){ + if(it2.key()[0] == '#'){ + QString key = it2.key(); + removeList.append(it2.key()); + } + } + for(QStringList::Iterator it3=removeList.begin(); + it3!=removeList.end(); ++it3){ + (*it).remove(*it3); + } + } +} +#endif + +void ConfigEx::decode() +{ + QString group = getGroup(); + setGroup("Global"); + QString charset = readEntry("CharSet", "utf8"); + qWarning("ConfigEx::decode()[%s][%s]", charset.latin1(), m_charset.latin1()); + setGroup(group); + if(charset != m_charset){ + m_charset = charset; + read(); + } + //removeComment(); +} + +void ConfigEx::read() +{ + qWarning("ConfigEx::read()"); + groups.clear(); + changed = FALSE; + + if ( !QFileInfo( filename ).exists() ) { + git = groups.end(); + return; + } + + QFile f( filename ); + if ( !f.open( IO_ReadOnly ) ) { + git = groups.end(); + return; + } + + QTextStream s( &f ); +#ifdef CONFIG_MULTICODEC + QTextCodec* codec = QTextCodec::codecForName(m_charset); + if(codec == NULL){ + codec = QTextCodec::codecForName("utf8"); + qWarning("Config CharSet[utf8]"); + } else { + qWarning("Config CharSet[%s]", m_charset.latin1()); + } + s.setCodec(codec); +#else /* CONFIG_MULTICODEC */ +#if QT_VERSION <= 230 && defined(QT_NO_CODECS) + // The below should work, but doesn't in Qt 2.3.0 + s.setCodec( QTextCodec::codecForMib( 106 ) ); +#else + s.setEncoding( QTextStream::UnicodeUTF8 ); +#endif +#endif /* CONFIG_MULTICODEC */ + + QStringList list = QStringList::split('\n', s.read() ); + + f.close(); + + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + if ( !parse( *it ) ) { + git = groups.end(); + return; + } + } +} + +QStringList ConfigEx::getKeys() +{ + QStringList keys; + if(groups.end() != git){ + for(ConfigGroup::ConstIterator it=(*git).begin(); + it!=(*git).end(); ++it){ + if(it.key()[0] != '#'){ + keys.append(it.key()); + } + } + } + return(keys); +} + +QDateTime ConfigEx::lastModified() +{ + QFileInfo info(filename); + return(info.lastModified()); +} diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/ConfigEx.h b/noncore/applets/keyhelper/keyhelperapplet/misc/ConfigEx.h new file mode 100644 index 0000000..32120cc --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/ConfigEx.h @@ -0,0 +1,89 @@ +#ifndef _CONFIG_EX_H_ +#define _CONFIG_EX_H_ + +#include <qstringlist.h> +#include <qdatetime.h> +#include <qfileinfo.h> +#include <qtextstream.h> +#include <qtextcodec.h> + +#define QTOPIA_INTERNAL_LANGLIST +#include <qpe/config.h> +#include <qpe/global.h> + +#define CONFIG_MULTICODEC + +/* Singleton Object */ +class ConfigEx : public Config +{ +public: + static ConfigEx& getInstance(const QString& name){ + static ConfigEx cfg(name); + if(/*cfg.flush() ||*/cfg.m_lastRead < cfg.lastModified()){ + cfg.load(&cfg); + } + return(cfg); + } + +#if 0 + bool flush(){ + if(changed){ + write(); + return(true); + } else { + return(false); + } + } +#endif + + const QString& getGroup(){ + return(git.key()); + } + + void load(ConfigEx* cfg){ + cfg->read(); + cfg->decode(); + cfg->m_lastRead = QDateTime::currentDateTime(); + } + + void setConfig(const QString& name){ + if(name == QString::null){ + return; + } + /*flush();*/ + filename = configFilename(name, User); + load(this); + } + + void reload() { + /*flush();*/ + load(this); + } + + QStringList getKeys(); + QDateTime lastModified(); + QDateTime lastRead(){ + return(m_lastRead); + } + + friend class Dummy; /* for compie warning */ +private: + ConfigEx(const QString& name, Domain domain=User); + ConfigEx& operator=(const ConfigEx&); + virtual ~ConfigEx(){changed = false;} + + class Dummy{}; /* for compile warning */ + + + void read(); + void decode(); + //void removeComment(); + + QDateTime m_lastRead; +#ifdef CONFIG_MULTICODEC + QString m_charset; +#endif +}; + +#endif /* _CONFIG_EX_H_ */ + diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/KHUtil.cpp b/noncore/applets/keyhelper/keyhelperapplet/misc/KHUtil.cpp new file mode 100644 index 0000000..b7134d9 --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/KHUtil.cpp @@ -0,0 +1,90 @@ +#include "KHUtil.h" +#include <qwindowsystem_qws.h> + +int KHUtil::hex2int(const QString& hexstr, bool* ok) +{ + int val; + bool success; + if(hexstr.find("0x") == 0){ + val = hexstr.mid(2).toInt(&success, 16); + } else { + val = hexstr.toInt(&success, 16); + } + if(!success){ + val = 0; + } + if(ok){ + *ok = success; + } + return(val); +} + +const QStringList KHUtil::parseArgs(const QString& arguments) +{ + QString str; + QStringList args; + char quote = 0; + char c; + for(unsigned int i=0; i<arguments.length(); i++){ + c = arguments[i]; + switch(c){ + case '\"': + if(quote == 0){ + quote = c; + } else if(quote == '\"'){ + if(str.length() > 0){ + args.append(str); + } + str = ""; + quote = 0; + } else { + str += c; + } + break; + case '\'': + if(quote == 0){ + quote = c; + } else if(quote == '\''){ + if(str.length() > 0){ + args.append(str); + } + str = ""; + quote = 0; + } else { + str += c; + } + break; + case ' ': + if(quote == 0){ + if(str.length() > 0){ + args.append(str); + str = ""; + } + } else { + str += c; + } + break; + default: + str += c; + break; + } + } + if(str.length() > 0){ + args.append(str); + } + return(args); +} + +const QString KHUtil::currentApp() +{ + QString app; + const QList<QWSWindow>& list = qwsServer->clientWindows(); + QWSWindow* w; + for(QListIterator<QWSWindow> it(list); (w=it.current()); ++it){ + if(w->isVisible() && w->client()->identity() != QString::null){ + app = w->client()->identity(); + break; + } + } + return app; +} diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/KHUtil.h b/noncore/applets/keyhelper/keyhelperapplet/misc/KHUtil.h new file mode 100644 index 0000000..a92a1b2 --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/KHUtil.h @@ -0,0 +1,15 @@ +#ifndef _KHUTIL_H_ +#define _KHUTIL_H_ + +#include <qstring.h> +#include <qstringlist.h> + +class KHUtil +{ +public: + static int hex2int(const QString& hexstr, bool* ok=NULL); + static const QStringList parseArgs(const QString& arguments); + static const QString currentApp(); +}; + +#endif /* _KHUTIL_H_ */ diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/KeyAction.cpp b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyAction.cpp new file mode 100644 index 0000000..f44138c --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyAction.cpp @@ -0,0 +1,253 @@ +#include "KeyAction.h" + +KeyAction::KeyAction() +{ + qDebug("KeyAction::KeyAction()"); + enable(); +} + +KeyAction::~KeyAction() +{ + qDebug("KeyAction::~KeyAction()"); +} + +void KeyAction::init() +{ + ConfigEx& cfg = ConfigEx::getInstance("keyhelper"); + + QString oldgroup = cfg.getGroup(); + cfg.setGroup("Global"); + + m_keepToggle = cfg.readBoolEntry("KeepToggle", true); + + m_excludeKeys.clear(); + if(cfg.hasKey("ExcludeKeys")){ + QStringList keys = cfg.readListEntry("ExcludeKeys", ','); + for(QStringList::Iterator it=keys.begin(); + it!=keys.end(); ++it){ + int code; + if((*it).find("0x") == 0){ + code = KHUtil::hex2int(*it); + } else { + code = KeyNames::getCode(*it); + } + if(code > 0){ + m_excludeKeys.append(code); + } + } + } else { + m_excludeKeys.append(Qt::Key_F34); + } + + m_presscnt = 0; + m_check = true; + m_keep_toggle_code = 0; + m_capture = false; + cfg.setGroup(oldgroup); +} + +void KeyAction::setAction(int unicode, int keycode, int modifiers, + bool isPress, bool autoRepeat) +{ + m_unicode = unicode; + m_keycode = keycode; + m_modifiers = modifiers; + m_isPress = isPress; + m_autoRepeat = autoRepeat; +} + +bool KeyAction::checkState() +{ + if(0 < m_unicode && m_unicode < 0xFFFF){ + QChar ch(m_unicode); + QChar::Category category = ch.category(); + if(category == QChar::Letter_Lowercase){ + if(m_modifiers == 0){ + m_pMappings->setCapsLock(false); + return(true); + } else if(m_modifiers == Qt::ShiftButton){ + m_pMappings->setCapsLock(true); + return(true); + } + } else if(category == QChar::Letter_Uppercase){ + if(m_modifiers == 0){ + m_pMappings->setCapsLock(true); + return(true); + } else if(m_modifiers == Qt::ShiftButton){ + m_pMappings->setCapsLock(false); + return(true); + } + } + } + return(false); +} + +void KeyAction::sendKeyEvent(int unicode, int keycode, int modifiers, + bool isPress, bool autoRepeat) +{ + if(m_hookChannel.isEmpty()){ + QWSServer::sendKeyEvent(unicode, keycode, modifiers, isPress, autoRepeat); + } else { + if(QCopChannel::isRegistered(m_hookChannel)){ + QCopEnvelope e(m_hookChannel, "keyEvent(int,int,int,int,int)"); + e << unicode << keycode << modifiers << (int)isPress << (int)autoRepeat; + } else { + m_hookChannel = ""; + QWSServer::sendKeyEvent(unicode, keycode, modifiers, isPress, autoRepeat); + } + } +} + +bool KeyAction::doAction() +{ + if(m_enable == false){ + return(false); + } +#if 0 + if(m_excludeKeys.contains(m_keycode)){ + return(false); + } +#endif + if(!m_autoRepeat){ + qDebug("recv[%x][%x][%x][%d]", + m_unicode, + m_keycode, + m_modifiers, + m_isPress); + } + + if(m_autoRepeat && !m_excludeKeys.contains(m_keycode)){ + KeyRepeater::RepeaterMode repMode = m_pRepeater->getMode(); + if(repMode == KeyRepeater::ENABLE + || repMode == KeyRepeater::KILL){ + /* autoRepeat ¤Ï̵»ë */ + return(true); + } + } + + if(m_pRepeater->isRepeatable(m_keycode)){ + if(m_isPress){ + m_presscnt++; + } else { + m_presscnt--; + if(m_presscnt <= 0){ + m_pRepeater->stop(); + m_presscnt = 0; + } + } + } + + if(m_check && m_isPress){ + /* check capslock state */ + if(checkState()){ + m_check = false; + } + } + + int unicode, keycode, modifiers; + /* keep toggle reset */ + if(m_keepToggle && m_keep_toggle_code != 0){ + if(m_keep_toggle_code != m_keycode){ + m_pModifiers->resetToggles(); + m_keep_toggle_code = 0; + } else { + m_pModifiers->keepToggles(); + } + } + + /* modifier ¾õÂÖ¼èÆÀ */ + int keymask = m_pModifiers->getState(m_modifiers); + modifiers = m_pModifiers->getModifiers(m_modifiers); + + bool isModMapped = false; + /* modifier ¾õÂÖ¹¹¿· */ + if(m_autoRepeat == false){ + if(m_isPress){ + isModMapped = m_pModifiers->pressKey(m_keycode, m_modifiers); + } else { + m_pModifiers->releaseKey(m_keycode); + } + } + + if(m_capture && m_isPress && m_autoRepeat == false){ + QCopEnvelope e("QPE/KeyHelperConf", "event(int,int,int)"); + e << m_keycode << m_unicode << modifiers; + } + + /* keyextension ŬÍÑ */ + bool fKeyCancel = m_pExtensions->doKey(m_keycode, keymask, m_isPress); + if(fKeyCancel){ + if(m_keepToggle){ + m_keep_toggle_code = m_keycode; + } else { + m_pModifiers->resetToggles(); + } + m_pRepeater->stop(); + return(true); + } + + /* keymapping ŬÍÑ */ +#if 0 + bool isMapped = m_pMappings->apply(m_keycode, keymask, m_isPress); + if(isMapped == false){ + if(m_pMappings->isDefined()){ + m_pMappings->setOriginal(m_unicode, m_modifiers); + } else { + m_pMappings->setUnicode(m_unicode); + //m_pMappings->setKeycode(m_keycode); + } + //return(false); + } +#else + bool isMapped = m_pMappings->apply(m_unicode, m_keycode, m_modifiers, + keymask, m_isPress); +#endif + + /* modifier ŬÍÑ */ + m_pMappings->setModifiers(modifiers); + + keycode = m_pMappings->getKeycode(); + if(keycode <= 0){ + return(true); + } + + if(/*m_autoRepeat == false &&*/ m_isPress){ + if(isModMapped == false || (isModMapped && isMapped)){ + if(m_pModifiers->isModifier(keycode) == false){ + m_pModifiers->resetToggles(); + } + } + } + unicode = m_pMappings->getUnicode(); + modifiers = m_pMappings->getModifiers(); + if(keycode > 0){ + /* disable mapping */ + if(m_excludeKeys.contains(keycode)){ + return(false); + } + /* send key event */ + sendKeyEvent( + unicode, + keycode, + modifiers, + m_isPress, + m_autoRepeat); + } + if(m_isPress){ + /* repeater start */ + m_pRepeater->start(unicode, keycode, modifiers); +#if 0 + } else if(m_presscnt <= 0){ + m_presscnt = 0; + m_pRepeater->stop(); +#endif + } else { + m_pRepeater->stop(keycode); + } + qWarning("send[%x][%x][%x][%d]", + m_pMappings->getUnicode(), + m_pMappings->getKeycode(), + m_pMappings->getModifiers(), + m_isPress); + return(true); +} diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/KeyAction.h b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyAction.h new file mode 100644 index 0000000..4eb5eb6 --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyAction.h @@ -0,0 +1,87 @@ +#ifndef _KEY_ACTION_H_ +#define _KEY_ACTION_H_ + +#include <qobject.h> +#include <qwindowsystem_qws.h> +#include <qtimer.h> +#include <qpe/power.h> +#include "KeyMappings.h" +#include "KeyModifiers.h" +#include "KeyExtensions.h" +#include "KeyRepeater.h" +#include "ConfigEx.h" + +class KeyAction : public QObject +{ + Q_OBJECT +public: + KeyAction(); + virtual ~KeyAction(); + + void setKeyMappings(KeyMappings* map) + { + m_pMappings = map; + } + void setKeyModifiers(KeyModifiers* mod) + { + m_pModifiers = mod; + } + void setKeyExtensions(KeyExtensions* ext) + { + m_pExtensions = ext; + } + void setKeyRepeater(KeyRepeater* rep) + { + m_pRepeater = rep; + connect(m_pRepeater, SIGNAL(keyEvent(int,int,int,bool,bool)), + this, SLOT(sendKeyEvent(int,int,int,bool,bool))); + } + void setAction(int unicode, int keycode, int modifiers, + bool isPress, bool autoRepeat); + bool doAction(); + + void enable(){ + init(); + m_enable = true; + }; + void disable(){ + m_enable = false; + }; + void setCapture(bool enable){ + m_capture = enable; + } + + void setHook(const QCString& s){ + m_hookChannel = s; + } +private: + int m_unicode; + int m_keycode; + int m_modifiers; + bool m_isPress; + bool m_autoRepeat; + + bool m_capture; + bool m_enable; + int m_presscnt; + + int m_keep_toggle_code; + bool m_keepToggle; + bool m_check; + QValueList<int> m_excludeKeys; + + QCString m_hookChannel; + + KeyMappings* m_pMappings; + KeyModifiers* m_pModifiers; + KeyExtensions* m_pExtensions; + KeyRepeater* m_pRepeater; + + void init(); + bool checkState(); +private slots: + void sendKeyEvent(int unicode, int keycode, int modifiers, + bool isPress, bool autoRepeat); +}; + +#endif /* _KEY_ACTION_H_ */ diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/KeyMappings.cpp b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyMappings.cpp new file mode 100644 index 0000000..0151d39 --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyMappings.cpp @@ -0,0 +1,340 @@ +#include "KeyMappings.h" + +static QIntDict<QWSServer::KeyMap> g_mapCache(127); + +MapInfo::MapInfo(int code, int mod, int uni, + int shift_uni, int ctrl_uni) +{ + const QWSServer::KeyMap* map; + if(uni == 0 || shift_uni == 0 || ctrl_uni == 0){ + map = MapInfo::findKeyMap(code); + if(map != NULL){ + isDefined = true; + unicode = map->unicode; + shift_unicode = map->shift_unicode; + ctrl_unicode = map->ctrl_unicode; + } else { + isDefined = false; + unicode = 0; + shift_unicode = 0; + ctrl_unicode = 0; + } + } else { + isDefined = true; + } + keycode = code; + modifiers = mod; + if(uni != 0){ + unicode = uni; + } + if(shift_uni != 0){ + shift_unicode = shift_uni; + } + if(ctrl_uni != 0){ + ctrl_unicode = ctrl_uni; + } +} + +const QWSServer::KeyMap* MapInfo::findKeyMap(int keycode) +{ + const QWSServer::KeyMap* m = QWSServer::keyMap(); + + while(m->key_code != 0){ + if(m->key_code == keycode){ + return(m); + } + m++; + } + return(NULL); +} + +KeyMappings::KeyMappings() +{ + qDebug("KeyMappings::KeyMappings()"); + init(); +} + +KeyMappings::~KeyMappings() +{ + qDebug("KeyMappings::~KeyMappings()"); + clear(); +} + +void KeyMappings::init() +{ + m_capslock = false; +} + +void KeyMappings::reset() +{ + clear(); +} + +void KeyMappings::clear() +{ + for(QMap<int, CodeMaps*>::Iterator it = m_keymaps.begin(); + it!=m_keymaps.end(); ++it){ + delete (*it); + } + m_keymaps.clear(); + g_mapCache.setAutoDelete(true); + g_mapCache.clear(); +} + +void KeyMappings::assign(int keycode, int keymask, int mapcode, + int mapmodifiers, int unicode, int shift_unicode, int ctrl_unicode) +{ + CodeMaps* map; + if(m_keymaps.contains(keycode)){ + map = m_keymaps[keycode]; + } else { + map = new CodeMaps(); + m_keymaps.insert(keycode, map); + } + + MapInfo info(mapcode, mapmodifiers, unicode, shift_unicode, ctrl_unicode); + m_it = map->insert(keymask, info); +} + +void KeyMappings::assignModifier(const QString& type, const QString& state) +{ + int maskbit = 0; + QString str; + str = type.lower(); + if(str == "shift"){ + maskbit = Qt::ShiftButton; + } else if(str == "control"){ + maskbit = Qt::ControlButton; + } else if(str == "alt"){ + maskbit = Qt::AltButton; + } + str = state.lower(); + if(str == "off"){ + maskbit = (maskbit << 16) & 0xFFFF0000; + } + (*m_it).modifiers |= maskbit; +} + +void KeyMappings::assignUnicode(const QString& kind, const QString& ch) +{ + QString str; + int code = ch[0].unicode(); + str = kind.lower(); + if(str == "unicode"){ + (*m_it).unicode = code; + } else if(str == "shift_unicode"){ + (*m_it).shift_unicode = code; + } else if(str == "ctrl_unicode"){ + (*m_it).ctrl_unicode = code; + } +} + +void KeyMappings::assignUnicode(int unicode) +{ + (*m_it).unicode = (*m_it).shift_unicode = + (*m_it).ctrl_unicode = unicode; +} + +void KeyMappings::statistics() +{ + qWarning("KeyMappings::statistics()"); + for(QMap<int, CodeMaps*>::Iterator it=m_keymaps.begin(); + it!=m_keymaps.end(); ++it){ + qWarning(" code = %x", it.key()); + for(QMap<int, MapInfo>::Iterator it2=(*it)->begin(); + it2!=(*it)->end(); ++it2){ + qDebug(" [%x]-[%x][%x][%x][%x][%x]", it2.key(), + (*it2).keycode, + (*it2).modifiers, + (*it2).unicode, + (*it2).shift_unicode, + (*it2).ctrl_unicode); + } + } +} + +bool KeyMappings::apply(int unicode, int keycode, int modifiers, + int keymask, bool isPress) +{ + CodeMaps* map; + m_isMapped = false; + + if(m_keymaps.contains(keycode)){ + map = m_keymaps[keycode]; + if(map->contains(keymask)){ + m_isMapped = true; + m_keyinfo = (*map)[keymask]; + } else { + int mask = -1; + for(CodeMaps::Iterator it=map->begin(); + it!=map->end(); ++it){ + if((keymask & it.key()) == it.key() + && it.key() > mask){ + mask = it.key(); + } + } + if(mask != -1){ + m_isMapped = true; + m_keyinfo = (*map)[mask]; + } + } + } + + if(m_isMapped == false){ + QWSServer::KeyMap* cache = g_mapCache[keycode]; + if(cache == NULL){ + cache = new QWSServer::KeyMap(); + g_mapCache.insert(keycode, cache); + cache->unicode = cache->shift_unicode = cache->ctrl_unicode = 0; + } + if(cache->unicode == 0 || cache->shift_unicode == 0 || cache->ctrl_unicode == 0){ + QChar ch(unicode); + if(modifiers & Qt::ControlButton){ + cache->ctrl_unicode = unicode; + } else if(modifiers & Qt::ShiftButton){ + cache->shift_unicode = ch.upper().unicode(); + } else { + cache->unicode = ch.lower().unicode(); + } + } + m_keyinfo = MapInfo(keycode, 0, + cache->unicode, cache->shift_unicode, cache->ctrl_unicode); + if(m_keyinfo.isDefined){ + setOriginal(unicode, modifiers); + } else { + setUnicode(unicode); + } + } + +#if 1 + if(isPress){ + if(m_keyinfo.keycode == Qt::Key_CapsLock){ + m_capslock = !m_capslock; + } + } +#endif + return(m_isMapped); +} + +bool KeyMappings::apply(int keycode, int keymask, bool isPress) +{ + CodeMaps* map; + m_isMapped = false; + + if(m_keymaps.contains(keycode)){ + map = m_keymaps[keycode]; + if(map->contains(keymask)){ + m_isMapped = true; + m_keyinfo = (*map)[keymask]; + } else { + int mask = -1; + for(CodeMaps::Iterator it=map->begin(); + it!=map->end(); ++it){ + if((keymask & it.key()) == it.key() + && it.key() > mask){ + mask = it.key(); + } + } + if(mask != -1){ + m_isMapped = true; + m_keyinfo = (*map)[mask]; + } + } + } + if(m_isMapped == false){ + m_keyinfo = MapInfo(keycode); + } +#if 1 + if(isPress){ + if(m_keyinfo.keycode == Qt::Key_CapsLock){ + m_capslock = !m_capslock; + } + } +#endif + return(m_isMapped); +} + +/** + * set original unicode + */ +void KeyMappings::setOriginal(int unicode, int modifiers) +{ + if(modifiers & Qt::ControlButton){ + m_keyinfo.ctrl_unicode = unicode; + } else if(modifiers & Qt::ShiftButton){ + m_keyinfo.shift_unicode = unicode; + } else { + m_keyinfo.unicode = unicode; + } +} + +void KeyMappings::setModifiers(int modifiers) +{ + m_modifiers = modifiers; + m_modifiers |= (m_keyinfo.modifiers & 0xFFFF); + m_modifiers &= ~((m_keyinfo.modifiers >> 16) & 0xFFFF); +} + +void KeyMappings::setUnicode(int unicode) +{ + m_keyinfo.unicode = unicode; + m_keyinfo.shift_unicode = unicode; + m_keyinfo.ctrl_unicode = unicode; +} + +void KeyMappings::setKeycode(int keycode) +{ + m_keyinfo.keycode = keycode; +} + +int KeyMappings::getUnicode() +{ + int unicode; + if(m_modifiers & Qt::ControlButton){ + unicode = m_keyinfo.ctrl_unicode; + } else if(m_modifiers & Qt::ShiftButton){ + unicode = m_keyinfo.shift_unicode; + QChar ch(unicode); + if(m_capslock){ + unicode = ch.lower().unicode(); + } else { + unicode = ch.upper().unicode(); + } + } else { + unicode = m_keyinfo.unicode; + QChar ch(unicode); + if(m_capslock){ + unicode = ch.upper().unicode(); + } else { + unicode = ch.lower().unicode(); + } + } + qDebug("UNICODE[%d][%x][%x]", m_capslock, unicode, m_keyinfo.unicode); +#if 0 + if(m_isMapped && m_capslock){ + QChar ch(unicode); + QChar::Category category = ch.category(); + if(category == QChar::Letter_Uppercase){ + unicode = ch.lower().unicode(); + } else if(category == QChar::Letter_Lowercase){ + unicode = ch.upper().unicode(); + } + } +#endif + return(unicode); +} + +int KeyMappings::getKeycode() +{ + return(m_keyinfo.keycode); +} + +int KeyMappings::getModifiers() +{ + return(m_modifiers); +} + +bool KeyMappings::isDefined() +{ + return(m_keyinfo.isDefined); +} diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/KeyMappings.h b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyMappings.h new file mode 100644 index 0000000..9705c8c --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyMappings.h @@ -0,0 +1,72 @@ +#ifndef _KEY_MAPPINGS_H_ +#define _KEY_MAPPINGS_H_ + +#include <qwindowsystem_qws.h> +#include <qmap.h> + +#include <qintdict.h> + +class MapInfo +{ +public: + MapInfo(){}; + MapInfo(int code, int mod = 0, int uni = 0, + int shift_uni = 0, int ctrl_uni = 0); + + static const QWSServer::KeyMap* findKeyMap(int code); + + int keycode; + int modifiers; + int unicode; + int shift_unicode; + int ctrl_unicode; + bool isDefined; +}; + +class KeyMappings +{ +public: + typedef QWSServer::KeyMap KeyMap; + typedef QMap<int, MapInfo> CodeMaps; + + KeyMappings(); + virtual ~KeyMappings(); + + void setOriginal(int unicode, int modifiers); + void setModifiers(int modifiers); + void setUnicode(int unicode); + void setKeycode(int keycode); + + int getUnicode(); + int getKeycode(); + int getModifiers(); + bool isDefined(); + + void assign(int keycode, int keymask, int mapcode, int mapmodifiers = 0, + int unicode = 0, int shift_unicode = 0, int ctrl_unicode = 0); + void assignModifier(const QString& type, const QString& state); + void assignUnicode(const QString& kind, const QString& ch); + void assignUnicode(int unicode); + bool apply(int unicode, int keycode, int modifiers, int keymask, bool isPress); + bool apply(int keycode, int keymask, bool isPress); + void setCapsLock(bool on=true){ + m_capslock = on; + } + + void reset(); + + void statistics(); +private: + QMap<int, CodeMaps*> m_keymaps; + MapInfo m_keyinfo; + int m_modifiers; + CodeMaps::Iterator m_it; + + bool m_capslock; + bool m_isMapped; + + void init(); + void clear(); +}; + +#endif /* _KEY_MAPPINGS_H_ */ diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/KeyModifiers.cpp b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyModifiers.cpp new file mode 100644 index 0000000..4699b11 --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyModifiers.cpp @@ -0,0 +1,285 @@ +#include "KeyModifiers.h" + +KeyModifiers::KeyModifiers() +{ + qDebug("KeyModifiers::KeyModifiers()"); + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), + this, SLOT(resetToggles())); + init(); +} + +KeyModifiers::~KeyModifiers() +{ + qDebug("KeyModifiers::~KeyModifiers()"); + delete m_pTimer; + clear(); +} + +void KeyModifiers::addType(const QString& type) +{ + if(m_types.contains(type) == false){ + qDebug("addType[%s][%x]", type.latin1(), m_bitmask); + m_types.insert(type, m_bitmask); + m_bitmask = m_bitmask << 1; + } +} + +ModifierInfo* KeyModifiers::assign(const QString& type, int keycode, + int keymask, bool mode) +{ + m_info = new ModifierInfo(type, keycode, keymask, mode); + addType(type); + m_modifiers.append(m_info); + if(mode){ + m_togglekeys.append(m_info); + } + assignRelease(m_info, keycode); + return(m_info); +} + +void KeyModifiers::assignRelease(int keycode) +{ + assignRelease(m_info, keycode); +} + +void KeyModifiers::assignRelease(ModifierInfo* info, int keycode) +{ + if(m_releasekeys.contains(keycode) == false){ + m_releasekeys.insert(keycode, new ModifierList); + } + m_releasekeys[keycode]->append(info); +} + +void KeyModifiers::setToggle() +{ + setToggle(m_info); +} + +void KeyModifiers::setToggle(ModifierInfo* info) +{ + info->toggle_mode = true; + m_togglekeys.append(info); +} + +void KeyModifiers::keepToggles() +{ + if(m_timeout > 0){ + m_pTimer->start(m_timeout, true); + } +} + +bool KeyModifiers::pressKey(int keycode, int modifiers) +{ + int keymask; + + keymask = getState(modifiers, true); + + for(ModifierList::Iterator it=m_modifiers.begin(); + it!=m_modifiers.end(); ++it){ + if((*it)->keycode == keycode + && ((*it)->keymask & keymask) == (*it)->keymask){ + (*it)->pressed = true; + if((*it)->toggle_mode){ + /* change toggle state */ + (*it)->toggled = !((*it)->toggled); + if((*it)->toggled){ + keepToggles(); + } else { + m_pTimer->stop(); + } + } + return(true); + } + } + return(false); +} + +bool KeyModifiers::isModifier(int keycode) +{ + if(keycode == Qt::Key_Shift + || keycode == Qt::Key_Control + || keycode == Qt::Key_Alt + || keycode == Qt::Key_Meta + || keycode == Qt::Key_F22){ + return(true); + } else { + return(false); + } +} + +void KeyModifiers::releaseKey(int keycode) +{ + if(m_releasekeys.contains(keycode)){ + ModifierList* list = m_releasekeys[keycode]; + for(ModifierList::Iterator it=(*list).begin(); + it!=(*list).end(); ++it){ + (*it)->pressed = false; + } + } +} + +int KeyModifiers::getState() +{ + int state = 0; + for(ModifierList::Iterator it=m_modifiers.begin(); + it!=m_modifiers.end(); ++it){ + if((*it)->pressed || (*it)->toggled){ + state |= m_types[(*it)->type]; + } + } + return(state); +} + +int KeyModifiers::getState(int modifiers, bool reset) +{ + int state = getState(); + int mask; + + mask = getMask("Shift"); + if(modifiers & Qt::ShiftButton){ + state |= mask; + } else { + if(reset){ + state &= ~mask; + } + } + mask = getMask("Control"); + if(modifiers & Qt::ControlButton){ + state |= mask; + } else { + if(reset){ + state &= ~mask; + } + } + mask = getMask("Alt"); + if(modifiers & Qt::AltButton){ + state |= mask; + } else { + if(reset){ + state &= ~mask; + } + } + + return(state); +} + +int KeyModifiers::getModifiers(int modifiers) +{ + int state = getState(); + + if(state & getMask("Shift")){ + modifiers |= Qt::ShiftButton; + } + if(state & getMask("Control")){ + modifiers |= Qt::ControlButton; + } + if(state & getMask("Alt")){ + modifiers |= Qt::AltButton; + } + + return(modifiers); +} + +int KeyModifiers::getMask(const QString& type) +{ + if(m_types.contains(type)){ + return(m_types[type]); + } else { + return(0); + } +} + +void KeyModifiers::clear() +{ + m_types.clear(); + + m_togglekeys.clear(); + + for(ModifierList::Iterator it=m_modifiers.begin(); + it!=m_modifiers.end(); ++it){ + delete *it; + } + m_modifiers.clear(); + + for(QMap<int, ModifierList*>::Iterator it=m_releasekeys.begin(); + it!=m_releasekeys.end(); ++it){ + delete *it; + } + m_releasekeys.clear(); +} + +void KeyModifiers::init() +{ + m_bitmask = 0x00000001; + addType("Shift"); + addType("Control"); + addType("Alt"); + + ConfigEx& cfg = ConfigEx::getInstance("keyhelper"); + + cfg.setGroup("Global"); + + QString timeout = cfg.readEntry("ToggleTimeout", "10"); + int msec = timeout.toInt(); + msec *= 1000; /* sec to msec */ + m_timeout = msec; +} + +void KeyModifiers::reset() +{ + clear(); + init(); +} + +bool KeyModifiers::isToggled() +{ + for(ModifierList::Iterator it=m_togglekeys.begin(); + it!=m_togglekeys.end(); ++it){ + if((*it)->toggled){ + return(true); + } + } + return(false); +} + +void KeyModifiers::resetToggles() +{ + for(ModifierList::Iterator it=m_togglekeys.begin(); + it!=m_togglekeys.end(); ++it){ + (*it)->toggled = false; + } + m_pTimer->stop(); +} + +void KeyModifiers::resetStates() +{ + for(ModifierList::Iterator it=m_modifiers.begin(); + it!=m_modifiers.end(); ++it){ + (*it)->pressed = false; + } + resetToggles(); +} + +void KeyModifiers::statistics() +{ + qWarning("KeyModifiers::statistics()"); + for(ModifierList::Iterator it=m_modifiers.begin(); + it!=m_modifiers.end(); ++it){ + qWarning(" [%s][%x][%x][%d][%d]", + (*it)->type.latin1(), + (*it)->keycode, + (*it)->keymask, + (*it)->pressed, + (*it)->toggled); + for(QMap<int, ModifierList*>::Iterator it2=m_releasekeys.begin(); + it2!=m_releasekeys.end(); ++it2){ + for(ModifierList::Iterator it3=(*it2)->begin(); + it3!=(*it2)->end(); ++it3){ + if(*it == *it3){ + qWarning(" release[%x]", it2.key()); + } + } + } + } +} diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/KeyModifiers.h b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyModifiers.h new file mode 100644 index 0000000..a99c181 --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyModifiers.h @@ -0,0 +1,80 @@ +#ifndef _KEY_MODIFIERS_H_ +#define _KEY_MODIFIERS_H_ + +#include <qmap.h> +#include <qtimer.h> +#include <qvaluelist.h> +#include <qnamespace.h> + +#include <qpe/config.h> +#include "ConfigEx.h" + +struct ModifierInfo { +public: + ModifierInfo(const QString& tp, int code, int mask, bool mode) + { + type = tp; + keycode = code; + keymask = mask; + pressed = false; + toggled = false; + toggle_mode = mode; + } + QString type; + int keycode; + int keymask; + bool pressed; + bool toggled; + bool toggle_mode; +private: +} ; + +class KeyModifiers : public QObject +{ + Q_OBJECT +public: + typedef QValueList<ModifierInfo*> ModifierList; + + KeyModifiers(); + virtual ~KeyModifiers(); + void addType(const QString& type); + ModifierInfo* assign(const QString& type, int keycode, + int keymask = 0, bool toggle = false); + void assignRelease(int keycode); + void assignRelease(ModifierInfo* info, int keycode); + void setToggle(); + void setToggle(ModifierInfo* info); + + bool isToggled(); + void resetStates(); + void keepToggles(); + + bool pressKey(int keycode, int modifiers); + void releaseKey(int keycode); + int getState(); + int getState(int modifiers, bool reset = false); + int getMask(const QString& type); + int getModifiers(int modifiers); + + bool isModifier(int keycode); + + void statistics(); + + void reset(); +public slots: + void resetToggles(); +private: + QMap<QString, int> m_types; + int m_bitmask; + ModifierList m_modifiers; + QMap<int, ModifierList*> m_releasekeys; + ModifierList m_togglekeys; + ModifierInfo* m_info; + QTimer* m_pTimer; + int m_timeout; + + void clear(); + void init(); +}; + +#endif /* _KEY_MODIFIERS_H_ */ diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/KeyNames.cpp b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyNames.cpp new file mode 100644 index 0000000..2def857 --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyNames.cpp @@ -0,0 +1,303 @@ +#include "KeyNames.h" + +QMap<QString, int> KeyNames::codemap; +QMap<int, QString> KeyNames::namemap; +QString KeyNames::tmpname; + +static struct { + int code; + char* name; +} stKeyNames[] = { +{Qt::Key_Escape, "Escape"}, +{Qt::Key_Tab, "Tab"}, +{Qt::Key_Backtab, "Backtab"}, +{Qt::Key_BackTab, "BackTab"}, +{Qt::Key_Backtab, "Backtab"}, +{Qt::Key_Backspace, "Backspace"}, +{Qt::Key_BackSpace, "BackSpace"}, +{Qt::Key_Backspace, "Backspace"}, +{Qt::Key_Return, "Return"}, +{Qt::Key_Enter, "Enter"}, +{Qt::Key_Insert, "Insert"}, +{Qt::Key_Delete, "Delete"}, +{Qt::Key_Pause, "Pause"}, +{Qt::Key_Print, "Print"}, +{Qt::Key_SysReq, "SysReq"}, +{Qt::Key_Home, "Home"}, +{Qt::Key_End, "End"}, +{Qt::Key_Left, "Left"}, +{Qt::Key_Up, "Up"}, +{Qt::Key_Right, "Right"}, +{Qt::Key_Down, "Down"}, +{Qt::Key_Prior, "Prior"}, +{Qt::Key_PageUp, "PageUp"}, +{Qt::Key_Prior, "Prior"}, +{Qt::Key_Next, "Next"}, +{Qt::Key_PageDown, "PageDown"}, +{Qt::Key_Next, "Next"}, +{Qt::Key_Shift, "Shift"}, +{Qt::Key_Control, "Control"}, +{Qt::Key_Meta, "Meta"}, +{Qt::Key_Alt, "Alt"}, +{Qt::Key_CapsLock, "CapsLock"}, +{Qt::Key_NumLock, "NumLock"}, +{Qt::Key_ScrollLock, "ScrollLock"}, +{Qt::Key_F1, "F1"}, +{Qt::Key_F2, "F2"}, +{Qt::Key_F3, "F3"}, +{Qt::Key_F4, "F4"}, +{Qt::Key_F5, "F5"}, +{Qt::Key_F6, "F6"}, +{Qt::Key_F7, "F7"}, +{Qt::Key_F8, "F8"}, +{Qt::Key_F9, "F9"}, +{Qt::Key_F10, "F10"}, +{Qt::Key_F11, "F11"}, +{Qt::Key_F12, "F12"}, +{Qt::Key_F13, "F13"}, +{Qt::Key_F14, "F14"}, +{Qt::Key_F15, "F15"}, +{Qt::Key_F16, "F16"}, +{Qt::Key_F17, "F17"}, +{Qt::Key_F18, "F18"}, +{Qt::Key_F19, "F19"}, +{Qt::Key_F20, "F20"}, +{Qt::Key_F21, "F21"}, +{Qt::Key_F22, "F22"}, +{Qt::Key_F23, "F23"}, +{Qt::Key_F24, "F24"}, +{Qt::Key_F25, "F25"}, +{Qt::Key_F26, "F26"}, +{Qt::Key_F27, "F27"}, +{Qt::Key_F28, "F28"}, +{Qt::Key_F29, "F29"}, +{Qt::Key_F30, "F30"}, +{Qt::Key_F31, "F31"}, +{Qt::Key_F32, "F32"}, +{Qt::Key_F33, "F33"}, +{Qt::Key_F34, "F34"}, +{Qt::Key_F35, "F35"}, +{Qt::Key_Super_L, "Super_L"}, +{Qt::Key_Super_R, "Super_R"}, +{Qt::Key_Menu, "Menu"}, +{Qt::Key_Hyper_L, "Hyper_L"}, +{Qt::Key_Hyper_R, "Hyper_R"}, +{Qt::Key_Help, "Help"}, +{Qt::Key_Space, "Space"}, +{Qt::Key_Any, "Any"}, +{Qt::Key_Space, "Space"}, +{Qt::Key_Exclam, "Exclam"}, +{Qt::Key_QuoteDbl, "QuoteDbl"}, +{Qt::Key_NumberSign, "NumberSign"}, +{Qt::Key_Dollar, "Dollar"}, +{Qt::Key_Percent, "Percent"}, +{Qt::Key_Ampersand, "Ampersand"}, +{Qt::Key_Apostrophe, "Apostrophe"}, +{Qt::Key_ParenLeft, "ParenLeft"}, +{Qt::Key_ParenRight, "ParenRight"}, +{Qt::Key_Asterisk, "Asterisk"}, +{Qt::Key_Plus, "Plus"}, +{Qt::Key_Comma, "Comma"}, +{Qt::Key_Minus, "Minus"}, +{Qt::Key_Period, "Period"}, +{Qt::Key_Slash, "Slash"}, +{Qt::Key_0, "0"}, +{Qt::Key_1, "1"}, +{Qt::Key_2, "2"}, +{Qt::Key_3, "3"}, +{Qt::Key_4, "4"}, +{Qt::Key_5, "5"}, +{Qt::Key_6, "6"}, +{Qt::Key_7, "7"}, +{Qt::Key_8, "8"}, +{Qt::Key_9, "9"}, +{Qt::Key_Colon, "Colon"}, +{Qt::Key_Semicolon, "Semicolon"}, +{Qt::Key_Less, "Less"}, +{Qt::Key_Equal, "Equal"}, +{Qt::Key_Greater, "Greater"}, +{Qt::Key_Question, "Question"}, +{Qt::Key_At, "At"}, +{Qt::Key_A, "A"}, +{Qt::Key_B, "B"}, +{Qt::Key_C, "C"}, +{Qt::Key_D, "D"}, +{Qt::Key_E, "E"}, +{Qt::Key_F, "F"}, +{Qt::Key_G, "G"}, +{Qt::Key_H, "H"}, +{Qt::Key_I, "I"}, +{Qt::Key_J, "J"}, +{Qt::Key_K, "K"}, +{Qt::Key_L, "L"}, +{Qt::Key_M, "M"}, +{Qt::Key_N, "N"}, +{Qt::Key_O, "O"}, +{Qt::Key_P, "P"}, +{Qt::Key_Q, "Q"}, +{Qt::Key_R, "R"}, +{Qt::Key_S, "S"}, +{Qt::Key_T, "T"}, +{Qt::Key_U, "U"}, +{Qt::Key_V, "V"}, +{Qt::Key_W, "W"}, +{Qt::Key_X, "X"}, +{Qt::Key_Y, "Y"}, +{Qt::Key_Z, "Z"}, +{Qt::Key_BracketLeft, "BracketLeft"}, +{Qt::Key_Backslash, "Backslash"}, +{Qt::Key_BracketRight, "BracketRight"}, +{Qt::Key_AsciiCircum, "AsciiCircum"}, +{Qt::Key_Underscore, "Underscore"}, +{Qt::Key_QuoteLeft, "QuoteLeft"}, +{Qt::Key_BraceLeft, "BraceLeft"}, +{Qt::Key_Bar, "Bar"}, +{Qt::Key_BraceRight, "BraceRight"}, +{Qt::Key_AsciiTilde, "AsciiTilde"}, +{Qt::Key_nobreakspace, "nobreakspace"}, +{Qt::Key_exclamdown, "exclamdown"}, +{Qt::Key_cent, "cent"}, +{Qt::Key_sterling, "sterling"}, +{Qt::Key_currency, "currency"}, +{Qt::Key_yen, "yen"}, +{Qt::Key_brokenbar, "brokenbar"}, +{Qt::Key_section, "section"}, +{Qt::Key_diaeresis, "diaeresis"}, +{Qt::Key_copyright, "copyright"}, +{Qt::Key_ordfeminine, "ordfeminine"}, +{Qt::Key_guillemotleft, "guillemotleft"}, +{Qt::Key_notsign, "notsign"}, +{Qt::Key_hyphen, "hyphen"}, +{Qt::Key_registered, "registered"}, +{Qt::Key_macron, "macron"}, +{Qt::Key_degree, "degree"}, +{Qt::Key_plusminus, "plusminus"}, +{Qt::Key_twosuperior, "twosuperior"}, +{Qt::Key_threesuperior, "threesuperior"}, +{Qt::Key_acute, "acute"}, +{Qt::Key_mu, "mu"}, +{Qt::Key_paragraph, "paragraph"}, +{Qt::Key_periodcentered, "periodcentered"}, +{Qt::Key_cedilla, "cedilla"}, +{Qt::Key_onesuperior, "onesuperior"}, +{Qt::Key_masculine, "masculine"}, +{Qt::Key_guillemotright, "guillemotright"}, +{Qt::Key_onequarter, "onequarter"}, +{Qt::Key_onehalf, "onehalf"}, +{Qt::Key_threequarters, "threequarters"}, +{Qt::Key_questiondown, "questiondown"}, +{Qt::Key_Agrave, "Agrave"}, +{Qt::Key_Aacute, "Aacute"}, +{Qt::Key_Acircumflex, "Acircumflex"}, +{Qt::Key_Atilde, "Atilde"}, +{Qt::Key_Adiaeresis, "Adiaeresis"}, +{Qt::Key_Aring, "Aring"}, +{Qt::Key_AE, "AE"}, +{Qt::Key_Ccedilla, "Ccedilla"}, +{Qt::Key_Egrave, "Egrave"}, +{Qt::Key_Eacute, "Eacute"}, +{Qt::Key_Ecircumflex, "Ecircumflex"}, +{Qt::Key_Ediaeresis, "Ediaeresis"}, +{Qt::Key_Igrave, "Igrave"}, +{Qt::Key_Iacute, "Iacute"}, +{Qt::Key_Icircumflex, "Icircumflex"}, +{Qt::Key_Idiaeresis, "Idiaeresis"}, +{Qt::Key_ETH, "ETH"}, +{Qt::Key_Ntilde, "Ntilde"}, +{Qt::Key_Ograve, "Ograve"}, +{Qt::Key_Oacute, "Oacute"}, +{Qt::Key_Ocircumflex, "Ocircumflex"}, +{Qt::Key_Otilde, "Otilde"}, +{Qt::Key_Odiaeresis, "Odiaeresis"}, +{Qt::Key_multiply, "multiply"}, +{Qt::Key_Ooblique, "Ooblique"}, +{Qt::Key_Ugrave, "Ugrave"}, +{Qt::Key_Uacute, "Uacute"}, +{Qt::Key_Ucircumflex, "Ucircumflex"}, +{Qt::Key_Udiaeresis, "Udiaeresis"}, +{Qt::Key_Yacute, "Yacute"}, +{Qt::Key_THORN, "THORN"}, +{Qt::Key_ssharp, "ssharp"}, +{Qt::Key_agrave, "agrave"}, +{Qt::Key_aacute, "aacute"}, +{Qt::Key_acircumflex, "acircumflex"}, +{Qt::Key_atilde, "atilde"}, +{Qt::Key_adiaeresis, "adiaeresis"}, +{Qt::Key_aring, "aring"}, +{Qt::Key_ae, "ae"}, +{Qt::Key_ccedilla, "ccedilla"}, +{Qt::Key_egrave, "egrave"}, +{Qt::Key_eacute, "eacute"}, +{Qt::Key_ecircumflex, "ecircumflex"}, +{Qt::Key_ediaeresis, "ediaeresis"}, +{Qt::Key_igrave, "igrave"}, +{Qt::Key_iacute, "iacute"}, +{Qt::Key_icircumflex, "icircumflex"}, +{Qt::Key_idiaeresis, "idiaeresis"}, +{Qt::Key_eth, "eth"}, +{Qt::Key_ntilde, "ntilde"}, +{Qt::Key_ograve, "ograve"}, +{Qt::Key_oacute, "oacute"}, +{Qt::Key_ocircumflex, "ocircumflex"}, +{Qt::Key_otilde, "otilde"}, +{Qt::Key_odiaeresis, "odiaeresis"}, +{Qt::Key_division, "division"}, +{Qt::Key_oslash, "oslash"}, +{Qt::Key_ugrave, "ugrave"}, +{Qt::Key_uacute, "uacute"}, +{Qt::Key_ucircumflex, "ucircumflex"}, +{Qt::Key_udiaeresis, "udiaeresis"}, +{Qt::Key_yacute, "yacute"}, +{Qt::Key_thorn, "thorn"}, +{Qt::Key_ydiaeresis, "ydiaeresis"}, +{Qt::Key_unknown, "unknown"}, +{0,0}, +}; + +void KeyNames::setCodeMap() +{ + int i; + + codemap.clear(); + for(i=0; stKeyNames[i].code != 0; i++){ + codemap.insert(stKeyNames[i].name, stKeyNames[i].code); + } +} + +void KeyNames::setNameMap() +{ + int i; + + namemap.clear(); + for(i=0; stKeyNames[i].code != 0; i++){ + namemap.insert(stKeyNames[i].code, stKeyNames[i].name); + } +} + + +int KeyNames::getCode(const QString& s){ + if(codemap.isEmpty()) setCodeMap(); + if(codemap.contains(s)){ + return(codemap[s]); + } else { + if(s.find("0x") == 0){ + bool success; + int val = s.mid(2).toInt(&success, 16); + if(success){ + return(val); + } + } + return(0); + } +} + +const QString& KeyNames::getName(int code){ + if(namemap.isEmpty()) setNameMap(); + if(namemap.contains(code)){ + return(namemap[code]); + } else { + tmpname.sprintf("0x%x", code); + return(tmpname); + //return(QString::null); + } +} diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/KeyNames.h b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyNames.h new file mode 100644 index 0000000..3e80763 --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyNames.h @@ -0,0 +1,37 @@ +#ifndef _KEY_NAMES_H_ +#define _KEY_NAMES_H_ + +#include <qstring.h> +#include <qmap.h> +#include <qnamespace.h> + +class KeyNames +{ +public: + static const QString& getName(int code); + static int getCode(const QString& s); + + static void clearName(){ + namemap.clear(); + } + static void setCode(const QString& s, int code){ + if(codemap.contains(s) == false){ + codemap.insert(s, code); + } + } + static void clearCode(){ + codemap.clear(); + } + static void reset(){ + clearCode(); + } +private: + static QMap<QString, int> codemap; + static QMap<int, QString> namemap; + static QString tmpname; + + static void setCodeMap(); + static void setNameMap(); +}; + +#endif /* _KEY_NAMES_H_ */ diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/KeyRepeater.cpp b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyRepeater.cpp new file mode 100644 index 0000000..84a8a89 --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyRepeater.cpp @@ -0,0 +1,140 @@ +#include "KeyRepeater.h" + +KeyRepeater::KeyRepeater() +{ + qDebug("KeyRepeater::KeyRepeater()"); + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(autoRepeat())); + init(); +} + +KeyRepeater::~KeyRepeater() +{ + qDebug("KeyRepeater::~KeyRepeater()"); + delete m_pTimer; +} + +void KeyRepeater::start(int unicode, int keycode, int modifiers) +{ + m_unicode = unicode; + m_keycode = keycode; + m_modifiers = modifiers; + if(m_mode == ENABLE){ + m_pTimer->stop(); + if(isRepeatable(keycode)){ + /* repeater start */ + m_pTimer->start(m_repeatdelay, TRUE); + } + } +} + +void KeyRepeater::stop(int keycode) +{ + if(keycode == 0 + || keycode == m_keycode + || isRepeatable(keycode) == false){ + m_pTimer->stop(); + } +} + +void KeyRepeater::init() +{ + m_mode = ENABLE; + m_repeatdelay = 400; + m_repeatperiod = 60; + m_disablekeys.append(0); + m_disablekeys.append(Qt::Key_Escape); + m_disablekeys.append(Qt::Key_Shift); + m_disablekeys.append(Qt::Key_Control); + m_disablekeys.append(Qt::Key_Alt); + m_disablekeys.append(Qt::Key_Meta); + for(int i=Qt::Key_F1; i<=Qt::Key_F35; i++){ + m_disablekeys.append(i); + } +} + +void KeyRepeater::clear() +{ + m_disablekeys.clear(); +} + +void KeyRepeater::reset() +{ + clear(); + init(); +} + +void KeyRepeater::setRepeatable(int keycode, bool enable) +{ + if(enable){ + QValueList<int>::Iterator it = m_disablekeys.find(keycode); + if(it != m_disablekeys.end()){ + m_disablekeys.remove(it); + } + } else { + if(m_disablekeys.contains(keycode) == false){ + m_disablekeys.append(keycode); + } + } +} + +bool KeyRepeater::isRepeatable(int keycode) +{ + if(m_disablekeys.contains(keycode)){ + return(false); + } else { + return(true); + } +} + +void KeyRepeater::autoRepeat() +{ + /* key release event */ +#if 0 + sendKeyEvent( + m_unicode, + m_keycode, + m_modifiers, + FALSE, + TRUE); + /* key press event */ + sendKeyEvent( + m_unicode, + m_keycode, + m_modifiers, + TRUE, + TRUE); +#else + emit keyEvent( + m_unicode, + m_keycode, + m_modifiers, + FALSE, + TRUE); + /* key press event */ + emit keyEvent( + m_unicode, + m_keycode, + m_modifiers, + TRUE, + TRUE); +#endif + /* start auto repeat */ + m_pTimer->start(m_repeatperiod); +#if 0 + qDebug("autoRepeat[%x][%x][%x]", + m_unicode, + m_keycode, + m_modifiers); +#endif +} + +void KeyRepeater::statistics() +{ + qWarning("KeyRepeater::statistics()"); + qWarning(" delay[%d] period[%d]", m_repeatdelay, m_repeatperiod); + for(QValueList<int>::Iterator it=m_disablekeys.begin(); + it!=m_disablekeys.end(); ++it){ + qDebug(" disable[%x]", *it); + } +} diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/KeyRepeater.h b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyRepeater.h new file mode 100644 index 0000000..56d6414 --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/KeyRepeater.h @@ -0,0 +1,86 @@ +#ifndef _KEY_REPEATER_H_ +#define _KEY_REPEATER_H_ + +#include <qobject.h> +#include <qtimer.h> +#include <qvaluelist.h> +#include <qwindowsystem_qws.h> + +#include <syslog.h> + +class KeyRepeater : public QObject +{ + Q_OBJECT +public: + KeyRepeater(); + virtual ~KeyRepeater(); + + typedef enum { + DISABLE=0, + ENABLE=1, + KILL=2, + } RepeaterMode; + + void start(int unicode, int keycode, int modifieres); + void stop(int keycode = 0); + void reset(); + + void setRepeatable(int keycode, bool enable); + bool isRepeatable(int keycode); + + void setMode(int mode){ + switch(mode){ + case DISABLE: + m_mode = DISABLE; + break; + case ENABLE: + m_mode = ENABLE; + break; + case KILL: + m_mode = KILL; + break; + default: + m_mode = ENABLE; + break; + } + } + RepeaterMode getMode(){ + return(m_mode); + } + + void setDelay(int msec) + { + m_repeatdelay = msec; + } + void setPeriod(int msec) + { + m_repeatperiod = msec; + } + + void statistics(); +private slots: + void autoRepeat(); +private: + int m_unicode; + int m_keycode; + int m_modifiers; + + int m_repeatdelay; + int m_repeatperiod; + + QCString m_hookChannel; + + RepeaterMode m_mode; + + QValueList<int> m_disablekeys; + + QTimer* m_pTimer; + + void init(); + void clear(); +signals: + void keyEvent(int unicode, int keycode, int modifiers, + bool isPress, bool autoRepeat); +}; + +#endif /* _KEY_REPEATER_H_ */ diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/StringParser.cpp b/noncore/applets/keyhelper/keyhelperapplet/misc/StringParser.cpp new file mode 100644 index 0000000..72c15f1 --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/StringParser.cpp @@ -0,0 +1,72 @@ +#include "StringParser.h" + +#include <qregexp.h> + +QStringList StringParser::split(const QChar& sep, const QString& str, + bool allowEmptyEntries) +{ + QString line = str + sep; + QString quote; + QRegExp rxend; + QRegExp rxdbl; + int pos=0, len, idx=0; + QStringList list; + while(idx < (int)line.length()-1){ + if(!quote.isEmpty()){ + QString s; + while((pos = rxend.match(line, idx, &len)) != -1){ + s += line.mid(idx, len+pos-idx-1); + idx = pos+len-1; + if(len % 2 == 0){ + s.replace(rxdbl, quote); + list.append(s.left(s.length()-1)); + idx++; + break; + } + } + quote = ""; + } else if(line[idx] == '\"'){ + rxend.setPattern(QString("\"+") + sep); + rxdbl.setPattern("\"\""); + quote = "\""; + idx++; + } else if(line[idx] == '\''){ + rxend.setPattern(QString("\'+") + sep); + rxdbl.setPattern("\'\'"); + quote = "\'"; + idx++; + } else if(!allowEmptyEntries && line[idx] == sep){ + idx++; + } else { + pos = line.find(sep, idx); + if(pos != -1){ + const QString& s = line.mid(idx, pos-idx); + list.append(s); + idx = pos+1; + } + } + if(pos == -1) break; + } + return list; +} + +QString StringParser::join(const QChar& sep, const QStringList& list) +{ + QString str; + QString s; + QStringList tmp; + QRegExp quote("\""); + for(QStringList::ConstIterator it=list.begin(); + it!=list.end(); ++it){ + s = *it; + if(s.find(sep) != -1 + || s[0] == '\"' + || s[0] == '\''){ + s.replace(quote, "\"\""); + tmp.append("\"" + s + "\""); + } else { + tmp.append(s); + } + } + return tmp.join(sep); +} diff --git a/noncore/applets/keyhelper/keyhelperapplet/misc/StringParser.h b/noncore/applets/keyhelper/keyhelperapplet/misc/StringParser.h new file mode 100644 index 0000000..8c1dc58 --- a/dev/null +++ b/noncore/applets/keyhelper/keyhelperapplet/misc/StringParser.h @@ -0,0 +1,14 @@ +#ifndef _STRING_PARSER_H_ +#define _STRING_PARSER_H_ + +#include <qstringlist.h> + +class StringParser +{ +public: + static QStringList split(const QChar& sep, const QString& str, + bool allowEmptyEntries=FALSE); + static QString join(const QChar& sep, const QStringList& list); +}; + +#endif /* _STRING_PARSER_H_ */ |