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/X11R6/lib/X11/";
00034 loadRules (mX11Dir + QString("xkb/rules/%1").arg(rule));
00035 }
00036
00037
00038
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
00086
00087
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
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
00158
00159 QDict<QString> SaXKeyRules::getModels (void) {
00160 return mModels;
00161 }
00162
00163
00164
00165
00166 QDict<QString> SaXKeyRules::getLayouts (void) {
00167 return mLayouts;
00168 }
00169
00170
00171
00172
00173 QDict<QString> SaXKeyRules::getOptions (void) {
00174 return mOptions;
00175 }
00176
00177
00178
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
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
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
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
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
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
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
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
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
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
00381
00382 void SaXManipulateKeyboard::removeXKBVariant ( const QString& layout ) {
00383
00386
00387 setXKBVariant (layout,"");
00388 }
00389
00390
00391
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
00433
00434 QString SaXManipulateKeyboard::getDriver (void) {
00435
00437
00438 if (! mImport) {
00439 return QString();
00440 }
00441 return mImport -> getItem ("Driver");
00442 }
00443
00444
00445
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
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
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
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
00521
00522 QString SaXManipulateKeyboard::getXKBModel (void) {
00523
00526
00527 if (! mImport) {
00528 return QString();
00529 }
00530 return mImport -> getItem ("XkbModel");
00531 }
00532
00533
00534
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
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 }