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/X11R6/lib/X11/";
00034         loadRules (mX11Dir + QString("xkb/rules/%1").arg(rule));
00035 }
00036 
00037 //====================================
00038 // loadRules
00039 //------------------------------------
00040 void SaXKeyRules::loadRules(QString file) {
00041         // .../
00044         // ----
00045         static struct {
00046                 const char * locale;
00047                 const char * layout;
00048         } fixedLayouts[] = {
00049                 { "ben", "Bengali" },
00050                 { "ar" , "Arabic"  },
00051                 { "ir" , "Farsi"   },
00052                 { 0    , 0 }
00053         };
00054         char* locale = setlocale (LC_ALL,NULL);
00055         XkbRF_RulesPtr rules = XkbRF_Load (
00056                 QFile::encodeName(file).data(),
00057                 locale, true, true
00058         );
00059         if (! rules) {
00060                 excXKBLoadRulesFailed();
00061                 qError (errorString(),EXC_XKBLOADRULESFAILED);
00062                 return;
00063         }
00064         int i;
00065         for (i = 0; i < rules->models.num_desc; ++i) {
00066                 mModels.replace (
00067                         rules->models.desc[i].name,
00068                         new QString (qstrdup( rules->models.desc[i].desc))
00069                 );
00070         }
00071         for (i = 0; i < rules->layouts.num_desc; ++i) {
00072                 mLayouts.replace (
00073                         rules->layouts.desc[i].name,
00074                         new QString (qstrdup( rules->layouts.desc[i].desc))
00075                 );
00076         }
00077         for (i = 0; i < rules->options.num_desc; ++i) {
00078                 mOptions.replace (
00079                         rules->options.desc[i].name,
00080                         new QString (qstrdup( rules->options.desc[i].desc))
00081                 );
00082         }
00083         XkbRF_Free(rules, true);
00084         // ...
00085         // Knowing which variants we have won't help us
00086         // We want to know which particular variants are available for
00087         // each language
00088         // ---
00089         for(int i=0; fixedLayouts[i].layout != 0; i++ ) {
00090                 mLayouts.replace (
00091                         fixedLayouts[i].locale, new QString (fixedLayouts[i].layout)
00092                 );
00093         }
00094 }
00095 
00096 //====================================
00097 // getVariants
00098 //------------------------------------
00099 QList<QString> SaXKeyRules::getVariants (const QString& layout) {
00100         // .../
00103         // ----
00104         if ( layout.isEmpty() || ! getLayouts().find(layout) ) {
00105                 return QList<QString>();
00106         }
00107         QList<QString> result1;
00108         QStringList* r1 = mVarLists[layout];
00109         if ( r1 ) {
00110                 for ( QStringList::Iterator it=r1->begin(); it != r1->end(); ++it ) {
00111                         QString* item = new QString (*it);
00112                         result1.append (item);
00113                 }
00114                 return result1;
00115         }
00116         QList<QString> result2;
00117         QStringList* result = new QStringList();
00118         QString file = mX11Dir + "xkb/symbols/" + layout;
00119         QFile f(file);
00120         if (f.open(IO_ReadOnly)) {
00121                 QTextStream ts(&f);
00122                 QString line;
00123                 QString prev_line;
00124                 while (!ts.eof()) {
00125                         prev_line = line;
00126                         line = ts.readLine().simplifyWhiteSpace();
00127                         if (line[0] == '#' || line.left(2) == "//" || line.isEmpty()) {
00128                                 continue;
00129                         }
00130                         int pos = line.find("xkb_symbols");
00131                         if (pos < 0) {
00132                                 continue;
00133                         }
00134                         if ( prev_line.find("hidden") >=0 ) {
00135                                 continue;
00136                         }
00137                         pos = line.find('"', pos) + 1;
00138                         int pos2 = line.find('"', pos);
00139                         if ( pos < 0 || pos2 < 0 ) {
00140                                 continue;
00141                         }
00142                         result->append (
00143                                 line.mid(pos, pos2-pos)
00144                         );
00145                 }
00146                 f.close();
00147         }
00148         mVarLists.insert(layout, result);
00149         for ( QStringList::Iterator it=result->begin(); it != result->end();++it) {
00150                 QString* item = new QString (*it);
00151                 result2.append (item);
00152         }
00153         return result2;
00154 }
00155 
00156 //====================================
00157 // getModels
00158 //------------------------------------
00159 QDict<QString> SaXKeyRules::getModels  (void) {
00160         return mModels;
00161 }
00162 
00163 //====================================
00164 // getLayouts
00165 //------------------------------------
00166 QDict<QString> SaXKeyRules::getLayouts (void) {
00167         return mLayouts;
00168 }
00169 
00170 //====================================
00171 // getOptions
00172 //------------------------------------
00173 QDict<QString> SaXKeyRules::getOptions (void) {
00174         return mOptions;
00175 }
00176 
00177 //====================================
00178 // Constructor...
00179 //------------------------------------
00180 SaXManipulateKeyboard::SaXManipulateKeyboard (
00181         SaXImport* in, int kbd
00182 ) : SaXManipulateKeyboardIF () {
00183         // .../
00188         // ----
00189         if ( ! in ) {
00190                 excNullPointerArgument ();
00191                 qError (errorString(),EXC_NULLPOINTERARGUMENT);
00192                 return;
00193         }
00194         if ( in->getSectionID() != SAX_KEYBOARD ) {
00195                 excKeyboardImportBindFailed ( in->getSectionID() );
00196                 qError (errorString(),EXC_KEYBOARDIMPORTBINDFAILED);
00197                 return;
00198         }
00199         mImport = in;
00200         mKeyboard = kbd;
00201         mImport -> setID ( mKeyboard );
00202 }
00203 
00204 //====================================
00205 // set keyboard ID
00206 //------------------------------------
00207 bool SaXManipulateKeyboard::selectKeyboard (int ptr) {
00208         // .../
00211         // ----
00212         if (! mImport) {
00213                 return false;
00214         }
00215         if (mImport -> setID ( ptr )) {
00216                 mKeyboard = ptr;
00217                 return true;
00218         }
00219         return false;
00220 }
00221 
00222 //====================================
00223 // setXKBModel
00224 //------------------------------------
00225 void SaXManipulateKeyboard::setXKBModel (const QString& model) {
00226         // .../
00229         // ----
00230         if (! mImport) {
00231                 return;
00232         }
00233         mImport -> setItem ( "XkbModel",model );
00234 }
00235 
00236 //====================================
00237 // setXKBLayout
00238 //------------------------------------
00239 void SaXManipulateKeyboard::setXKBLayout (const QString& layout) {
00240         // .../
00243         // ----
00244         if (! mImport) {
00245                 return;
00246         }
00247         mImport -> setItem ( "XkbLayout",layout );
00248 }
00249 
00250 //====================================
00251 // addXKBLayout
00252 //------------------------------------
00253 void SaXManipulateKeyboard::addXKBLayout (const QString& layout) {
00254         // .../
00258         // ----
00259         if (! mImport) {
00260                 return;
00261         }
00262         QString val;
00263         QString key ("XkbLayout");
00264         if (! mImport -> getItem (key).isEmpty()) {
00265                 val = mImport -> getItem (key);
00266         }
00267         QTextOStream (&val) << val << "," << layout;
00268         mImport -> setItem ( key,val );
00269 }
00270 
00271 //====================================
00272 // removeXKBLayout
00273 //------------------------------------
00274 void SaXManipulateKeyboard::removeXKBLayout (const QString& layout) {
00275         // .../
00278         // ----
00279         if (! mImport) {
00280                 return;
00281         }
00282         QString val (layout);
00283         QString key ("XkbLayout");
00284         if (! mImport -> getItem (key).isEmpty()) {
00285                 mImport -> removeItem (key,val);
00286         }
00287 }
00288 
00289 //====================================
00290 // setXKBOption
00291 //------------------------------------
00292 void SaXManipulateKeyboard::setXKBOption (const QString& option) {
00293         // .../
00296         // ----
00297         if (! mImport) {
00298                 return;
00299         }
00300         mImport -> setItem ( "XkbOptions",option );
00301 }
00302 
00303 //====================================
00304 // addXKBOption
00305 //------------------------------------
00306 void SaXManipulateKeyboard::addXKBOption (const QString& option) {
00307         // .../
00310         // ----
00311         if (! mImport) {
00312                 return;
00313         }
00314         QString val;
00315         QString key ("XkbOptions");
00316         if (! mImport -> getItem (key).isEmpty()) {
00317                 val = mImport -> getItem (key);
00318         }
00319         QTextOStream (&val) << val << "," << option;
00320         mImport -> setItem ( key,val );
00321 }
00322 
00323 //====================================
00324 // removeXKBOption
00325 //------------------------------------
00326 void SaXManipulateKeyboard::removeXKBOption (const QString& option) {
00327         // .../
00330         // ----
00331         if (! mImport) {
00332                 return;
00333         }
00334         QString val (option);
00335         QString key ("XkbOptions");
00336         if (! mImport -> getItem (key).isEmpty()) {
00337                 mImport -> removeItem (key,val);
00338         }
00339 }
00340 
00341 //====================================
00342 // setXKBVariant
00343 //------------------------------------
00344 void SaXManipulateKeyboard::setXKBVariant (
00345         const QString& layout, const QString& variant
00346 ) {
00347         // .../
00350         // ----
00351         if (! mImport) {
00352                 return;
00353         }
00354         int layoutCount = findLayout (layout);
00355         if (layoutCount < 0) {
00356                 excXKBLayoutUndefined (layout);
00357                 qError (errorString(),EXC_XKBLAYOUTUNDEFINED);
00358                 return;
00359         }
00360         QList<QString> vList = getXKBVariantList();
00361         QList<QString> lList = getXKBLayout();
00362         int varCount = 0;
00363         QStringList result;
00364         QListIterator<QString> it (lList);
00365         for (; it.current();++it) {
00366                 QString item;
00367                 if (vList.at(varCount)) {
00368                         item = *vList.at (varCount);
00369                 }
00370                 if (varCount == layoutCount) {
00371                         item = variant;
00372                 }
00373                 result += item;
00374                 varCount++;
00375         }
00376         mImport -> setItem ("XkbVariant",result.join(","));
00377 }
00378 
00379 //====================================
00380 // removeXKBVariant
00381 //------------------------------------
00382 void SaXManipulateKeyboard::removeXKBVariant ( const QString& layout ) {
00383         // .../
00386         // ----
00387         setXKBVariant (layout,"");
00388 }
00389 
00390 //====================================
00391 // setMapping
00392 //------------------------------------
00393 void SaXManipulateKeyboard::setMapping (
00394         const QString& type,const QString& mapping
00395 ) {
00396         // .../
00400         // ----
00401         if (! mImport) {
00402                 return;
00403         }
00404         QString key (type);
00405         QString map (mapping);
00406         if (
00407                 (key != XKB_LEFT_ALT)       &&
00408                 (key != XKB_RIGHT_ALT)      &&
00409                 (key != XKB_SCROLL_LOCK)    &&
00410                 (key != XKB_RIGHT_CTL)
00411         ) {
00412                 excInvalidArgument (type);
00413                 qError (errorString(),EXC_INVALIDARGUMENT);
00414                 return;
00415         }
00416         if (
00417                 (map != XKB_MAP_META)       &&
00418                 (map != XKB_MAP_COMPOSE)    &&
00419                 (map != XKB_MAP_MODESHIFT)  &&
00420                 (map != XKB_MAP_MODELOCK)   &&
00421                 (map != XKB_MAP_SCROLLLOCK) &&
00422                 (map != XKB_MAP_CONTROL)
00423         ) {
00424                 excInvalidArgument (mapping);
00425                 qError (errorString(),EXC_INVALIDARGUMENT);
00426                 return;
00427         }
00428         mImport -> setItem ( type,mapping );
00429 }
00430 
00431 //====================================
00432 // getDriver
00433 //------------------------------------
00434 QString SaXManipulateKeyboard::getDriver (void) {
00435         // .../
00437         // ----
00438         if (! mImport) {
00439                 return QString();
00440         }
00441         return mImport -> getItem ("Driver");
00442 }
00443 
00444 //====================================
00445 // getXKBOptionList
00446 //------------------------------------
00447 QList<QString> SaXManipulateKeyboard::getXKBOptionList (void) {
00448         // .../
00450         // ----
00451         if (! mImport) {
00452                 return QList<QString>();
00453         }
00454         QString options = mImport -> getItem ("XkbOptions");
00455         return createList (options);
00456 }
00457 
00458 //====================================
00459 // getXKBLayout
00460 //------------------------------------
00461 QList<QString> SaXManipulateKeyboard::getXKBLayout (void) {
00462         // .../
00465         // ----
00466         if (! mImport) {
00467                 return QList<QString>();
00468         }
00469         QString layouts = mImport -> getItem ("XkbLayout");
00470         return createList (layouts);
00471 }
00472 
00473 //====================================
00474 // getXKBVariantList
00475 //------------------------------------
00476 QList<QString> SaXManipulateKeyboard::getXKBVariantList (void) {
00477         // .../
00480         // ----
00481         if (! mImport) {
00482                 return QList<QString>();
00483         }
00484         QString variants = mImport -> getItem ("XkbVariant");
00485         return createList (variants);
00486 }
00487 
00488 //====================================
00489 // getXKBVariant for layout X
00490 //------------------------------------
00491 QString SaXManipulateKeyboard::getXKBVariant ( const QString& layout ) {
00492         // .../
00497         // ----
00498         if (! mImport) {
00499                 return QString();
00500         }
00501         int layoutCount = findLayout (layout);
00502         if (layoutCount < 0) {
00503                 excXKBLayoutUndefined (layout);
00504                 qError (errorString(),EXC_XKBLAYOUTUNDEFINED);
00505                 return QString();
00506         }
00507         int varCount = 0;
00508         QList<QString> vList = getXKBVariantList();
00509         QListIterator<QString> it (vList);
00510         for (; it.current();++it) {
00511                 if (varCount == layoutCount) {
00512                         return *it.current();
00513                 }
00514                 varCount++;
00515         }
00516         return QString();
00517 }
00518 
00519 //====================================
00520 // getXKBModel
00521 //------------------------------------
00522 QString SaXManipulateKeyboard::getXKBModel (void) {
00523         // .../
00526         // ----
00527         if (! mImport) {
00528                 return QString();
00529         }
00530         return mImport -> getItem ("XkbModel");
00531 }
00532 
00533 //====================================
00534 // findLayout
00535 //------------------------------------
00536 int SaXManipulateKeyboard::findLayout (const QString& layout) {
00537         // .../
00541         // ----
00542         int count  = 0;
00543         bool found = false;
00544         QString layoutData = mImport -> getItem ("XkbLayout");
00545         QStringList layouts = QStringList::split ( ",", layoutData );
00546         for (QStringList::Iterator it=layouts.begin(); it!=layouts.end();++ it) {
00547                 QString item (*it);
00548                 if (item == layout) {
00549                         found = true; break;
00550                 }
00551                 count++;
00552         }
00553         if (! found) {
00554                 return -1;
00555         }
00556         return count;
00557 }
00558 
00559 //====================================
00560 // transform string to Qlist
00561 //------------------------------------
00562 QList<QString> SaXManipulateKeyboard::createList ( const QString& data) {
00563         // .../
00566         // ----
00567         if (data.isEmpty()) {
00568                 return QList<QString>();
00569         }
00570         QList<QString> result; 
00571         QStringList dataList = QStringList::split ( ",", data, true );
00572         for (QStringList::Iterator it=dataList.begin(); it!=dataList.end();++ it) {
00573                 QString* item = new QString (*it);
00574                 result.append (item);
00575         }
00576         return result;
00577 }
00578 } // end namespace

Generated on Mon Jun 19 12:42:49 2006 for libsax by  doxygen 1.4.6