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