summaryrefslogtreecommitdiff
path: root/noncore/applets/keyhelper/keyhelperapplet/misc
Side-by-side diff
Diffstat (limited to 'noncore/applets/keyhelper/keyhelperapplet/misc') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/ConfigEx.cpp112
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/ConfigEx.h89
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/KHUtil.cpp90
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/KHUtil.h15
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/KeyAction.cpp253
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/KeyAction.h87
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/KeyMappings.cpp340
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/KeyMappings.h72
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/KeyModifiers.cpp285
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/KeyModifiers.h80
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/KeyNames.cpp303
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/KeyNames.h37
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/KeyRepeater.cpp140
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/KeyRepeater.h86
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/StringParser.cpp72
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/StringParser.h14
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_ */