00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "keyboard.h"
00022
00023 namespace SaX {
00024
00025
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
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
00092
00093
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
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
00164
00165 QDict<QString> SaXKeyRules::getModels (void) {
00166 return mModels;
00167 }
00168
00169
00170
00171
00172 QDict<QString> SaXKeyRules::getLayouts (void) {
00173 return mLayouts;
00174 }
00175
00176
00177
00178
00179 QDict<QString> SaXKeyRules::getOptions (void) {
00180 return mOptions;
00181 }
00182
00183
00184
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
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
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
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
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
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
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
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
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
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
00387
00388 void SaXManipulateKeyboard::removeXKBVariant ( const QString& layout ) {
00389
00392
00393 setXKBVariant (layout,"");
00394 }
00395
00396
00397
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
00439
00440 QString SaXManipulateKeyboard::getDriver (void) {
00441
00443
00444 if (! mImport) {
00445 return QString();
00446 }
00447 return mImport -> getItem ("Driver");
00448 }
00449
00450
00451
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
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
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
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
00527
00528 QString SaXManipulateKeyboard::getXKBModel (void) {
00529
00532
00533 if (! mImport) {
00534 return QString();
00535 }
00536 return mImport -> getItem ("XkbModel");
00537 }
00538
00539
00540
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
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 }