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