keyboard.cpp

00001 /**************
00002 FILE          : keyboard.cpp
00003 ***************
00004 PROJECT       : SaX2 - library interface
00005               :
00006 AUTHOR        : Marcus Schäfer <ms@suse.de>
00007               :
00008 BELONGS TO    : SaX2 - SuSE advanced X11 configuration 
00009               : 
00010               :
00011 DESCRIPTION   : native C++ class library to access SaX2
00012               : functionality. Easy to use interface for
00013               : //.../
00014               : - importing/exporting X11 configurations
00015               : - modifying/creating X11 configurations 
00016               : ---
00017               :
00018               :
00019 STATUS        : Status: Development
00020 **************/
00021 #include "keyboard.h"
00022 
00023 namespace SaX {
00024 //====================================
00025 // Constructor
00026 //------------------------------------
00027 SaXKeyRules::SaXKeyRules (QString rule): mLayouts(80) {
00028         // .../
00032         // ----
00033         mX11Dir = "/usr/lib/X11/";
00034         if (! access ("/usr/share/X11/xkb",R_OK|X_OK)) {
00035                 mX11Dir = "/usr/share/X11/";
00036         }
00037         loadRules (mX11Dir + QString("xkb/rules/%1").arg(rule));
00038 }
00039 
00040 //====================================
00041 // loadRules
00042 //------------------------------------
00043 void SaXKeyRules::loadRules(QString file) {
00044         // .../
00047         // ----
00048         static struct {
00049                 const char * locale;
00050                 const char * layout;
00051         } fixedLayouts[] = {
00052                 { "ben", "Bengali" },
00053                 { "ar" , "Arabic"  },
00054                 { "ir" , "Farsi"   },
00055                 { 0    , 0 }
00056         };
00057         char* locale = setlocale (LC_ALL,NULL);
00058         XkbRF_RulesPtr rules = XkbRF_Load (
00059                 QFile::encodeName(file).data(),
00060                 locale, true, true
00061         );
00062         if (! rules) {
00063                 excXKBLoadRulesFailed();
00064                 qError (errorString(),EXC_XKBLOADRULESFAILED);
00065                 return;
00066         }
00067         int i;
00068         for (i = 0; i < rules->models.num_desc; ++i) {
00069                 QString* item = new QString (qstrdup( rules->models.desc[i].desc));
00070                 if ( item->length() > 50 ) {
00071                         item->truncate ( 50 ); item->append ("...");
00072                 }
00073                 mModels.replace (
00074                         rules->models.desc[i].name,item
00075                 );
00076         }
00077         for (i = 0; i < rules->layouts.num_desc; ++i) {
00078                 mLayouts.replace (
00079                         rules->layouts.desc[i].name,
00080                         new QString (qstrdup( rules->layouts.desc[i].desc))
00081                 );
00082         }
00083         for (i = 0; i < rules->options.num_desc; ++i) {
00084                 mOptions.replace (
00085                         rules->options.desc[i].name,
00086                         new QString (qstrdup( rules->options.desc[i].desc))
00087                 );
00088         }
00089         XkbRF_Free(rules, true);
00090         // ...
00091         // Knowing which variants we have won't help us
00092         // We want to know which particular variants are available for
00093         // each language
00094         // ---
00095         for(int i=0; fixedLayouts[i].layout != 0; i++ ) {
00096                 mLayouts.replace (
00097                         fixedLayouts[i].locale, new QString (fixedLayouts[i].layout)
00098                 );
00099         }
00100 }
00101 
00102 //====================================
00103 // getVariants
00104 //------------------------------------
00105 QList<QString> SaXKeyRules::getVariants (const QString& layout) {
00106         // .../
00109         // ----
00110         if ( layout.isEmpty() || ! getLayouts().find(layout) ) {
00111                 return QList<QString>();
00112         }
00113         QList<QString> result1;
00114         QStringList* r1 = mVarLists[layout];
00115         if ( r1 ) {
00116                 for ( QStringList::Iterator it=r1->begin(); it != r1->end(); ++it ) {
00117                         QString* item = new QString (*it);
00118                         result1.append (item);
00119                 }
00120                 return result1;
00121         }
00122         QList<QString> result2;
00123         QStringList* result = new QStringList();
00124         QString file = mX11Dir + "xkb/symbols/" + layout;
00125         QFile f(file);
00126         if (f.open(IO_ReadOnly)) {
00127                 QTextStream ts(&f);
00128                 QString line;
00129                 QString prev_line;
00130                 while (!ts.eof()) {
00131                         prev_line = line;
00132                         line = ts.readLine().simplifyWhiteSpace();
00133                         if (line[0] == '#' || line.left(2) == "//" || line.isEmpty()) {
00134                                 continue;
00135                         }
00136                         int pos = line.find("xkb_symbols");
00137                         if (pos < 0) {
00138                                 continue;
00139                         }
00140                         if ( prev_line.find("hidden") >=0 ) {
00141                                 continue;
00142                         }
00143                         pos = line.find('"', pos) + 1;
00144                         int pos2 = line.find('"', pos);
00145                         if ( pos < 0 || pos2 < 0 ) {
00146                                 continue;
00147                         }
00148                         result->append (
00149                                 line.mid(pos, pos2-pos)
00150                         );
00151                 }
00152                 f.close();
00153         }
00154         mVarLists.insert(layout, result);
00155         for ( QStringList::Iterator it=result->begin(); it != result->end();++it) {
00156                 QString* item = new QString (*it);
00157                 result2.append (item);
00158         }
00159         return result2;
00160 }
00161 
00162 //====================================
00163 // getModels
00164 //------------------------------------
00165 QDict<QString> SaXKeyRules::getModels  (void) {
00166         return mModels;
00167 }
00168 
00169 //====================================
00170 // getLayouts
00171 //------------------------------------
00172 QDict<QString> SaXKeyRules::getLayouts (void) {
00173         return mLayouts;
00174 }
00175 
00176 //====================================
00177 // getOptions
00178 //------------------------------------
00179 QDict<QString> SaXKeyRules::getOptions (void) {
00180         return mOptions;
00181 }
00182 
00183 //====================================
00184 // Constructor...
00185 //------------------------------------
00186 SaXManipulateKeyboard::SaXManipulateKeyboard (
00187         SaXImport* in, int kbd
00188 ) : SaXManipulateKeyboardIF () {
00189         // .../
00194         // ----
00195         if ( ! in ) {
00196                 excNullPointerArgument ();
00197                 qError (errorString(),EXC_NULLPOINTERARGUMENT);
00198                 return;
00199         }
00200         if ( in->getSectionID() != SAX_KEYBOARD ) {
00201                 excKeyboardImportBindFailed ( in->getSectionID() );
00202                 qError (errorString(),EXC_KEYBOARDIMPORTBINDFAILED);
00203                 return;
00204         }
00205         mImport = in;
00206         mKeyboard = kbd;
00207         mImport -> setID ( mKeyboard );
00208 }
00209 
00210 //====================================
00211 // set keyboard ID
00212 //------------------------------------
00213 bool SaXManipulateKeyboard::selectKeyboard (int ptr) {
00214         // .../
00217         // ----
00218         if (! mImport) {
00219                 return false;
00220         }
00221         if (mImport -> setID ( ptr )) {
00222                 mKeyboard = ptr;
00223                 return true;
00224         }
00225         return false;
00226 }
00227 
00228 //====================================
00229 // setXKBModel
00230 //------------------------------------
00231 void SaXManipulateKeyboard::setXKBModel (const QString& model) {
00232         // .../
00235         // ----
00236         if (! mImport) {
00237                 return;
00238         }
00239         mImport -> setItem ( "XkbModel",model );
00240 }
00241 
00242 //====================================
00243 // setXKBLayout
00244 //------------------------------------
00245 void SaXManipulateKeyboard::setXKBLayout (const QString& layout) {
00246         // .../
00249         // ----
00250         if (! mImport) {
00251                 return;
00252         }
00253         mImport -> setItem ( "XkbLayout",layout );
00254 }
00255 
00256 //====================================
00257 // addXKBLayout
00258 //------------------------------------
00259 void SaXManipulateKeyboard::addXKBLayout (const QString& layout) {
00260         // .../
00264         // ----
00265         if (! mImport) {
00266                 return;
00267         }
00268         QString val;
00269         QString key ("XkbLayout");
00270         if (! mImport -> getItem (key).isEmpty()) {
00271                 val = mImport -> getItem (key);
00272         }
00273         QTextOStream (&val) << val << "," << layout;
00274         mImport -> setItem ( key,val );
00275 }
00276 
00277 //====================================
00278 // removeXKBLayout
00279 //------------------------------------
00280 void SaXManipulateKeyboard::removeXKBLayout (const QString& layout) {
00281         // .../
00284         // ----
00285         if (! mImport) {
00286                 return;
00287         }
00288         QString val (layout);
00289         QString key ("XkbLayout");
00290         if (! mImport -> getItem (key).isEmpty()) {
00291                 mImport -> removeItem (key,val);
00292         }
00293 }
00294 
00295 //====================================
00296 // setXKBOption
00297 //------------------------------------
00298 void SaXManipulateKeyboard::setXKBOption (const QString& option) {
00299         // .../
00302         // ----
00303         if (! mImport) {
00304                 return;
00305         }
00306         mImport -> setItem ( "XkbOptions",option );
00307 }
00308 
00309 //====================================
00310 // addXKBOption
00311 //------------------------------------
00312 void SaXManipulateKeyboard::addXKBOption (const QString& option) {
00313         // .../
00316         // ----
00317         if (! mImport) {
00318                 return;
00319         }
00320         QString val;
00321         QString key ("XkbOptions");
00322         if (! mImport -> getItem (key).isEmpty()) {
00323                 val = mImport -> getItem (key);
00324         }
00325         QTextOStream (&val) << val << "," << option;
00326         mImport -> setItem ( key,val );
00327 }
00328 
00329 //====================================
00330 // removeXKBOption
00331 //------------------------------------
00332 void SaXManipulateKeyboard::removeXKBOption (const QString& option) {
00333         // .../
00336         // ----
00337         if (! mImport) {
00338                 return;
00339         }
00340         QString val (option);
00341         QString key ("XkbOptions");
00342         if (! mImport -> getItem (key).isEmpty()) {
00343                 mImport -> removeItem (key,val);
00344         }
00345 }
00346 
00347 //====================================
00348 // setXKBVariant
00349 //------------------------------------
00350 void SaXManipulateKeyboard::setXKBVariant (
00351         const QString& layout, const QString& variant
00352 ) {
00353         // .../
00356         // ----
00357         if (! mImport) {
00358                 return;
00359         }
00360         int layoutCount = findLayout (layout);
00361         if (layoutCount < 0) {
00362                 excXKBLayoutUndefined (layout);
00363                 qError (errorString(),EXC_XKBLAYOUTUNDEFINED);
00364                 return;
00365         }
00366         QList<QString> vList = getXKBVariantList();
00367         QList<QString> lList = getXKBLayout();
00368         int varCount = 0;
00369         QStringList result;
00370         QListIterator<QString> it (lList);
00371         for (; it.current();++it) {
00372                 QString item;
00373                 if (vList.at(varCount)) {
00374                         item = *vList.at (varCount);
00375                 }
00376                 if (varCount == layoutCount) {
00377                         item = variant;
00378                 }
00379                 result += item;
00380                 varCount++;
00381         }
00382         mImport -> setItem ("XkbVariant",result.join(","));
00383 }
00384 
00385 //====================================
00386 // removeXKBVariant
00387 //------------------------------------
00388 void SaXManipulateKeyboard::removeXKBVariant ( const QString& layout ) {
00389         // .../
00392         // ----
00393         setXKBVariant (layout,"");
00394 }
00395 
00396 //====================================
00397 // setMapping
00398 //------------------------------------
00399 void SaXManipulateKeyboard::setMapping (
00400         const QString& type,const QString& mapping
00401 ) {
00402         // .../
00406         // ----
00407         if (! mImport) {
00408                 return;
00409         }
00410         QString key (type);
00411         QString map (mapping);
00412         if (
00413                 (key != XKB_LEFT_ALT)       &&
00414                 (key != XKB_RIGHT_ALT)      &&
00415                 (key != XKB_SCROLL_LOCK)    &&
00416                 (key != XKB_RIGHT_CTL)
00417         ) {
00418                 excInvalidArgument (type);
00419                 qError (errorString(),EXC_INVALIDARGUMENT);
00420                 return;
00421         }
00422         if (
00423                 (map != XKB_MAP_META)       &&
00424                 (map != XKB_MAP_COMPOSE)    &&
00425                 (map != XKB_MAP_MODESHIFT)  &&
00426                 (map != XKB_MAP_MODELOCK)   &&
00427                 (map != XKB_MAP_SCROLLLOCK) &&
00428                 (map != XKB_MAP_CONTROL)
00429         ) {
00430                 excInvalidArgument (mapping);
00431                 qError (errorString(),EXC_INVALIDARGUMENT);
00432                 return;
00433         }
00434         mImport -> setItem ( type,mapping );
00435 }
00436 
00437 //====================================
00438 // getDriver
00439 //------------------------------------
00440 QString SaXManipulateKeyboard::getDriver (void) {
00441         // .../
00443         // ----
00444         if (! mImport) {
00445                 return QString();
00446         }
00447         return mImport -> getItem ("Driver");
00448 }
00449 
00450 //====================================
00451 // getXKBOptionList
00452 //------------------------------------
00453 QList<QString> SaXManipulateKeyboard::getXKBOptionList (void) {
00454         // .../
00456         // ----
00457         if (! mImport) {
00458                 return QList<QString>();
00459         }
00460         QString options = mImport -> getItem ("XkbOptions");
00461         return createList (options);
00462 }
00463 
00464 //====================================
00465 // getXKBLayout
00466 //------------------------------------
00467 QList<QString> SaXManipulateKeyboard::getXKBLayout (void) {
00468         // .../
00471         // ----
00472         if (! mImport) {
00473                 return QList<QString>();
00474         }
00475         QString layouts = mImport -> getItem ("XkbLayout");
00476         return createList (layouts);
00477 }
00478 
00479 //====================================
00480 // getXKBVariantList
00481 //------------------------------------
00482 QList<QString> SaXManipulateKeyboard::getXKBVariantList (void) {
00483         // .../
00486         // ----
00487         if (! mImport) {
00488                 return QList<QString>();
00489         }
00490         QString variants = mImport -> getItem ("XkbVariant");
00491         return createList (variants);
00492 }
00493 
00494 //====================================
00495 // getXKBVariant for layout X
00496 //------------------------------------
00497 QString SaXManipulateKeyboard::getXKBVariant ( const QString& layout ) {
00498         // .../
00503         // ----
00504         if (! mImport) {
00505                 return QString();
00506         }
00507         int layoutCount = findLayout (layout);
00508         if (layoutCount < 0) {
00509                 excXKBLayoutUndefined (layout);
00510                 qError (errorString(),EXC_XKBLAYOUTUNDEFINED);
00511                 return QString();
00512         }
00513         int varCount = 0;
00514         QList<QString> vList = getXKBVariantList();
00515         QListIterator<QString> it (vList);
00516         for (; it.current();++it) {
00517                 if (varCount == layoutCount) {
00518                         return *it.current();
00519                 }
00520                 varCount++;
00521         }
00522         return QString();
00523 }
00524 
00525 //====================================
00526 // getXKBModel
00527 //------------------------------------
00528 QString SaXManipulateKeyboard::getXKBModel (void) {
00529         // .../
00532         // ----
00533         if (! mImport) {
00534                 return QString();
00535         }
00536         return mImport -> getItem ("XkbModel");
00537 }
00538 
00539 //====================================
00540 // findLayout
00541 //------------------------------------
00542 int SaXManipulateKeyboard::findLayout (const QString& layout) {
00543         // .../
00547         // ----
00548         int count  = 0;
00549         bool found = false;
00550         QString layoutData = mImport -> getItem ("XkbLayout");
00551         QStringList layouts = QStringList::split ( ",", layoutData );
00552         for (QStringList::Iterator it=layouts.begin(); it!=layouts.end();++ it) {
00553                 QString item (*it);
00554                 if (item == layout) {
00555                         found = true; break;
00556                 }
00557                 count++;
00558         }
00559         if (! found) {
00560                 return -1;
00561         }
00562         return count;
00563 }
00564 
00565 //====================================
00566 // transform string to Qlist
00567 //------------------------------------
00568 QList<QString> SaXManipulateKeyboard::createList ( const QString& data) {
00569         // .../
00572         // ----
00573         if (data.isEmpty()) {
00574                 return QList<QString>();
00575         }
00576         QList<QString> result; 
00577         QStringList dataList = QStringList::split ( ",", data, true );
00578         for (QStringList::Iterator it=dataList.begin(); it!=dataList.end();++ it) {
00579                 QString* item = new QString (*it);
00580                 result.append (item);
00581         }
00582         return result;
00583 }
00584 } // end namespace

Generated on Tue Sep 25 20:18:16 2007 for libsax by  doxygen 1.5.3