summaryrefslogtreecommitdiffstats
path: root/konsole/konsole/keytrans.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'konsole/konsole/keytrans.cpp')
-rw-r--r--konsole/konsole/keytrans.cpp755
1 files changed, 755 insertions, 0 deletions
diff --git a/konsole/konsole/keytrans.cpp b/konsole/konsole/keytrans.cpp
new file mode 100644
index 000000000..7632520ba
--- /dev/null
+++ b/konsole/konsole/keytrans.cpp
@@ -0,0 +1,755 @@
+/*
+ This file is part of Konsole, an X terminal.
+ Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+*/
+
+/*
+ The keyboard translation table allows to configure konsoles behavior
+ on key strokes.
+
+ FIXME: some bug crept in, disallowing '\0' to be emitted.
+*/
+
+#include "keytrans.h"
+#include <qbuffer.h>
+#include <qobject.h>
+#include <qintdict.h>
+#include <qfile.h>
+#include <kstandarddirs.h>
+#include <klocale.h>
+
+#include <stdio.h>
+#include <stddef.h>
+
+/* KeyEntry
+
+ instances represent the individual assignments
+*/
+
+KeyTrans::KeyEntry::KeyEntry(int _ref, int _key, int _bits, int _mask, int _cmd, QString _txt)
+: ref(_ref), key(_key), bits(_bits), mask(_mask), cmd(_cmd), txt(_txt)
+{
+}
+
+KeyTrans::KeyEntry::~KeyEntry()
+{
+}
+
+bool KeyTrans::KeyEntry::matches(int _key, int _bits, int _mask)
+{ int m = mask & _mask;
+ return _key == key && (bits & m) == (_bits & m);
+}
+
+bool KeyTrans::KeyEntry::metaspecified(void)
+{
+ return ((mask & (1 << BITS_Alt)) && (bits & (1 << BITS_Alt))) ||
+ ((mask & (1 << BITS_AnyMod)) && (bits & (1 << BITS_AnyMod)));
+}
+
+bool KeyTrans::KeyEntry::anymodspecified(void)
+{
+ return (mask & (1 << BITS_AnyMod)) && (bits & (1 << BITS_AnyMod));
+}
+
+QString KeyTrans::KeyEntry::text()
+{
+ return txt;
+}
+
+/* KeyTrans
+
+ combines the individual assignments to a proper map
+ Takes part in a collection themself.
+*/
+
+KeyTrans::KeyTrans(const QString& path)
+:m_path(path)
+,m_numb(0)
+,m_fileRead(false)
+{
+ tableX.setAutoDelete(true);
+ if (m_path=="[buildin]")
+ {
+ m_id = "default";
+ }
+ else
+ {
+ m_id = m_path;
+ int i = m_id.findRev('/');
+ if (i > -1)
+ m_id = m_id.mid(i+1);
+ i = m_id.findRev('.');
+ if (i > -1)
+ m_id = m_id.left(i);
+ }
+}
+
+KeyTrans::KeyTrans()
+{
+/* table.setAutoDelete(true);
+ path = "";
+ numb = 0;*/
+}
+
+KeyTrans::~KeyTrans()
+{
+}
+
+KeyTrans::KeyEntry* KeyTrans::addEntry(int ref, int key, int bits, int mask, int cmd, QString txt)
+// returns conflicting entry
+{
+ for (QPtrListIterator<KeyEntry> it(tableX); it.current(); ++it)
+ {
+ if (it.current()->matches(key,bits,mask))
+ {
+ return it.current();
+ }
+ }
+ tableX.append(new KeyEntry(ref,key,bits,mask,cmd,txt));
+ return (KeyEntry*)NULL;
+}
+
+bool KeyTrans::findEntry(int key, int bits, int* cmd, const char** txt, int* len,
+ bool* metaspecified)
+{
+ if (!m_fileRead) readConfig();
+
+ if (bits & ((1<<BITS_Shift)|(1<<BITS_Alt)|(1<<BITS_Control)))
+ bits |= (1<<BITS_AnyMod);
+
+ for (QPtrListIterator<KeyEntry> it(tableX); it.current(); ++it)
+ if (it.current()->matches(key,bits,0xffff))
+ {
+ *cmd = it.current()->cmd;
+ *len = it.current()->txt.length();
+ if ((*cmd==CMD_send) && it.current()->anymodspecified() && (*len < 16))
+ {
+ static char buf[16];
+ char *c, mask = '1' + BITS(0, bits&(1<<BITS_Shift)) +
+ BITS(1, bits&(1<<BITS_Alt)) + BITS(2, bits&(1<<BITS_Control));
+ strcpy(buf, it.current()->txt.ascii());
+ c = strchr(buf, '*');
+ if (c) *c = mask;
+ *txt = buf;
+ }
+ else
+ *txt = it.current()->txt.ascii();
+ *metaspecified = it.current()->metaspecified();
+ return true;
+ }
+ return false;
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Scanner for keyboard configuration */
+/* */
+/* ------------------------------------------------------------------------- */
+
+// regular tokenizer
+/* Tokens
+ - Spaces
+ - Name (A-Za-z0-9)+
+ - String
+ - Opr on of +-:
+*/
+
+#define SYMName 0
+#define SYMString 1
+#define SYMEol 2
+#define SYMEof 3
+#define SYMOpr 4
+#define SYMError 5
+
+#define inRange(L,X,H) ((L <= X) && (X <= H))
+#define isNibble(X) (inRange('A',X,'F')||inRange('a',X,'f')||inRange('0',X,'9'))
+#define convNibble(X) (inRange('0',X,'9')?X-'0':X+10-(inRange('A',X,'F')?'A':'a'))
+
+class KeytabReader
+{
+public:
+ KeytabReader(QString p, QIODevice &d);
+public:
+ void getCc();
+ void getSymbol();
+ void parseTo(KeyTrans* kt);
+ void ReportError(const char* msg);
+ void ReportToken(); // diagnostic
+private:
+ int sym;
+ QString res;
+ int len;
+ int slinno;
+ int scolno;
+private:
+ int cc;
+ int linno;
+ int colno;
+ QIODevice* buf;
+ QString path;
+};
+
+
+KeytabReader::KeytabReader(QString p, QIODevice &d)
+{
+ path = p;
+ buf = &d;
+ cc = 0;
+ colno = 0;
+}
+
+void KeytabReader::getCc()
+{
+ if (cc == '\n') { linno += 1; colno = 0; }
+ if (cc < 0) return;
+ cc = buf->getch();
+ colno += 1;
+}
+
+void KeytabReader::getSymbol()
+{
+ res = ""; len = 0; sym = SYMError;
+ while (cc == ' ') getCc(); // skip spaces
+ if (cc == '#') // skip comment
+ {
+ while (cc != '\n' && cc > 0) getCc();
+ }
+ slinno = linno;
+ scolno = colno;
+ if (cc <= 0)
+ {
+ sym = SYMEof; // eos
+ }
+ else if (cc == '\n')
+ {
+ getCc();
+ sym = SYMEol; // eol
+ }
+ else if (inRange('A',cc,'Z')||inRange('a',cc,'z')||inRange('0',cc,'9')||(cc=='_'))
+ {
+ while (inRange('A',cc,'Z') || inRange('a',cc,'z') || inRange('0',cc,'9') || (cc=='_'))
+ {
+ res = res + (char)cc;
+ getCc();
+ }
+ sym = SYMName;
+ }
+ else if (strchr("+-:",cc))
+ {
+ res = "";
+ res = res + (char)cc;
+ getCc();
+ sym = SYMOpr;
+ }
+ else if (cc == '"')
+ {
+ getCc();
+ while (cc >= ' ' && cc != '"')
+ { int sc;
+ if (cc == '\\') // handle quotation
+ {
+ getCc();
+ switch (cc)
+ {
+ case 'E' : sc = 27; getCc(); break;
+ case 'b' : sc = 8; getCc(); break;
+ case 'f' : sc = 12; getCc(); break;
+ case 't' : sc = 9; getCc(); break;
+ case 'r' : sc = 13; getCc(); break;
+ case 'n' : sc = 10; getCc(); break;
+ case '\\' : // fall thru
+ case '"' : sc = cc; getCc(); break;
+ case 'x' : getCc();
+ sc = 0;
+ if (!isNibble(cc)) return; sc = 16*sc + convNibble(cc); getCc();
+ if (!isNibble(cc)) return; sc = 16*sc + convNibble(cc); getCc();
+ break;
+ default : return;
+ }
+ }
+ else
+ {
+ // regular char
+ sc = cc; getCc();
+ }
+ res = res + (char)sc;
+ len = len + 1;
+ }
+ if (cc != '"') return;
+ getCc();
+ sym = SYMString;
+ }
+ else
+ {
+ // cc was an invalid char. Get next cc or we will loop forever.
+ getCc();
+ }
+}
+
+void KeytabReader::ReportToken() // diagnostic
+{
+ printf("sym(%d): ",slinno);
+ switch(sym)
+ {
+ case SYMEol : printf("End of line"); break;
+ case SYMEof : printf("End of file"); break;
+ case SYMName : printf("Name: %s",res.latin1()); break;
+ case SYMOpr : printf("Opr : %s",res.latin1()); break;
+ case SYMString : printf("String len %d,%d ",res.length(),len);
+ for (unsigned i = 0; i < res.length(); i++)
+ printf(" %02x(%c)",res.latin1()[i],res.latin1()[i]>=' '?res.latin1()[i]:'?');
+ break;
+ }
+ printf("\n");
+}
+
+void KeytabReader::ReportError(const char* msg) // diagnostic
+{
+ fprintf(stderr,"%s(%d,%d):error: %s.\n",path.ascii(),slinno,scolno,msg);
+}
+
+// local symbol tables ---------------------------------------------------------------------
+
+class KeyTransSymbols
+{
+public:
+ KeyTransSymbols();
+protected:
+ void defOprSyms();
+ void defModSyms();
+ void defKeySyms();
+ void defKeySym(const char* key, int val);
+ void defOprSym(const char* key, int val);
+ void defModSym(const char* key, int val);
+public:
+ QDict<QObject> keysyms;
+ QDict<QObject> modsyms;
+ QDict<QObject> oprsyms;
+};
+
+static KeyTransSymbols * syms = 0L;
+
+// parser ----------------------------------------------------------------------------------
+/* Syntax
+ - Line :: [KeyName { ("+" | "-") ModeName } ":" (String|CommandName)] "\n"
+ - Comment :: '#' (any but \n)*
+*/
+
+void KeyTrans::readConfig()
+{
+ if (m_fileRead) return;
+ m_fileRead=true;
+ QIODevice* buf(0);
+ if (m_path=="[buildin]")
+ {
+ QCString txt =
+#include "default.keytab.h"
+;
+ buf=new QBuffer(txt);
+ }
+ else
+ {
+ buf=new QFile(m_path);
+ };
+ KeytabReader ktr(m_path,*buf);
+ ktr.parseTo(this);
+ delete buf;
+}
+
+#define assertSyntax(Cond,Message) if (!(Cond)) { ReportError(Message); goto ERROR; }
+
+void KeytabReader::parseTo(KeyTrans* kt)
+{
+ // Opening sequence
+
+ buf->open(IO_ReadOnly);
+ getCc();
+ linno = 1;
+ colno = 1;
+ getSymbol();
+
+Loop:
+ // syntax: ["key" KeyName { ("+" | "-") ModeName } ":" String/CommandName] ["#" Comment]
+ if (sym == SYMName && !strcmp(res.latin1(),"keyboard"))
+ {
+ getSymbol(); assertSyntax(sym == SYMString, "Header expected")
+ kt->m_hdr = i18n(res.latin1());
+ getSymbol(); assertSyntax(sym == SYMEol, "Text unexpected")
+ getSymbol(); // eoln
+ goto Loop;
+ }
+ if (sym == SYMName && !strcmp(res.latin1(),"key"))
+ {
+//printf("line %3d: ",startofsym);
+ getSymbol(); assertSyntax(sym == SYMName, "Name expected")
+ assertSyntax(syms->keysyms[res], "Unknown key name")
+ ptrdiff_t key = (ptrdiff_t)(syms->keysyms[res]) - 1;
+//printf(" key %s (%04x)",res.latin1(),(int)syms->keysyms[res]-1);
+ getSymbol(); // + - :
+ int mode = 0;
+ int mask = 0;
+ while (sym == SYMOpr && (!strcmp(res.latin1(),"+") || !strcmp(res.latin1(),"-")))
+ {
+ bool on = !strcmp(res.latin1(),"+");
+ getSymbol();
+ // mode name
+ assertSyntax(sym == SYMName, "Name expected")
+ assertSyntax(syms->modsyms[res], "Unknown mode name")
+ ptrdiff_t bits = (ptrdiff_t)(syms->modsyms[res]) - 1;
+ if (mask & (1 << bits))
+ {
+ fprintf(stderr,"%s(%d,%d): mode name used multiple times.\n",path.ascii(),slinno,scolno);
+ }
+ else
+ {
+ mode |= (on << bits);
+ mask |= (1 << bits);
+ }
+//printf(", mode %s(%d) %s",res.latin1(),(int)syms->modsyms[res]-1,on?"on":"off");
+ getSymbol();
+ }
+ assertSyntax(sym == SYMOpr && !strcmp(res.latin1(),":"), "':' expected")
+ getSymbol();
+ // string or command
+ assertSyntax(sym == SYMName || sym == SYMString,"Command or string expected")
+ ptrdiff_t cmd = 0;
+ if (sym == SYMName)
+ {
+ assertSyntax(syms->oprsyms[res], "Unknown operator name")
+ cmd = (ptrdiff_t)(syms->oprsyms[res]) - 1;
+//printf(": do %s(%d)",res.latin1(),(int)syms->oprsyms[res]-1);
+ }
+ if (sym == SYMString)
+ {
+ cmd = CMD_send;
+//printf(": send");
+//for (unsigned i = 0; i < res.length(); i++)
+//printf(" %02x(%c)",res.latin1()[i],res.latin1()[i]>=' '?res.latin1()[i]:'?');
+ }
+//printf(". summary %04x,%02x,%02x,%d\n",key,mode,mask,cmd);
+ KeyTrans::KeyEntry* ke = kt->addEntry(slinno,key,mode,mask,cmd,res);
+ if (ke)
+ {
+ fprintf(stderr,"%s(%d): keystroke already assigned in line %d.\n",path.ascii(),slinno,ke->ref);
+ }
+ getSymbol();
+ assertSyntax(sym == SYMEol, "Unexpected text")
+ goto Loop;
+ }
+ if (sym == SYMEol)
+ {
+ getSymbol();
+ goto Loop;
+ }
+
+ assertSyntax(sym == SYMEof, "Undecodable Line")
+
+ buf->close();
+ return;
+
+ERROR:
+ while (sym != SYMEol && sym != SYMEof) getSymbol(); // eoln
+ goto Loop;
+}
+
+
+// local symbol tables ---------------------------------------------------------------------
+// material needed for parsing the config file.
+// This is incomplete work.
+
+void KeyTransSymbols::defKeySym(const char* key, int val)
+{
+ keysyms.insert(key,(QObject*)(val+1));
+}
+
+void KeyTransSymbols::defOprSym(const char* key, int val)
+{
+ oprsyms.insert(key,(QObject*)(val+1));
+}
+
+void KeyTransSymbols::defModSym(const char* key, int val)
+{
+ modsyms.insert(key,(QObject*)(val+1));
+}
+
+void KeyTransSymbols::defOprSyms()
+{
+ // Modifier
+ defOprSym("scrollLineUp", CMD_scrollLineUp );
+ defOprSym("scrollLineDown",CMD_scrollLineDown);
+ defOprSym("scrollPageUp", CMD_scrollPageUp );
+ defOprSym("scrollPageDown",CMD_scrollPageDown);
+ defOprSym("scrollLock", CMD_scrollLock);
+}
+
+void KeyTransSymbols::defModSyms()
+{
+ // Modifier
+ defModSym("Shift", BITS_Shift );
+ defModSym("Control", BITS_Control );
+ defModSym("Alt", BITS_Alt );
+ // Modes
+ defModSym("BsHack", BITS_BsHack ); // deprecated
+ defModSym("Ansi", BITS_Ansi );
+ defModSym("NewLine", BITS_NewLine );
+ defModSym("AppCuKeys", BITS_AppCuKeys );
+ defModSym("AppScreen", BITS_AppScreen );
+ // Special (Any Modifier)
+ defModSym("AnyMod", BITS_AnyMod );
+}
+
+void KeyTransSymbols::defKeySyms()
+{
+ // Grey keys
+ defKeySym("Escape", Qt::Key_Escape );
+ defKeySym("Tab", Qt::Key_Tab );
+ defKeySym("Backtab", Qt::Key_Backtab );
+ defKeySym("Backspace", Qt::Key_Backspace );
+ defKeySym("Return", Qt::Key_Return );
+ defKeySym("Enter", Qt::Key_Enter );
+ defKeySym("Insert", Qt::Key_Insert );
+ defKeySym("Delete", Qt::Key_Delete );
+ defKeySym("Pause", Qt::Key_Pause );
+ defKeySym("Print", Qt::Key_Print );
+ defKeySym("SysReq", Qt::Key_SysReq );
+ defKeySym("Home", Qt::Key_Home );
+ defKeySym("End", Qt::Key_End );
+ defKeySym("Left", Qt::Key_Left );
+ defKeySym("Up", Qt::Key_Up );
+ defKeySym("Right", Qt::Key_Right );
+ defKeySym("Down", Qt::Key_Down );
+ defKeySym("Prior", Qt::Key_Prior );
+ defKeySym("Next", Qt::Key_Next );
+ defKeySym("Shift", Qt::Key_Shift );
+ defKeySym("Control", Qt::Key_Control );
+ defKeySym("Meta", Qt::Key_Meta );
+ defKeySym("Alt", Qt::Key_Alt );
+ defKeySym("CapsLock", Qt::Key_CapsLock );
+ defKeySym("NumLock", Qt::Key_NumLock );
+ defKeySym("ScrollLock", Qt::Key_ScrollLock );
+ defKeySym("F1", Qt::Key_F1 );
+ defKeySym("F2", Qt::Key_F2 );
+ defKeySym("F3", Qt::Key_F3 );
+ defKeySym("F4", Qt::Key_F4 );
+ defKeySym("F5", Qt::Key_F5 );
+ defKeySym("F6", Qt::Key_F6 );
+ defKeySym("F7", Qt::Key_F7 );
+ defKeySym("F8", Qt::Key_F8 );
+ defKeySym("F9", Qt::Key_F9 );
+ defKeySym("F10", Qt::Key_F10 );
+ defKeySym("F11", Qt::Key_F11 );
+ defKeySym("F12", Qt::Key_F12 );
+ defKeySym("F13", Qt::Key_F13 );
+ defKeySym("F14", Qt::Key_F14 );
+ defKeySym("F15", Qt::Key_F15 );
+ defKeySym("F16", Qt::Key_F16 );
+ defKeySym("F17", Qt::Key_F17 );
+ defKeySym("F18", Qt::Key_F18 );
+ defKeySym("F19", Qt::Key_F19 );
+ defKeySym("F20", Qt::Key_F20 );
+ defKeySym("F21", Qt::Key_F21 );
+ defKeySym("F22", Qt::Key_F22 );
+ defKeySym("F23", Qt::Key_F23 );
+ defKeySym("F24", Qt::Key_F24 );
+ defKeySym("F25", Qt::Key_F25 );
+ defKeySym("F26", Qt::Key_F26 );
+ defKeySym("F27", Qt::Key_F27 );
+ defKeySym("F28", Qt::Key_F28 );
+ defKeySym("F29", Qt::Key_F29 );
+ defKeySym("F30", Qt::Key_F30 );
+ defKeySym("F31", Qt::Key_F31 );
+ defKeySym("F32", Qt::Key_F32 );
+ defKeySym("F33", Qt::Key_F33 );
+ defKeySym("F34", Qt::Key_F34 );
+ defKeySym("F35", Qt::Key_F35 );
+ defKeySym("Super_L", Qt::Key_Super_L );
+ defKeySym("Super_R", Qt::Key_Super_R );
+ defKeySym("Menu", Qt::Key_Menu );
+ defKeySym("Hyper_L", Qt::Key_Hyper_L );
+ defKeySym("Hyper_R", Qt::Key_Hyper_R );
+
+ // Regular keys
+ defKeySym("Space", Qt::Key_Space );
+ defKeySym("Exclam", Qt::Key_Exclam );
+ defKeySym("QuoteDbl", Qt::Key_QuoteDbl );
+ defKeySym("NumberSign", Qt::Key_NumberSign );
+ defKeySym("Dollar", Qt::Key_Dollar );
+ defKeySym("Percent", Qt::Key_Percent );
+ defKeySym("Ampersand", Qt::Key_Ampersand );
+ defKeySym("Apostrophe", Qt::Key_Apostrophe );
+ defKeySym("ParenLeft", Qt::Key_ParenLeft );
+ defKeySym("ParenRight", Qt::Key_ParenRight );
+ defKeySym("Asterisk", Qt::Key_Asterisk );
+ defKeySym("Plus", Qt::Key_Plus );
+ defKeySym("Comma", Qt::Key_Comma );
+ defKeySym("Minus", Qt::Key_Minus );
+ defKeySym("Period", Qt::Key_Period );
+ defKeySym("Slash", Qt::Key_Slash );
+ defKeySym("0", Qt::Key_0 );
+ defKeySym("1", Qt::Key_1 );
+ defKeySym("2", Qt::Key_2 );
+ defKeySym("3", Qt::Key_3 );
+ defKeySym("4", Qt::Key_4 );
+ defKeySym("5", Qt::Key_5 );
+ defKeySym("6", Qt::Key_6 );
+ defKeySym("7", Qt::Key_7 );
+ defKeySym("8", Qt::Key_8 );
+ defKeySym("9", Qt::Key_9 );
+ defKeySym("Colon", Qt::Key_Colon );
+ defKeySym("Semicolon", Qt::Key_Semicolon );
+ defKeySym("Less", Qt::Key_Less );
+ defKeySym("Equal", Qt::Key_Equal );
+ defKeySym("Greater", Qt::Key_Greater );
+ defKeySym("Question", Qt::Key_Question );
+ defKeySym("At", Qt::Key_At );
+ defKeySym("A", Qt::Key_A );
+ defKeySym("B", Qt::Key_B );
+ defKeySym("C", Qt::Key_C );
+ defKeySym("D", Qt::Key_D );
+ defKeySym("E", Qt::Key_E );
+ defKeySym("F", Qt::Key_F );
+ defKeySym("G", Qt::Key_G );
+ defKeySym("H", Qt::Key_H );
+ defKeySym("I", Qt::Key_I );
+ defKeySym("J", Qt::Key_J );
+ defKeySym("K", Qt::Key_K );
+ defKeySym("L", Qt::Key_L );
+ defKeySym("M", Qt::Key_M );
+ defKeySym("N", Qt::Key_N );
+ defKeySym("O", Qt::Key_O );
+ defKeySym("P", Qt::Key_P );
+ defKeySym("Q", Qt::Key_Q );
+ defKeySym("R", Qt::Key_R );
+ defKeySym("S", Qt::Key_S );
+ defKeySym("T", Qt::Key_T );
+ defKeySym("U", Qt::Key_U );
+ defKeySym("V", Qt::Key_V );
+ defKeySym("W", Qt::Key_W );
+ defKeySym("X", Qt::Key_X );
+ defKeySym("Y", Qt::Key_Y );
+ defKeySym("Z", Qt::Key_Z );
+ defKeySym("BracketLeft", Qt::Key_BracketLeft );
+ defKeySym("Backslash", Qt::Key_Backslash );
+ defKeySym("BracketRight", Qt::Key_BracketRight);
+ defKeySym("AsciiCircum", Qt::Key_AsciiCircum );
+ defKeySym("Underscore", Qt::Key_Underscore );
+ defKeySym("QuoteLeft", Qt::Key_QuoteLeft );
+ defKeySym("BraceLeft", Qt::Key_BraceLeft );
+ defKeySym("Bar", Qt::Key_Bar );
+ defKeySym("BraceRight", Qt::Key_BraceRight );
+ defKeySym("AsciiTilde", Qt::Key_AsciiTilde );
+}
+
+KeyTransSymbols::KeyTransSymbols()
+{
+ defModSyms();
+ defOprSyms();
+ defKeySyms();
+}
+
+// Global material -----------------------------------------------------------
+
+static int keytab_serial = 0; //FIXME: remove,localize
+
+static QIntDict<KeyTrans> * numb2keymap = 0L;
+
+KeyTrans* KeyTrans::find(int numb)
+{
+ KeyTrans* res = numb2keymap->find(numb);
+ return res ? res : numb2keymap->find(0);
+}
+
+KeyTrans* KeyTrans::find(const QString &id)
+{
+ QIntDictIterator<KeyTrans> it(*numb2keymap);
+ while(it.current())
+ {
+ if (it.current()->id() == id)
+ return it.current();
+ ++it;
+ }
+ return numb2keymap->find(0);
+}
+
+int KeyTrans::count()
+{
+ return numb2keymap->count();
+}
+
+void KeyTrans::addKeyTrans()
+{
+ m_numb = keytab_serial ++;
+ numb2keymap->insert(m_numb,this);
+}
+
+void KeyTrans::loadAll()
+{
+ if (!numb2keymap)
+ numb2keymap = new QIntDict<KeyTrans>;
+ else { // Needed for konsole_part.
+ numb2keymap->clear();
+ keytab_serial = 0;
+ }
+
+ if (!syms)
+ syms = new KeyTransSymbols;
+
+ //defaultKeyTrans()->addKeyTrans();
+ KeyTrans* sc = new KeyTrans("[buildin]");
+ sc->addKeyTrans();
+
+ QStringList lst = KGlobal::dirs()->findAllResources("data", "konsole/*.keytab");
+
+ for(QStringList::Iterator it = lst.begin(); it != lst.end(); ++it )
+ {
+ //QFile file(QFile::encodeName(*it));
+ sc = new KeyTrans(QFile::encodeName(*it));
+ //KeyTrans* sc = KeyTrans::fromDevice(QFile::encodeName(*it),file);
+ if (sc) sc->addKeyTrans();
+ }
+}
+
+// Debugging material -----------------------------------------------------------
+/*
+void TestTokenizer(QBuffer &buf)
+{
+ // opening sequence
+
+ buf.open(IO_ReadOnly);
+ cc = buf.getch();
+ lineno = 1;
+
+ // Test tokenizer
+
+ while (getSymbol(buf)) ReportToken();
+
+ buf.close();
+}
+
+void test()
+{
+ // Opening sequence
+
+ QCString txt =
+#include "default.keytab.h"
+ ;
+ QBuffer buf(txt);
+ if (0) TestTokenizer(buf);
+ if (1) { KeyTrans kt; kt.scanTable(buf); }
+}
+*/