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 #if QT_VERSION > 0x040100
00023 #include <Q3TextStream>
00024 #else
00025 typedef QTextStream Q3TextStream;
00026 #endif
00027
00028 namespace SaX {
00029
00030
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
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
00097
00098
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
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
00168
00169 Q3Dict<QString> SaXKeyRules::getModels (void) {
00170 return mModels;
00171 }
00172
00173
00174
00175
00176 Q3Dict<QString> SaXKeyRules::getLayouts (void) {
00177 return mLayouts;
00178 }
00179
00180
00181
00182
00183 Q3Dict<QString> SaXKeyRules::getOptions (void) {
00184 return mOptions;
00185 }
00186
00187
00188
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
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
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
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
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
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
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
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
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
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
00389
00390 void SaXManipulateKeyboard::removeXKBVariant ( const QString& layout ) {
00391
00394
00395 setXKBVariant (layout,"");
00396 }
00397
00398
00399
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
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
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
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
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
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
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
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
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 }