diff options
Diffstat (limited to 'kxkb/extension.cpp')
-rw-r--r-- | kxkb/extension.cpp | 263 |
1 files changed, 32 insertions, 231 deletions
diff --git a/kxkb/extension.cpp b/kxkb/extension.cpp index 616167944..1b6895043 100644 --- a/kxkb/extension.cpp +++ b/kxkb/extension.cpp @@ -21,20 +21,11 @@ #include "extension.h" -TQMap<TQString, FILE*> XKBExtension::fileCache; //TODO: move to class? - - static TQString getLayoutKey(const TQString& layout, const TQString& variant) { return layout + "." + variant; } -TQString XKBExtension::getPrecompiledLayoutFilename(const TQString& layoutKey) -{ - TQString compiledLayoutFileName = m_tempDir + layoutKey + ".xkm"; - return compiledLayoutFileName; -} - XKBExtension::XKBExtension(Display *d) { if ( d == NULL ) @@ -76,16 +67,11 @@ bool XKBExtension::init() // Do it, or face horrible memory corrupting bugs ::XkbInitAtoms(NULL); - return true; -} + // watch group change events + XkbSelectEventDetails(m_dpy, XkbUseCoreKbd, XkbStateNotify, + XkbAllStateComponentsMask, XkbGroupStateMask); -void XKBExtension::reset() -{ - for(TQMap<TQString, FILE*>::ConstIterator it = fileCache.begin(); it != fileCache.end(); it++) { - fclose(*it); -// remove( TQFile::encodeName(getPrecompiledLayoutFileName(*it)) ); - } - fileCache.clear(); + return true; } XKBExtension::~XKBExtension() @@ -94,106 +80,38 @@ XKBExtension::~XKBExtension() deletePrecompiledLayouts();*/ } -bool XKBExtension::setXkbOptions(const TQString& options, bool resetOld) +bool XKBExtension::setXkbOptions(const XkbOptions options) { - if (options.isEmpty()) - return true; - - TQString exe = TDEGlobal::dirs()->findExe("setxkbmap"); - if (exe.isEmpty()) - return false; - - TDEProcess p; - p << exe; - if( resetOld ) - p << "-option"; - p << "-option" << options; - - p.start(TDEProcess::Block); + TQString exe = TDEGlobal::dirs()->findExe("setxkbmap"); + if (exe.isEmpty()) + return false; - return p.normalExit() && (p.exitStatus() == 0); -} + TDEProcess p; + p << exe; -bool XKBExtension::setLayout(const TQString& model, - const TQString& layout, const TQString& variant, - const TQString& includeGroup, bool useCompiledLayouts) -{ - if( useCompiledLayouts == false ) { - return setLayoutInternal( model, layout, variant, includeGroup ); - } + p << "-layout"; + p << options.layouts; - const TQString layoutKey = getLayoutKey(layout, variant); + p << "-variant"; + p << options.variants; - bool res; - if( fileCache.contains(layoutKey) ) { - res = setCompiledLayout( layoutKey ); - kdDebug() << "[kxkb-extension] setCompiledLayout " << layoutKey << ": " << res << endl; - - if( res ) - return res; + if (!options.model.isEmpty()) { + p << "-model"; + p << options.model; } -// else { - res = setLayoutInternal( model, layout, variant, includeGroup ); - kdDebug() << "[kxkb-extension] setRawLayout " << layoutKey << ": " << res << endl; - if( res ) - compileCurrentLayout( layoutKey ); - -// } - return res; -} -// private -bool XKBExtension::setLayoutInternal(const TQString& model, - const TQString& layout, const TQString& variant, - const TQString& includeGroup) -{ - if ( layout.isEmpty() ) - return false; - - TQString exe = TDEGlobal::dirs()->findExe("setxkbmap"); - if( exe.isEmpty() ) { - kdError() << "[kxkb-extension] Can't find setxkbmap" << endl; - return false; + if (options.resetOld) { + p << "-option"; + } + if (!options.options.isEmpty()) { + p << "-option" << options.options; } - TQString fullLayout = layout; - TQString fullVariant = variant; - if( includeGroup.isEmpty() == false ) { - fullLayout = includeGroup; - fullLayout += ","; - fullLayout += layout; - -// fullVariant = baseVar; - fullVariant = ","; - fullVariant += variant; - } - - TDEProcess p; - p << exe; -// p << "-rules" << rule; - if( model.isEmpty() == false ) - p << "-model" << model; - p << "-layout" << fullLayout; - if( !fullVariant.isNull() && !fullVariant.isEmpty() ) - p << "-variant" << fullVariant; - - p.start(TDEProcess::Block); - - // reload system-wide hotkey-setup keycode -> keysym maps - TQString modmapFileName = TDEGlobal::dirs()->findResource( "data", "kxkb/system.xmodmap" ); - if ( TQFile::exists( modmapFileName ) ) { - TDEProcess pXmodmap; - pXmodmap << "xmodmap" << modmapFileName; - pXmodmap.start(TDEProcess::Block); - } + kdDebug() << "[kxkb-extension] Command: " << p.args() << endl; - if ( TQFile::exists( TQDir::home().path() + "/.Xmodmap" ) ) { - TDEProcess pXmodmapHome; - pXmodmapHome << "xmodmap" << TQDir::home().path() + "/.Xmodmap"; - pXmodmapHome.start(TDEProcess::Block); - } + p.start(TDEProcess::Block); - return p.normalExit() && (p.exitStatus() == 0); + return p.normalExit() && (p.exitStatus() == 0); } bool XKBExtension::setGroup(unsigned int group) @@ -209,130 +127,13 @@ unsigned int XKBExtension::getGroup() const return xkbState.group; } -/** - * @brief Gets the current layout in its binary compiled form - * and write it to the file specified by 'fileName' - * @param[in] fileName file to store compiled layout to - * @return true if no problem, false otherwise - */ -bool XKBExtension::compileCurrentLayout(const TQString &layoutKey) -{ - XkbFileInfo result; - memset(&result, 0, sizeof(result)); - result.type = XkmKeymapFile; - XkbReadFromServer(m_dpy, XkbAllMapComponentsMask, XkbAllMapComponentsMask, &result); - - const TQString fileName = getPrecompiledLayoutFilename(layoutKey); - - kdDebug() << "[kxkb-extension] compiling layout " << this << " cache size: " << fileCache.count() << endl; - if( fileCache.contains(layoutKey) ) { - kdDebug() << "[kxkb-extension] trashing old compiled layout for " << fileName << endl; - if( fileCache[ layoutKey ] != NULL ) - fclose( fileCache[ layoutKey ] ); // recompiling - trash the old file - fileCache.remove(fileName); - } - - FILE *output = fopen(TQFile::encodeName(fileName), "w"); - - if ( output == NULL ) - { - kdWarning() << "[kxkb-extension] Could not open " << fileName << " to precompile: " << strerror(errno) << endl; - XkbFreeKeyboard(result.xkb, XkbAllControlsMask, True); - return false; +/** Examines an X Event passed to it and takes actions if the event is of + * interest to KXkb */ +void XKBExtension::processXEvent(XEvent *event) { + XkbEvent* xkb_event = (XkbEvent*)event; + if (xkb_event->any.xkb_type == XkbStateNotify) { + emit groupChanged(xkb_event->state.group); } - - if( !XkbWriteXKMFile(output, &result) ) { - kdWarning() << "[kxkb-extension] Could not write compiled layout to " << fileName << endl; - fclose(output); - return false; - } - - fclose(output); // TODO: can we change mode w/out reopening? - FILE *input = fopen(TQFile::encodeName(fileName), "r"); - fileCache[ layoutKey ] = input; - - XkbFreeKeyboard(result.xkb, XkbAllControlsMask, True); - return true; } -/** - * @brief takes layout from its compiled binary snapshot in file - * and sets it as current - * TODO: cache layout in memory rather than in file - */ -bool XKBExtension::setCompiledLayout(const TQString &layoutKey) -{ - FILE *input = NULL; - - if( fileCache.contains(layoutKey) ) { - input = fileCache[ layoutKey ]; - } - - if( input == NULL ) { - kdWarning() << "[kxkb-extension] setCompiledLayout trying to reopen xkb file" << endl; // should never happen - const TQString fileName = getPrecompiledLayoutFilename(layoutKey); - input = fopen(TQFile::encodeName(fileName), "r"); - - // FILE *input = fopen(TQFile::encodeName(fileName), "r"); - if ( input == NULL ) { - kdDebug() << "[kxkb-extension] Unable to open " << fileName << ": " << strerror(errno) << endl; - fileCache.remove(layoutKey); - return false; - } - } - else { - rewind(input); - } - - XkbFileInfo result; - memset(&result, 0, sizeof(result)); - if ((result.xkb = XkbAllocKeyboard())==NULL) { - kdWarning() << "[kxkb-extension] Unable to allocate memory for keyboard description" << endl; -// fclose(input); -// fileCache.remove(layoutKey); - return false; - } - - unsigned retVal = XkmReadFile(input, 0, XkmKeymapLegal, &result); - if (retVal == XkmKeymapLegal) - { - // this means reading the Xkm didn't manage to read any section - kdWarning() << "[kxkb-extension] Unable to load map from file" << endl; - XkbFreeKeyboard(result.xkb, XkbAllControlsMask, True); - fclose(input); - fileCache.remove(layoutKey); - return false; - } - - // fclose(input); // don't close - goes in cache - - if (XkbChangeKbdDisplay(m_dpy, &result) == Success) - { - if (!XkbWriteToServer(&result)) - { - kdWarning() << "[kxkb-extension] Unable to write the keyboard layout to X display" << endl; - XkbFreeKeyboard(result.xkb, XkbAllControlsMask, True); - return false; - } - } - else - { - kdWarning() << "[kxkb-extension] Unable prepare the keyboard layout for X display" << endl; - } - - XkbFreeKeyboard(result.xkb, XkbAllControlsMask, True); - return true; -} - - -// Deletes the precompiled layouts stored in temporary files -// void XKBExtension::deletePrecompiledLayouts() -// { -// TQMapConstIterator<LayoutUnit, TQString> it, end; -// end = m_compiledLayoutFileNames.end(); -// for (it = m_compiledLayoutFileNames.begin(); it != end; ++it) -// { -// unlink(TQFile::encodeName(it.data())); -// } -// m_compiledLayoutFileNames.clear(); -// } +#include "extension.moc"
\ No newline at end of file |