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 mModels.replace (
00070 rules->models.desc[i].name,
00071 new QString (qstrdup( rules->models.desc[i].desc))
00072 );
00073 }
00074 for (i = 0; i < rules->layouts.num_desc; ++i) {
00075 mLayouts.replace (
00076 rules->layouts.desc[i].name,
00077 new QString (qstrdup( rules->layouts.desc[i].desc))
00078 );
00079 }
00080 for (i = 0; i < rules->options.num_desc; ++i) {
00081 mOptions.replace (
00082 rules->options.desc[i].name,
00083 new QString (qstrdup( rules->options.desc[i].desc))
00084 );
00085 }
00086 XkbRF_Free(rules, true);
00087
00088
00089
00090
00091
00092 for(int i=0; fixedLayouts[i].layout != 0; i++ ) {
00093 mLayouts.replace (
00094 fixedLayouts[i].locale, new QString (fixedLayouts[i].layout)
00095 );
00096 }
00097 }
00098
00099
00100
00101
00102 QList<QString> SaXKeyRules::getVariants (const QString& layout) {
00103
00106
00107 if ( layout.isEmpty() || ! getLayouts().find(layout) ) {
00108 return QList<QString>();
00109 }
00110 QList<QString> result1;
00111 QStringList* r1 = mVarLists[layout];
00112 if ( r1 ) {
00113 for ( QStringList::Iterator it=r1->begin(); it != r1->end(); ++it ) {
00114 QString* item = new QString (*it);
00115 result1.append (item);
00116 }
00117 return result1;
00118 }
00119 QList<QString> result2;
00120 QStringList* result = new QStringList();
00121 QString file = mX11Dir + "xkb/symbols/" + layout;
00122 QFile f(file);
00123 if (f.open(IO_ReadOnly)) {
00124 QTextStream ts(&f);
00125 QString line;
00126 QString prev_line;
00127 while (!ts.eof()) {
00128 prev_line = line;
00129 line = ts.readLine().simplifyWhiteSpace();
00130 if (line[0] == '#' || line.left(2) == "//" || line.isEmpty()) {
00131 continue;
00132 }
00133 int pos = line.find("xkb_symbols");
00134 if (pos < 0) {
00135 continue;
00136 }
00137 if ( prev_line.find("hidden") >=0 ) {
00138 continue;
00139 }
00140 pos = line.find('"', pos) + 1;
00141 int pos2 = line.find('"', pos);
00142 if ( pos < 0 || pos2 < 0 ) {
00143 continue;
00144 }
00145 result->append (
00146 line.mid(pos, pos2-pos)
00147 );
00148 }
00149 f.close();
00150 }
00151 mVarLists.insert(layout, result);
00152 for ( QStringList::Iterator it=result->begin(); it != result->end();++it) {
00153 QString* item = new QString (*it);
00154 result2.append (item);
00155 }
00156 return result2;
00157 }
00158
00159
00160
00161
00162 QDict<QString> SaXKeyRules::getModels (void) {
00163 return mModels;
00164 }
00165
00166
00167
00168
00169 QDict<QString> SaXKeyRules::getLayouts (void) {
00170 return mLayouts;
00171 }
00172
00173
00174
00175
00176 QDict<QString> SaXKeyRules::getOptions (void) {
00177 return mOptions;
00178 }
00179
00180
00181
00182
00183 SaXManipulateKeyboard::SaXManipulateKeyboard (
00184 SaXImport* in, int kbd
00185 ) : SaXManipulateKeyboardIF () {
00186
00191
00192 if ( ! in ) {
00193 excNullPointerArgument ();
00194 qError (errorString(),EXC_NULLPOINTERARGUMENT);
00195 return;
00196 }
00197 if ( in->getSectionID() != SAX_KEYBOARD ) {
00198 excKeyboardImportBindFailed ( in->getSectionID() );
00199 qError (errorString(),EXC_KEYBOARDIMPORTBINDFAILED);
00200 return;
00201 }
00202 mImport = in;
00203 mKeyboard = kbd;
00204 mImport -> setID ( mKeyboard );
00205 }
00206
00207
00208
00209
00210 bool SaXManipulateKeyboard::selectKeyboard (int ptr) {
00211
00214
00215 if (! mImport) {
00216 return false;
00217 }
00218 if (mImport -> setID ( ptr )) {
00219 mKeyboard = ptr;
00220 return true;
00221 }
00222 return false;
00223 }
00224
00225
00226
00227
00228 void SaXManipulateKeyboard::setXKBModel (const QString& model) {
00229
00232
00233 if (! mImport) {
00234 return;
00235 }
00236 mImport -> setItem ( "XkbModel",model );
00237 }
00238
00239
00240
00241
00242 void SaXManipulateKeyboard::setXKBLayout (const QString& layout) {
00243
00246
00247 if (! mImport) {
00248 return;
00249 }
00250 mImport -> setItem ( "XkbLayout",layout );
00251 }
00252
00253
00254
00255
00256 void SaXManipulateKeyboard::addXKBLayout (const QString& layout) {
00257
00261
00262 if (! mImport) {
00263 return;
00264 }
00265 QString val;
00266 QString key ("XkbLayout");
00267 if (! mImport -> getItem (key).isEmpty()) {
00268 val = mImport -> getItem (key);
00269 }
00270 QTextOStream (&val) << val << "," << layout;
00271 mImport -> setItem ( key,val );
00272 }
00273
00274
00275
00276
00277 void SaXManipulateKeyboard::removeXKBLayout (const QString& layout) {
00278
00281
00282 if (! mImport) {
00283 return;
00284 }
00285 QString val (layout);
00286 QString key ("XkbLayout");
00287 if (! mImport -> getItem (key).isEmpty()) {
00288 mImport -> removeItem (key,val);
00289 }
00290 }
00291
00292
00293
00294
00295 void SaXManipulateKeyboard::setXKBOption (const QString& option) {
00296
00299
00300 if (! mImport) {
00301 return;
00302 }
00303 mImport -> setItem ( "XkbOptions",option );
00304 }
00305
00306
00307
00308
00309 void SaXManipulateKeyboard::addXKBOption (const QString& option) {
00310
00313
00314 if (! mImport) {
00315 return;
00316 }
00317 QString val;
00318 QString key ("XkbOptions");
00319 if (! mImport -> getItem (key).isEmpty()) {
00320 val = mImport -> getItem (key);
00321 }
00322 QTextOStream (&val) << val << "," << option;
00323 mImport -> setItem ( key,val );
00324 }
00325
00326
00327
00328
00329 void SaXManipulateKeyboard::removeXKBOption (const QString& option) {
00330
00333
00334 if (! mImport) {
00335 return;
00336 }
00337 QString val (option);
00338 QString key ("XkbOptions");
00339 if (! mImport -> getItem (key).isEmpty()) {
00340 mImport -> removeItem (key,val);
00341 }
00342 }
00343
00344
00345
00346
00347 void SaXManipulateKeyboard::setXKBVariant (
00348 const QString& layout, const QString& variant
00349 ) {
00350
00353
00354 if (! mImport) {
00355 return;
00356 }
00357 int layoutCount = findLayout (layout);
00358 if (layoutCount < 0) {
00359 excXKBLayoutUndefined (layout);
00360 qError (errorString(),EXC_XKBLAYOUTUNDEFINED);
00361 return;
00362 }
00363 QList<QString> vList = getXKBVariantList();
00364 QList<QString> lList = getXKBLayout();
00365 int varCount = 0;
00366 QStringList result;
00367 QListIterator<QString> it (lList);
00368 for (; it.current();++it) {
00369 QString item;
00370 if (vList.at(varCount)) {
00371 item = *vList.at (varCount);
00372 }
00373 if (varCount == layoutCount) {
00374 item = variant;
00375 }
00376 result += item;
00377 varCount++;
00378 }
00379 mImport -> setItem ("XkbVariant",result.join(","));
00380 }
00381
00382
00383
00384
00385 void SaXManipulateKeyboard::removeXKBVariant ( const QString& layout ) {
00386
00389
00390 setXKBVariant (layout,"");
00391 }
00392
00393
00394
00395
00396 void SaXManipulateKeyboard::setMapping (
00397 const QString& type,const QString& mapping
00398 ) {
00399
00403
00404 if (! mImport) {
00405 return;
00406 }
00407 QString key (type);
00408 QString map (mapping);
00409 if (
00410 (key != XKB_LEFT_ALT) &&
00411 (key != XKB_RIGHT_ALT) &&
00412 (key != XKB_SCROLL_LOCK) &&
00413 (key != XKB_RIGHT_CTL)
00414 ) {
00415 excInvalidArgument (type);
00416 qError (errorString(),EXC_INVALIDARGUMENT);
00417 return;
00418 }
00419 if (
00420 (map != XKB_MAP_META) &&
00421 (map != XKB_MAP_COMPOSE) &&
00422 (map != XKB_MAP_MODESHIFT) &&
00423 (map != XKB_MAP_MODELOCK) &&
00424 (map != XKB_MAP_SCROLLLOCK) &&
00425 (map != XKB_MAP_CONTROL)
00426 ) {
00427 excInvalidArgument (mapping);
00428 qError (errorString(),EXC_INVALIDARGUMENT);
00429 return;
00430 }
00431 mImport -> setItem ( type,mapping );
00432 }
00433
00434
00435
00436
00437 QString SaXManipulateKeyboard::getDriver (void) {
00438
00440
00441 if (! mImport) {
00442 return QString();
00443 }
00444 return mImport -> getItem ("Driver");
00445 }
00446
00447
00448
00449
00450 QList<QString> SaXManipulateKeyboard::getXKBOptionList (void) {
00451
00453
00454 if (! mImport) {
00455 return QList<QString>();
00456 }
00457 QString options = mImport -> getItem ("XkbOptions");
00458 return createList (options);
00459 }
00460
00461
00462
00463
00464 QList<QString> SaXManipulateKeyboard::getXKBLayout (void) {
00465
00468
00469 if (! mImport) {
00470 return QList<QString>();
00471 }
00472 QString layouts = mImport -> getItem ("XkbLayout");
00473 return createList (layouts);
00474 }
00475
00476
00477
00478
00479 QList<QString> SaXManipulateKeyboard::getXKBVariantList (void) {
00480
00483
00484 if (! mImport) {
00485 return QList<QString>();
00486 }
00487 QString variants = mImport -> getItem ("XkbVariant");
00488 return createList (variants);
00489 }
00490
00491
00492
00493
00494 QString SaXManipulateKeyboard::getXKBVariant ( const QString& layout ) {
00495
00500
00501 if (! mImport) {
00502 return QString();
00503 }
00504 int layoutCount = findLayout (layout);
00505 if (layoutCount < 0) {
00506 excXKBLayoutUndefined (layout);
00507 qError (errorString(),EXC_XKBLAYOUTUNDEFINED);
00508 return QString();
00509 }
00510 int varCount = 0;
00511 QList<QString> vList = getXKBVariantList();
00512 QListIterator<QString> it (vList);
00513 for (; it.current();++it) {
00514 if (varCount == layoutCount) {
00515 return *it.current();
00516 }
00517 varCount++;
00518 }
00519 return QString();
00520 }
00521
00522
00523
00524
00525 QString SaXManipulateKeyboard::getXKBModel (void) {
00526
00529
00530 if (! mImport) {
00531 return QString();
00532 }
00533 return mImport -> getItem ("XkbModel");
00534 }
00535
00536
00537
00538
00539 int SaXManipulateKeyboard::findLayout (const QString& layout) {
00540
00544
00545 int count = 0;
00546 bool found = false;
00547 QString layoutData = mImport -> getItem ("XkbLayout");
00548 QStringList layouts = QStringList::split ( ",", layoutData );
00549 for (QStringList::Iterator it=layouts.begin(); it!=layouts.end();++ it) {
00550 QString item (*it);
00551 if (item == layout) {
00552 found = true; break;
00553 }
00554 count++;
00555 }
00556 if (! found) {
00557 return -1;
00558 }
00559 return count;
00560 }
00561
00562
00563
00564
00565 QList<QString> SaXManipulateKeyboard::createList ( const QString& data) {
00566
00569
00570 if (data.isEmpty()) {
00571 return QList<QString>();
00572 }
00573 QList<QString> result;
00574 QStringList dataList = QStringList::split ( ",", data, true );
00575 for (QStringList::Iterator it=dataList.begin(); it!=dataList.end();++ it) {
00576 QString* item = new QString (*it);
00577 result.append (item);
00578 }
00579 return result;
00580 }
00581 }