Ticket #5583: lirc-5583-v2.patch
File lirc-5583-v2.patch, 24.6 KB (added by , 16 years ago) |
---|
-
mythtv/libs/libmythui/lirc.h
1 1 #ifndef LIRC_H_ 2 2 #define LIRC_H_ 3 3 4 #include <lirc/lirc_client.h>5 4 #include <QObject> 6 5 #include <QThread> 7 6 #include <QString> 7 #include <QMutex> 8 8 9 9 #include "mythexp.h" 10 10 … … 14 14 * Create connection to the lircd daemon and translate remote keypresses 15 15 * into custom events which are posted to the mainwindow. 16 16 */ 17 class MPUBLIC LircThread : public QThread 17 class LIRCPriv; 18 class MPUBLIC LIRC : public QThread 18 19 { 19 20 Q_OBJECT 21 20 22 public: 21 LircThread(QObject *main_window); 22 ~LircThread(); 23 int Init(const QString &config_file, const QString &program, 24 bool ignoreExtApp=false); 25 void Stop(void) { m_bStop = true; } 23 LIRC(QObject *main_window, 24 const QString &lircd_device, 25 const QString &our_program, 26 const QString &config_file, 27 const QString &external_app); 28 bool Init(void); 26 29 30 virtual void start(void); 31 virtual void deleteLater(void); 32 27 33 private: 28 void run(void); 34 virtual ~LIRC(); 35 void TeardownAll(); 36 37 bool IsDoRunSet(void) const; 38 virtual void run(void); 29 39 void SpawnApp(void); 40 QList<QByteArray> GetCodes(void); 41 void Process(const QByteArray &data); 30 42 31 struct lirc_config *m_lircConfig; 32 QObject *m_mainWindow; 33 volatile bool m_bStop; 34 int m_fd; 35 36 QString m_externalApp; 43 mutable QMutex lock; 44 static QMutex lirclib_lock; 45 QObject *m_mainWindow; ///< window to send key events to 46 QString lircdDevice; ///< device on which to receive lircd data 47 QString program; ///< program to extract from config file 48 QString configFile; ///< config file containing LIRC->key mappings 49 QString m_externalApp; ///< external application for keys 50 bool doRun; 51 int lircd_socket; 52 uint buf_offset; 53 QByteArray buf; 54 uint eofCount; 55 uint retryCount; 56 LIRCPriv *d; 37 57 }; 38 58 39 59 #endif -
mythtv/libs/libmythui/mythmainwindow.cpp
116 116 bool ignore_joystick_keys; 117 117 118 118 #ifdef USE_LIRC 119 L ircThread*lircThread;119 LIRC *lircThread; 120 120 #endif 121 121 122 122 #ifdef USE_JOYSTICK_MENU … … 319 319 config_file = QDir::homePath() + "/.lircrc"; 320 320 321 321 d->lircThread = NULL; 322 d->lircThread = new LircThread(this); 323 if (!d->lircThread->Init(config_file, "mythtv")) 322 d->lircThread = new LIRC( 323 this, 324 GetMythDB()->GetSetting("LircSocket", "/dev/lircd"), 325 "mythtv", config_file, 326 GetMythDB()->GetSetting("LircKeyPressedApp", "")); 327 328 if (d->lircThread->Init()) 324 329 d->lircThread->start(); 325 330 #endif 326 331 … … 426 431 #ifdef USE_LIRC 427 432 if (d->lircThread) 428 433 { 429 if (d->lircThread->isRunning()) 430 { 431 d->lircThread->Stop(); 432 d->lircThread->wait(); 433 } 434 435 delete d->lircThread; 434 d->lircThread->deleteLater(); 436 435 d->lircThread = NULL; 437 436 } 438 437 #endif -
mythtv/libs/libmythui/lirc.cpp
1 #include <algorithm> 2 #include <vector> 3 using namespace std; 4 1 5 #include <QApplication> 2 6 #include <QEvent> 3 7 #include <QKeySequence> 8 #include <QStringList> 4 9 5 10 #include <cstdio> 6 11 #include <cerrno> … … 15 20 16 21 #include "lirc.h" 17 22 #include "lircevent.h" 23 #include <lirc/lirc_client.h> 18 24 19 LircThread::LircThread(QObject *main_window) 25 namespace POSIX 26 { 27 #include <sys/types.h> 28 #include <sys/select.h> 29 #include <sys/socket.h> 30 #include <sys/un.h> 31 #include <netinet/in.h> 32 #include <arpa/inet.h> 33 #include <netdb.h> 34 #include <unistd.h> 35 #include <fcntl.h> 36 }; 37 using namespace POSIX; 38 39 #define LOC QString("LIRC: ") 40 #define LOC_WARN QString("LIRC, Warning: ") 41 #define LOC_ERR QString("LIRC, Error: ") 42 43 class LIRCPriv 44 { 45 public: 46 LIRCPriv() : lircConfig(NULL) {} 47 ~LIRCPriv() 48 { 49 if (lircConfig) 50 { 51 lirc_freeconfig(lircConfig); 52 lircConfig = NULL; 53 } 54 } 55 56 struct lirc_config *lircConfig; 57 }; 58 59 QMutex LIRC::lirclib_lock; 60 61 /** \class LIRC 62 * \brief Interface between mythtv and lircd 63 * 64 * Create connection to the lircd daemon and translate remote keypresses 65 * into custom events which are posted to the mainwindow. 66 */ 67 68 LIRC::LIRC(QObject *main_window, 69 const QString &lircd_device, 70 const QString &our_program, 71 const QString &config_file, 72 const QString &external_app) 20 73 : QThread(), 21 m_lircConfig(NULL), m_mainWindow(main_window), 22 m_bStop(false), m_fd(-1), 23 m_externalApp("") 74 lock(QMutex::Recursive), 75 m_mainWindow(main_window), 76 lircdDevice(lircd_device), 77 program(our_program), 78 configFile(config_file), 79 m_externalApp(external_app), 80 doRun(false), 81 lircd_socket(-1), 82 buf_offset(0), 83 eofCount(0), 84 retryCount(0), 85 d(new LIRCPriv()) 24 86 { 87 lircdDevice.detach(); 88 program.detach(); 89 configFile.detach(); 90 m_externalApp.detach(); 91 buf.resize(128); 25 92 } 26 93 27 /** 28 * \brief Initialise the class variables, read the lirc config and user 29 * settings 30 */ 31 int LircThread::Init(const QString &config_file, const QString &program, 32 bool ignoreExtApp) 94 LIRC::~LIRC() 33 95 { 34 /* Connect the unix socket */ 35 m_fd = lirc_init((char *)qPrintable(program), 1); 36 if (m_fd == -1) 96 TeardownAll(); 97 } 98 99 void LIRC::deleteLater(void) 100 { 101 TeardownAll(); 102 QThread::deleteLater(); 103 } 104 105 void LIRC::TeardownAll(void) 106 { 107 QMutexLocker locker(&lock); 108 if (doRun) 37 109 { 38 VERBOSE(VB_IMPORTANT,39 QString("lirc_init failed for %1, see preceding messages")40 .arg(program));41 return -1;110 doRun = false; 111 lock.unlock(); 112 wait(); 113 lock.lock(); 42 114 } 43 115 44 /* parse the config file */ 45 if (lirc_readconfig((char *)qPrintable(config_file), &m_lircConfig, NULL)) 116 if (lircd_socket >= 0) 46 117 { 47 VERBOSE(VB_IMPORTANT, 48 QString("Failed to read lirc config %1 for %2") 49 .arg(config_file).arg(program)); 50 lirc_deinit(); 51 return -1; 118 close(lircd_socket); 119 lircd_socket = -1; 52 120 } 53 121 54 if (!ignoreExtApp) 55 m_externalApp = GetMythDB()->GetSetting("LircKeyPressedApp", ""); 122 if (d) 123 { 124 delete d; 125 d = NULL; 126 } 127 } 56 128 57 VERBOSE(VB_GENERAL, 58 QString("lirc init success using configuration file: %1") 59 .arg(config_file)); 129 QByteArray get_ip(const QString &h) 130 { 131 QByteArray hba = h.toLatin1(); 132 struct in_addr sin_addr; 133 if (inet_aton(hba.constData(), &sin_addr)) 134 return hba; 60 135 61 return 0; 62 } 136 struct addrinfo hints; 137 memset(&hints, 0, sizeof(hints)); 138 hints.ai_family = AF_INET; 139 hints.ai_socktype = SOCK_STREAM; 140 hints.ai_protocol = IPPROTO_TCP; 63 141 64 LircThread::~LircThread() 65 { 66 lirc_deinit(); 67 if (m_lircConfig) 68 lirc_freeconfig(m_lircConfig); 142 struct addrinfo *result; 143 int err = getaddrinfo(hba.constData(), NULL, &hints, &result); 144 if (err) 145 { 146 VERBOSE(VB_IMPORTANT, QString("get_ip: %1").arg(gai_strerror(err))); 147 return QString("").toLatin1(); 148 } 149 150 int addrlen = result->ai_addrlen; 151 if (!addrlen) 152 { 153 freeaddrinfo(result); 154 return QString("").toLatin1(); 155 } 156 157 if (result->ai_addr->sa_family != AF_INET) 158 { 159 freeaddrinfo(result); 160 return QString("").toLatin1(); 161 } 162 163 sin_addr = ((struct sockaddr_in*)(result->ai_addr))->sin_addr; 164 hba = QByteArray(inet_ntoa(sin_addr)); 165 freeaddrinfo(result); 166 167 return hba; 69 168 } 70 169 71 /** 72 * \brief Main thread loop 73 */ 74 void LircThread::run(void) 170 bool LIRC::Init(void) 75 171 { 76 char *code = 0; 77 char *ir = 0; 78 int ret; 79 fd_set readfds; 80 struct timeval timeout; 172 QMutexLocker locker(&lock); 173 if (lircd_socket >= 0) 174 return true; 81 175 82 /* Process all events read */ 83 while (!m_bStop) 176 if (lircdDevice.startsWith('/')) 84 177 { 85 FD_ZERO(&readfds); 86 FD_SET(m_fd, &readfds); 178 // Connect the unix socket 179 QByteArray dev = lircdDevice.toLocal8Bit(); 180 if (dev.size() > 107) 181 { 182 VERBOSE(VB_IMPORTANT, LOC_ERR + QString("lircdDevice '%1'") 183 .arg(lircdDevice) + 184 " is too long for the 'unix' socket API"); 87 185 88 // the maximum time select() should wait 89 timeout.tv_sec = 0; 90 timeout.tv_usec = 100000; 186 return false; 187 } 91 188 92 ret = select(m_fd + 1, &readfds, NULL, NULL, &timeout); 189 lircd_socket = socket(AF_UNIX, SOCK_STREAM, 0); 190 if (lircd_socket < 0) 191 { 192 VERBOSE(VB_IMPORTANT, LOC_ERR + 193 QString("Failed to open Unix socket '%1'") 194 .arg(lircdDevice) + ENO); 93 195 94 if (ret == 0)95 continue;196 return false; 197 } 96 198 97 if (ret == -1) 199 struct sockaddr_un addr; 200 memset(&addr, 0, sizeof(sockaddr_un)); 201 addr.sun_family = AF_UNIX; 202 strncpy(addr.sun_path, dev.constData(),107); 203 204 int ret = POSIX::connect( 205 lircd_socket, (struct sockaddr*) &addr, sizeof(addr)); 206 207 if (ret < 0) 98 208 { 99 perror("LircThread - select"); 100 return; 209 VERBOSE(VB_IMPORTANT, LOC_ERR + 210 QString("Failed to connect to Unix socket '%1'") 211 .arg(lircdDevice) + ENO); 212 213 close(lircd_socket); 214 lircd_socket = -1; 215 return false; 101 216 } 217 } 218 else 219 { 220 lircd_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 221 if (lircd_socket < 0) 222 { 223 VERBOSE(VB_IMPORTANT, LOC_ERR + 224 QString("Failed to open TCP socket '%1'") 225 .arg(lircdDevice) + ENO); 102 226 103 if (ret == 1) 227 return false; 228 } 229 230 QString dev = lircdDevice; 231 uint port = 8765; 232 QStringList tmp = lircdDevice.split(':'); 233 if (2 == tmp.size()) 104 234 { 105 ret = lirc_nextcode(&ir); 235 dev = tmp[0]; 236 port = (tmp[1].toUInt()) ? tmp[1].toUInt() : port; 237 } 238 QByteArray device = get_ip(dev); 239 struct sockaddr_in addr; 240 memset(&addr, 0, sizeof(sockaddr_in)); 241 addr.sin_family = AF_INET; 242 addr.sin_port = htons(port); 106 243 107 if (ret == -1) 244 if (!inet_aton(device.constData(), &addr.sin_addr)) 245 { 246 VERBOSE(VB_IMPORTANT, LOC_ERR + 247 QString("Failed to parse IP address '%1'").arg(dev)); 248 249 close(lircd_socket); 250 lircd_socket = -1; 251 return false; 252 } 253 254 int ret = POSIX::connect( 255 lircd_socket, (struct sockaddr*) &addr, sizeof(addr)); 256 if (ret < 0) 257 { 258 VERBOSE(VB_IMPORTANT, LOC_ERR + 259 QString("Failed to connect TCP socket '%1'") 260 .arg(lircdDevice) + ENO); 261 262 close(lircd_socket); 263 lircd_socket = -1; 264 return false; 265 } 266 267 // On Linux, select() can indicate data when there isn't 268 // any due to TCP checksum in-particular; to avoid getting 269 // stuck on a read() call add the O_NONBLOCK flag. 270 int flags = fcntl(lircd_socket, F_GETFD); 271 if (flags >= 0) 272 { 273 ret = fcntl(lircd_socket, F_SETFD, flags | O_NONBLOCK); 274 if (ret < 0) 108 275 { 109 if (errno != 0) 110 VERBOSE(VB_IMPORTANT, 111 QString("LircThread: lirc_nextcode failed" 112 "last error was: %1").arg(errno)); 113 return; 276 VERBOSE(VB_IMPORTANT, LOC_WARN + 277 QString("Failed set flags for socket '%1'") 278 .arg(lircdDevice) + ENO); 114 279 } 280 } 115 281 116 if (!ir) 117 continue; 282 // Attempt to inline out-of-band messages and keep the connection open.. 283 int i = 1; 284 setsockopt(lircd_socket, SOL_SOCKET, SO_OOBINLINE, &i, sizeof(i)); 285 i = 1; 286 setsockopt(lircd_socket, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i)); 287 } 118 288 119 while ((ret = lirc_code2char(m_lircConfig, ir, &code)) == 0 && 120 code != NULL) 289 // parse the config file 290 if (!d->lircConfig) 291 { 292 QMutexLocker static_lock(&lirclib_lock); 293 QByteArray cfg = configFile.toLocal8Bit(); 294 if (lirc_readconfig( 295 const_cast<char*>(cfg.constData()), &d->lircConfig, NULL)) 296 { 297 VERBOSE(VB_IMPORTANT, LOC_ERR + 298 QString("Failed to read config file '%1'").arg(configFile)); 299 300 close(lircd_socket); 301 lircd_socket = -1; 302 return false; 303 } 304 305 // Get rid of the stuff we don't care about.. 306 vector<struct lirc_config_entry*> del; 307 struct lirc_config_entry *it = d->lircConfig->first; 308 while (it->next) 309 { 310 if (program == QString(it->next->prog)) 121 311 { 122 QKeySequence a(code); 312 it = it->next; 313 } 314 else 315 { 316 del.push_back(it->next); 317 it->next = it->next->next; 318 } 319 } 320 if (program != QString(d->lircConfig->first->prog)) 321 { 322 del.push_back(d->lircConfig->first); 323 d->lircConfig->first = d->lircConfig->first->next; 324 } 325 d->lircConfig->next = d->lircConfig->first; 123 326 124 int keycode = 0; 327 for (uint i = 0; i < del.size(); i++) 328 { 329 struct lirc_config_entry *c = del[i]; 330 if (c->prog) 331 free(c->prog); 332 if (c->change_mode) 333 free(c->change_mode); 334 if (c->mode) 335 free(c->mode); 125 336 126 // Send a dummy keycode if we couldn't convert the key sequence. 127 // This is done so the main code can output a warning for bad 128 // mappings. 129 if (!a.count()) 130 QApplication::postEvent(m_mainWindow, 131 new LircKeycodeEvent(code, keycode, 132 true)); 337 struct lirc_code *code = c->code; 338 while (code) 339 { 340 if (code->remote && code->remote!=LIRC_ALL) 341 free(code->remote); 342 if (code->button && code->button!=LIRC_ALL) 343 free(code->button); 344 struct lirc_code *code_temp = code->next; 345 free(code); 346 code = code_temp; 347 } 133 348 134 for (unsigned int i = 0; i < a.count(); i++) 135 { 136 keycode = a[i]; 349 struct lirc_list *list = c->config; 350 while (list) 351 { 352 if (list->string) 353 free(list->string); 354 struct lirc_list *list_temp = list->next; 355 free(list); 356 list = list_temp; 357 } 137 358 138 QApplication::postEvent(m_mainWindow, 139 new LircKeycodeEvent(code, keycode, 140 true)); 141 QApplication::postEvent(m_mainWindow, 142 new LircKeycodeEvent(code, keycode, 143 false)); 359 free(c); 360 } 361 } 144 362 145 SpawnApp(); 146 } 363 VERBOSE(VB_GENERAL, LOC + 364 QString("Successfully initialized '%1' using '%2' config") 365 .arg(lircdDevice).arg(configFile)); 366 367 return true; 368 } 369 370 void LIRC::start(void) 371 { 372 QMutexLocker locker(&lock); 373 374 if (lircd_socket < 0) 375 { 376 VERBOSE(VB_IMPORTANT, LOC_ERR + "start() called without lircd socket"); 377 return; 378 } 379 380 doRun = true; 381 QThread::start(); 382 } 383 384 bool LIRC::IsDoRunSet(void) const 385 { 386 QMutexLocker locker(&lock); 387 return doRun; 388 } 389 390 void LIRC::Process(const QByteArray &data) 391 { 392 QMutexLocker static_lock(&lirclib_lock); 393 394 // lirc_code2char will make code point to a static datafer.. 395 char *code = NULL; 396 int ret = lirc_code2char( 397 d->lircConfig, const_cast<char*>(data.constData()), &code); 398 399 while ((0 == ret) && code) 400 { 401 QString text(code); 402 QKeySequence a(code); 403 404 int keycode = 0; 405 406 // Send a dummy keycode if we couldn't convert the key sequence. 407 // This is done so the main code can output a warning for bad 408 // mappings. 409 if (!a.count()) 410 { 411 QApplication::postEvent( 412 m_mainWindow, new LircKeycodeEvent(text, keycode, true)); 413 } 414 415 for (unsigned int i = 0; i < a.count(); i++) 416 { 417 keycode = a[i]; 418 419 QApplication::postEvent( 420 m_mainWindow, new LircKeycodeEvent(text, keycode, true)); 421 QApplication::postEvent( 422 m_mainWindow, new LircKeycodeEvent(text, keycode, false)); 423 424 SpawnApp(); 425 } 426 ret = lirc_code2char( 427 d->lircConfig, const_cast<char*>(data.constData()), &code); 428 } 429 } 430 431 void LIRC::run(void) 432 { 433 //VERBOSE(VB_GENERAL, LOC + "run -- start"); 434 /* Process all events read */ 435 while (IsDoRunSet()) 436 { 437 if (eofCount && retryCount) 438 usleep(100 * 1000); 439 440 if ((eofCount >= 10) || (lircd_socket < 0)) 441 { 442 QMutexLocker locker(&lock); 443 eofCount = 0; 444 if (++retryCount > 1000) 445 { 446 VERBOSE(VB_IMPORTANT, LOC_ERR + 447 "Failed to reconnect, exiting LIRC thread."); 448 doRun = false; 449 continue; 147 450 } 451 VERBOSE(VB_GENERAL, LOC_WARN + "EOF -- reconnecting"); 148 452 149 free(ir); 150 if (ret == -1) 151 break; 453 close(lircd_socket); 454 lircd_socket = -1; 455 456 if (!Init()) 457 sleep(2); // wait a while before we retry.. 458 459 continue; 152 460 } 461 462 fd_set readfds; 463 FD_ZERO(&readfds); 464 FD_SET(lircd_socket, &readfds); 465 466 // the maximum time select() should wait 467 struct timeval timeout; 468 timeout.tv_sec = 1; // 1 second 469 timeout.tv_usec = 100 * 1000; // 100 ms 470 471 int ret = select(lircd_socket + 1, &readfds, NULL, NULL, &timeout); 472 473 if (ret < 0 && errno != EINTR) 474 { 475 VERBOSE(VB_IMPORTANT, LOC_ERR + "select() failed" + ENO); 476 continue; 477 } 478 479 // 0: Timer expired with no data, repeat select 480 // -1: Iinterrupted while waiting, repeat select 481 if (ret <= 0) 482 continue; 483 484 QList<QByteArray> codes = GetCodes(); 485 for (uint i = 0; i < (uint) codes.size(); i++) 486 Process(codes[i]); 153 487 } 488 //VERBOSE(VB_GENERAL, LOC + "run -- end"); 154 489 } 155 490 156 /** 157 * \brief Spawn a user defined application which might do something like 158 * illuminating an led to give positive feedback that a key was received 159 */ 160 void LircThread::SpawnApp(void) 491 QList<QByteArray> LIRC::GetCodes(void) 161 492 { 493 QList<QByteArray> ret; 494 ssize_t len = -1; 495 do 496 { 497 len = read(lircd_socket, 498 buf.data() + buf_offset, 499 buf.size() - buf_offset - 1); 500 501 if (len >= 0) 502 break; 503 504 if (EINTR == errno) 505 continue; 506 else if (EAGAIN == errno) 507 return ret; 508 else if (107 == errno) 509 { 510 if (!eofCount) 511 VERBOSE(VB_GENERAL, LOC + "GetCodes -- EOF?"); 512 eofCount++; 513 return ret; 514 } 515 else 516 { 517 VERBOSE(VB_IMPORTANT, LOC + "Error reading socket" + ENO); 518 return ret; 519 } 520 } while (false); 521 522 if (0 == len) 523 { 524 if (!eofCount) 525 VERBOSE(VB_GENERAL, LOC + "GetCodes -- eof?"); 526 eofCount++; 527 return ret; 528 } 529 530 eofCount = 0; 531 retryCount = 0; 532 533 buf_offset += len; 534 if ((uint)buf.size() < buf_offset + 128) 535 buf.reserve(buf.size() * 2); 536 uint tmpc = std::max(buf.capacity() - 1,128); 537 538 buf.resize(buf_offset); 539 ret = buf.split('\n'); 540 buf.resize(tmpc); 541 if (buf.endsWith('\n')) 542 { 543 buf_offset = 0; 544 return ret; 545 } 546 547 buf = ret.back(); 548 ret.pop_back(); 549 buf_offset = std::max(buf.size() - 1, 0); 550 buf.resize(tmpc); 551 552 return ret; 553 } 554 555 void LIRC::SpawnApp(void) 556 { 557 // Spawn app to illuminate led (or what ever the user has picked if 558 // anything) to give positive feedback that a key was received 162 559 if (m_externalApp.isEmpty()) 163 560 return; 164 561 -
mythtv/programs/mythfrontend/globalsettings.cpp
2273 2273 return ge; 2274 2274 } 2275 2275 2276 static HostLineEdit *LircDaemonDevice() 2277 { 2278 HostLineEdit *ge = new HostLineEdit("LircSocket"); 2279 ge->setLabel(QObject::tr("LIRC Daemon Socket")); 2280 ge->setValue("/dev/lircd"); 2281 QString help = QObject::tr( 2282 "UNIX socket or IP address[:port] to connect in " 2283 "order to communicate with the LIRC Daemon."); 2284 ge->setHelpText(help); 2285 return ge; 2286 } 2287 2276 2288 static HostLineEdit *LircKeyPressedApp() 2277 2289 { 2278 2290 HostLineEdit *ge = new HostLineEdit("LircKeyPressedApp"); 2279 ge->setLabel(QObject::tr(" Keypress Application"));2291 ge->setLabel(QObject::tr("LIRC Keypress Application")); 2280 2292 ge->setValue(""); 2281 2293 ge->setHelpText(QObject::tr("External application or script to run when " 2282 2294 "a keypress is received by LIRC.")); … … 2286 2298 static HostLineEdit *ScreenShotPath() 2287 2299 { 2288 2300 HostLineEdit *ge = new HostLineEdit("ScreenShotPath"); 2289 ge->setLabel(QObject::tr("Screen ShotPath"));2301 ge->setLabel(QObject::tr("Screen Shot Path")); 2290 2302 ge->setValue("/tmp/"); 2291 2303 ge->setHelpText(QObject::tr("Path to screenshot storage location. Should be writable by the frontend")); 2292 2304 return ge; … … 4571 4583 VerticalConfigurationGroup *general = 4572 4584 new VerticalConfigurationGroup(false, true, false, false); 4573 4585 general->setLabel(QObject::tr("General")); 4586 general->addChild(AllowQuitShutdown()); 4574 4587 HorizontalConfigurationGroup *row = 4575 4588 new HorizontalConfigurationGroup(false, false, true, true); 4576 VerticalConfigurationGroup *col1 = 4577 new VerticalConfigurationGroup(false, false, true, true); 4578 VerticalConfigurationGroup *col2 = 4579 new VerticalConfigurationGroup(false, false, true, true); 4580 col1->addChild(AllowQuitShutdown()); 4581 col1->addChild(NoPromptOnExit()); 4582 col2->addChild(UseArrowAccels()); 4583 col2->addChild(NetworkControlEnabled()); 4584 row->addChild(col1); 4585 row->addChild(col2); 4586 4587 MythMediaSettings *mediaMon = new MythMediaSettings(); 4588 4589 general->addChild(LircKeyPressedApp()); 4589 row->addChild(NoPromptOnExit()); 4590 row->addChild(UseArrowAccels()); 4591 general->addChild(row); 4592 general->addChild(new MythMediaSettings()); 4590 4593 general->addChild(ScreenShotPath()); 4591 general->addChild(row);4592 general->addChild(NetworkControlPort());4593 general->addChild(mediaMon);4594 4594 addChild(general); 4595 4595 4596 VerticalConfigurationGroup *remotecontrol = 4597 new VerticalConfigurationGroup(false, true, false, false); 4598 remotecontrol->setLabel(QObject::tr("Remote Control")); 4599 remotecontrol->addChild(LircDaemonDevice()); 4600 remotecontrol->addChild(LircKeyPressedApp()); 4601 remotecontrol->addChild(NetworkControlEnabled()); 4602 remotecontrol->addChild(NetworkControlPort()); 4603 addChild(remotecontrol); 4604 4596 4605 VerticalConfigurationGroup* misc = new VerticalConfigurationGroup(false); 4597 4606 misc->setLabel(QObject::tr("Miscellaneous")); 4598 4607