summaryrefslogtreecommitdiff
path: root/noncore/applets/keyhelper/keyhelperapplet/misc/KeyMappings.cpp
Side-by-side diff
Diffstat (limited to 'noncore/applets/keyhelper/keyhelperapplet/misc/KeyMappings.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/misc/KeyMappings.cpp340
1 files changed, 340 insertions, 0 deletions
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);
+}