Ticket #5583: 5583-v4.patch
File 5583-v4.patch, 28.2 KB (added by , 15 years ago) |
---|
-
libs/libmythui/lirc.h
1 1 #ifndef LIRC_H_ 2 2 #define LIRC_H_ 3 3 4 #include <QByteArray> 5 #include <QString> 6 #include <QObject> 4 7 #include <QThread> 5 #include <QString> 8 #include <QMutex> 9 #include <QList> 6 10 7 #include <lirc/lirc_client.h> 11 class LIRCPriv; 8 12 9 /** \class LircThread 10 * \brief Interface between mythtv and lircd 11 * 12 * Create connection to the lircd daemon and translate remote keypresses 13 * into custom events which are posted to the mainwindow. 14 */ 15 class LircThread : public QThread 13 class LIRC : public QThread 16 14 { 17 15 Q_OBJECT 18 16 public: 19 LircThread(QObject *main_window); 20 ~LircThread(); 21 int Init(const QString &config_file, const QString &program, 22 bool ignoreExtApp=false); 23 void Stop(void) { m_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); 24 23 24 virtual void start(void); 25 virtual void deleteLater(void); 26 25 27 private: 26 void run(void); 28 virtual ~LIRC(); 29 void TeardownAll(); 30 31 bool IsDoRunSet(void) const; 32 virtual void run(void); 27 33 void SpawnApp(void); 28 29 struct lirc_config *m_lircConfig; 30 QObject *m_mainWindow; 31 volatile bool m_bStop; 32 int m_fd; 33 34 QString m_externalApp; 34 QList<QByteArray> GetCodes(void); 35 void Process(const QByteArray &data); 36 37 mutable QMutex lock; 38 static QMutex lirclib_lock; 39 QObject *m_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; ///< file containing LIRC->key mappings 43 QString m_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; 35 51 }; 36 52 37 53 #endif -
libs/libmythui/mythmainwindow.cpp
24 24 #include <HIToolbox/Menus.h> // For GetMBarHeight() 25 25 #endif 26 26 27 #ifdef USE_LIRC28 27 #include "lirc.h" 29 28 #include "lircevent.h" 30 #endif31 29 32 30 #ifdef USING_APPLEREMOTE 33 31 #include "AppleRemoteListener.h" 34 #include "lircevent.h"35 32 #endif 36 33 37 34 #ifdef USE_JOYSTICK_MENU … … 118 115 bool ignore_lirc_keys; 119 116 bool ignore_joystick_keys; 120 117 121 #ifdef USE_LIRC 122 LircThread *lircThread; 123 #endif 118 LIRC *lircThread; 124 119 125 120 #ifdef USE_JOYSTICK_MENU 126 121 JoystickMenuThread *joystickThread; … … 336 331 337 332 installEventFilter(this); 338 333 339 #ifdef USE_LIRC340 QString config_file = GetConfDir() + "/lircrc";341 if (!QFile::exists(config_file))342 config_file = QDir::homePath() + "/.lircrc";343 344 334 d->lircThread = NULL; 345 d->lircThread = new LircThread(this); 346 if (!d->lircThread->Init(config_file, "mythtv")) 347 d->lircThread->start(); 348 #endif 335 StartLIRC(); 349 336 350 337 #ifdef USE_JOYSTICK_MENU 351 338 d->ignore_joystick_keys = false; … … 449 436 #ifdef USE_LIRC 450 437 if (d->lircThread) 451 438 { 452 if (d->lircThread->isRunning()) 453 { 454 d->lircThread->Stop(); 455 d->lircThread->wait(); 456 } 457 458 delete d->lircThread; 439 d->lircThread->deleteLater(); 459 440 d->lircThread = NULL; 460 441 } 461 442 #endif … … 1762 1743 return d->uiScreenRect; 1763 1744 } 1764 1745 1746 void MythMainWindow::StartLIRC(void) 1747 { 1748 #ifdef USE_LIRC 1749 if (d->lircThread) 1750 { 1751 d->lircThread->deleteLater(); 1752 d->lircThread = NULL; 1753 } 1754 1755 QString config_file = GetConfDir() + "/lircrc"; 1756 if (!QFile::exists(config_file)) 1757 config_file = QDir::homePath() + "/.lircrc"; 1758 1759 d->lircThread = new LIRC( 1760 this, 1761 GetMythDB()->GetSetting("LircSocket", "/dev/lircd"), 1762 "mythtv", config_file, 1763 GetMythDB()->GetSetting("LircKeyPressedApp", "")); 1764 1765 if (d->lircThread->Init()) 1766 { 1767 d->lircThread->start(); 1768 } 1769 else 1770 { 1771 d->lircThread->deleteLater(); 1772 d->lircThread = NULL; 1773 } 1774 #endif 1775 } 1776 1765 1777 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
libs/libmythui/lirc.cpp
1 // System headers 2 #include <lirc/lirc_client.h> 3 4 // C headers 5 #include <cstdio> 6 #include <cerrno> 7 #include <cstdlib> 8 9 // C++ headers 10 #include <algorithm> 11 #include <vector> 12 using namespace std; 13 14 // Qt headers 1 15 #include <QApplication> 2 16 #include <QEvent> 3 17 #include <QKeySequence> 18 #include <QStringList> 4 19 5 #include <cstdio> 6 #include <cerrno> 7 #include <sys/wait.h> 8 #include <sys/types.h> 9 #include <unistd.h> 10 #include <stdlib.h> 11 20 // MythTV headers 12 21 #include "mythverbose.h" 13 22 #include "mythdb.h" 14 23 #include "mythsystem.h" 15 16 24 #include "lirc.h" 17 25 #include "lircevent.h" 18 26 19 LircThread::LircThread(QObject *main_window) 27 // POSIX headers 28 namespace POSIX 29 { 30 #include <sys/types.h> 31 #include <sys/socket.h> 32 #include <sys/select.h> 33 #include <sys/un.h> 34 #include <netinet/in.h> 35 #include <arpa/inet.h> 36 #include <netdb.h> 37 #include <unistd.h> 38 #include <fcntl.h> 39 #include <sys/wait.h> 40 }; 41 using namespace POSIX; 42 43 #define LOC QString("LIRC: ") 44 #define LOC_WARN QString("LIRC, Warning: ") 45 #define LOC_ERR QString("LIRC, Error: ") 46 47 class LIRCPriv 48 { 49 public: 50 LIRCPriv() : lircConfig(NULL) {} 51 ~LIRCPriv() 52 { 53 if (lircConfig) 54 { 55 lirc_freeconfig(lircConfig); 56 lircConfig = NULL; 57 } 58 } 59 60 struct lirc_config *lircConfig; 61 }; 62 63 QMutex LIRC::lirclib_lock; 64 65 /** \class LIRC 66 * \brief Interface between mythtv and lircd 67 * 68 * Create connection to the lircd daemon and translate remote keypresses 69 * into custom events which are posted to the mainwindow. 70 */ 71 72 LIRC::LIRC(QObject *main_window, 73 const QString &lircd_device, 74 const QString &our_program, 75 const QString &config_file, 76 const QString &external_app) 20 77 : QThread(), 21 m_lircConfig(NULL), m_mainWindow(main_window), 22 m_bStop(false), m_fd(-1), 23 m_externalApp("") 78 lock(QMutex::Recursive), 79 m_mainWindow(main_window), 80 lircdDevice(lircd_device), 81 program(our_program), 82 configFile(config_file), 83 m_externalApp(external_app), 84 doRun(false), 85 lircd_socket(-1), 86 buf_offset(0), 87 eofCount(0), 88 retryCount(0), 89 d(new LIRCPriv()) 24 90 { 91 lircdDevice.detach(); 92 program.detach(); 93 configFile.detach(); 94 m_externalApp.detach(); 95 buf.resize(128); 25 96 } 97 98 LIRC::~LIRC() 99 { 100 TeardownAll(); 101 } 26 102 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) 103 void LIRC::deleteLater(void) 33 104 { 34 /* Connect the unix socket */ 35 m_fd = lirc_init((char *)qPrintable(program), 1); 36 if (m_fd == -1) 105 TeardownAll(); 106 QThread::deleteLater(); 107 } 108 109 void LIRC::TeardownAll(void) 110 { 111 QMutexLocker locker(&lock); 112 if (doRun) 37 113 { 38 VERBOSE(VB_IMPORTANT,39 QString("lirc_init failed for %1, see preceding messages")40 .arg(program));41 return -1;114 doRun = false; 115 lock.unlock(); 116 wait(); 117 lock.lock(); 42 118 } 119 120 if (lircd_socket >= 0) 121 { 122 close(lircd_socket); 123 lircd_socket = -1; 124 } 125 126 if (d) 127 { 128 delete d; 129 d = NULL; 130 } 131 } 132 133 QByteArray get_ip(const QString &h) 134 { 135 QByteArray hba = h.toLatin1(); 136 struct in_addr sin_addr; 137 if (inet_aton(hba.constData(), &sin_addr)) 138 return hba; 139 140 struct addrinfo hints; 141 memset(&hints, 0, sizeof(hints)); 142 hints.ai_family = AF_INET; 143 hints.ai_socktype = SOCK_STREAM; 144 hints.ai_protocol = IPPROTO_TCP; 145 146 struct addrinfo *result; 147 int err = getaddrinfo(hba.constData(), NULL, &hints, &result); 148 if (err) 149 { 150 VERBOSE(VB_IMPORTANT, QString("get_ip: %1").arg(gai_strerror(err))); 151 return QString("").toLatin1(); 152 } 43 153 44 /* parse the config file */45 if ( lirc_readconfig((char *)qPrintable(config_file), &m_lircConfig, NULL))154 int addrlen = result->ai_addrlen; 155 if (!addrlen) 46 156 { 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; 157 freeaddrinfo(result); 158 return QString("").toLatin1(); 52 159 } 53 160 54 if (!ignoreExtApp) 55 m_externalApp = GetMythDB()->GetSetting("LircKeyPressedApp", ""); 161 if (result->ai_addr->sa_family != AF_INET) 162 { 163 freeaddrinfo(result); 164 return QString("").toLatin1(); 165 } 56 166 57 VERBOSE(VB_GENERAL,58 QString("lirc init success using configuration file: %1")59 .arg(config_file));167 sin_addr = ((struct sockaddr_in*)(result->ai_addr))->sin_addr; 168 hba = QByteArray(inet_ntoa(sin_addr)); 169 freeaddrinfo(result); 60 170 61 return 0;171 return hba; 62 172 } 173 174 bool LIRC::Init(void) 175 { 176 QMutexLocker locker(&lock); 177 if (lircd_socket >= 0) 178 return true; 179 180 if (lircdDevice.startsWith('/')) 181 { 182 // Connect the unix socket 183 QByteArray dev = lircdDevice.toLocal8Bit(); 184 if (dev.size() > 107) 185 { 186 VERBOSE(VB_IMPORTANT, LOC_ERR + QString("lircdDevice '%1'") 187 .arg(lircdDevice) + 188 " is too long for the 'unix' socket API"); 189 190 return false; 191 } 192 193 lircd_socket = socket(AF_UNIX, SOCK_STREAM, 0); 194 if (lircd_socket < 0) 195 { 196 VERBOSE(VB_IMPORTANT, LOC_ERR + 197 QString("Failed to open Unix socket '%1'") 198 .arg(lircdDevice) + ENO); 199 200 return false; 201 } 202 203 struct sockaddr_un addr; 204 memset(&addr, 0, sizeof(sockaddr_un)); 205 addr.sun_family = AF_UNIX; 206 strncpy(addr.sun_path, dev.constData(),107); 63 207 64 LircThread::~LircThread() 65 { 66 lirc_deinit(); 67 if (m_lircConfig) 68 lirc_freeconfig(m_lircConfig); 208 int ret = POSIX::connect( 209 lircd_socket, (struct sockaddr*) &addr, sizeof(addr)); 210 211 if (ret < 0) 212 { 213 VERBOSE(VB_IMPORTANT, LOC_ERR + 214 QString("Failed to connect to Unix socket '%1'") 215 .arg(lircdDevice) + ENO); 216 217 close(lircd_socket); 218 lircd_socket = -1; 219 return false; 220 } 221 } 222 else 223 { 224 lircd_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 225 if (lircd_socket < 0) 226 { 227 VERBOSE(VB_IMPORTANT, LOC_ERR + 228 QString("Failed to open TCP socket '%1'") 229 .arg(lircdDevice) + ENO); 230 231 return false; 232 } 233 234 QString dev = lircdDevice; 235 uint port = 8765; 236 QStringList tmp = lircdDevice.split(':'); 237 if (2 == tmp.size()) 238 { 239 dev = tmp[0]; 240 port = (tmp[1].toUInt()) ? tmp[1].toUInt() : port; 241 } 242 QByteArray device = get_ip(dev); 243 struct sockaddr_in addr; 244 memset(&addr, 0, sizeof(sockaddr_in)); 245 addr.sin_family = AF_INET; 246 addr.sin_port = htons(port); 247 248 if (!inet_aton(device.constData(), &addr.sin_addr)) 249 { 250 VERBOSE(VB_IMPORTANT, LOC_ERR + 251 QString("Failed to parse IP address '%1'").arg(dev)); 252 253 close(lircd_socket); 254 lircd_socket = -1; 255 return false; 256 } 257 258 int ret = POSIX::connect( 259 lircd_socket, (struct sockaddr*) &addr, sizeof(addr)); 260 if (ret < 0) 261 { 262 VERBOSE(VB_IMPORTANT, LOC_ERR + 263 QString("Failed to connect TCP socket '%1'") 264 .arg(lircdDevice) + ENO); 265 266 close(lircd_socket); 267 lircd_socket = -1; 268 return false; 269 } 270 271 // On Linux, select() can indicate data when there isn't 272 // any due to TCP checksum in-particular; to avoid getting 273 // stuck on a read() call add the O_NONBLOCK flag. 274 int flags = fcntl(lircd_socket, F_GETFD); 275 if (flags >= 0) 276 { 277 ret = fcntl(lircd_socket, F_SETFD, flags | O_NONBLOCK); 278 if (ret < 0) 279 { 280 VERBOSE(VB_IMPORTANT, LOC_WARN + 281 QString("Failed set flags for socket '%1'") 282 .arg(lircdDevice) + ENO); 283 } 284 } 285 286 // Attempt to inline out-of-band messages and keep the connection open.. 287 int i = 1; 288 setsockopt(lircd_socket, SOL_SOCKET, SO_OOBINLINE, &i, sizeof(i)); 289 i = 1; 290 setsockopt(lircd_socket, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i)); 291 } 292 293 // parse the config file 294 if (!d->lircConfig) 295 { 296 QMutexLocker static_lock(&lirclib_lock); 297 QByteArray cfg = configFile.toLocal8Bit(); 298 if (lirc_readconfig( 299 const_cast<char*>(cfg.constData()), &d->lircConfig, NULL)) 300 { 301 VERBOSE(VB_IMPORTANT, LOC_ERR + 302 QString("Failed to read config file '%1'").arg(configFile)); 303 304 close(lircd_socket); 305 lircd_socket = -1; 306 return false; 307 } 308 309 // Get rid of the stuff we don't care about.. 310 vector<struct lirc_config_entry*> del; 311 struct lirc_config_entry *it = d->lircConfig->first; 312 while (it->next) 313 { 314 if (program == QString(it->next->prog)) 315 { 316 it = it->next; 317 } 318 else 319 { 320 del.push_back(it->next); 321 it->next = it->next->next; 322 } 323 } 324 if (program != QString(d->lircConfig->first->prog)) 325 { 326 del.push_back(d->lircConfig->first); 327 d->lircConfig->first = d->lircConfig->first->next; 328 } 329 d->lircConfig->next = d->lircConfig->first; 330 331 for (uint i = 0; i < del.size(); i++) 332 { 333 struct lirc_config_entry *c = del[i]; 334 if (c->prog) 335 free(c->prog); 336 if (c->change_mode) 337 free(c->change_mode); 338 if (c->mode) 339 free(c->mode); 340 341 struct lirc_code *code = c->code; 342 while (code) 343 { 344 if (code->remote && code->remote!=LIRC_ALL) 345 free(code->remote); 346 if (code->button && code->button!=LIRC_ALL) 347 free(code->button); 348 struct lirc_code *code_temp = code->next; 349 free(code); 350 code = code_temp; 351 } 352 353 struct lirc_list *list = c->config; 354 while (list) 355 { 356 if (list->string) 357 free(list->string); 358 struct lirc_list *list_temp = list->next; 359 free(list); 360 list = list_temp; 361 } 362 363 free(c); 364 } 365 } 366 367 VERBOSE(VB_GENERAL, LOC + 368 QString("Successfully initialized '%1' using '%2' config") 369 .arg(lircdDevice).arg(configFile)); 370 371 return true; 69 372 } 70 373 71 /** 72 * \brief Main thread loop 73 */ 74 void LircThread::run(void) 374 void LIRC::start(void) 75 375 { 76 char *code = 0; 77 char *ir = 0; 78 int ret; 79 fd_set readfds; 80 struct timeval timeout; 376 QMutexLocker locker(&lock); 81 377 82 /* Process all events read */ 83 while (!m_bStop) 378 if (lircd_socket < 0) 84 379 { 85 FD_ZERO(&readfds); 86 FD_SET(m_fd, &readfds); 380 VERBOSE(VB_IMPORTANT, LOC_ERR + "start() called without lircd socket"); 381 return; 382 } 87 383 88 // the maximum time select() should wait89 timeout.tv_sec = 0;90 timeout.tv_usec = 100000; 384 doRun = true; 385 QThread::start(); 386 } 91 387 92 ret = select(m_fd + 1, &readfds, NULL, NULL, &timeout); 388 bool LIRC::IsDoRunSet(void) const 389 { 390 QMutexLocker locker(&lock); 391 return doRun; 392 } 93 393 94 if (ret == 0) 95 continue; 394 void LIRC::Process(const QByteArray &data) 395 { 396 QMutexLocker static_lock(&lirclib_lock); 96 397 97 if (ret == -1) 398 // lirc_code2char will make code point to a static datafer.. 399 char *code = NULL; 400 int ret = lirc_code2char( 401 d->lircConfig, const_cast<char*>(data.constData()), &code); 402 403 while ((0 == ret) && code) 404 { 405 QString text(code); 406 QKeySequence a(code); 407 408 int keycode = 0; 409 410 // Send a dummy keycode if we couldn't convert the key sequence. 411 // This is done so the main code can output a warning for bad 412 // mappings. 413 if (!a.count()) 98 414 { 99 perror("LircThread - select");100 return;415 QApplication::postEvent( 416 m_mainWindow, new LircKeycodeEvent(text, keycode, true)); 101 417 } 102 418 103 if (ret == 1)419 for (unsigned int i = 0; i < a.count(); i++) 104 420 { 105 ret = lirc_nextcode(&ir);421 keycode = a[i]; 106 422 107 if (ret == -1) 423 QApplication::postEvent( 424 m_mainWindow, new LircKeycodeEvent(text, keycode, true)); 425 QApplication::postEvent( 426 m_mainWindow, new LircKeycodeEvent(text, keycode, false)); 427 428 SpawnApp(); 429 } 430 ret = lirc_code2char( 431 d->lircConfig, const_cast<char*>(data.constData()), &code); 432 } 433 } 434 435 void LIRC::run(void) 436 { 437 //VERBOSE(VB_GENERAL, LOC + "run -- start"); 438 /* Process all events read */ 439 while (IsDoRunSet()) 440 { 441 if (eofCount && retryCount) 442 usleep(100 * 1000); 443 444 if ((eofCount >= 10) || (lircd_socket < 0)) 445 { 446 QMutexLocker locker(&lock); 447 eofCount = 0; 448 if (++retryCount > 1000) 108 449 { 109 if (errno != 0) 110 VERBOSE(VB_IMPORTANT, 111 QString("LircThread: lirc_nextcode failed" 112 "last error was: %1").arg(errno)); 113 return; 450 VERBOSE(VB_IMPORTANT, LOC_ERR + 451 "Failed to reconnect, exiting LIRC thread."); 452 doRun = false; 453 continue; 114 454 } 455 VERBOSE(VB_GENERAL, LOC_WARN + "EOF -- reconnecting"); 456 457 close(lircd_socket); 458 lircd_socket = -1; 115 459 116 if (! ir)117 continue;460 if (!Init()) 461 sleep(2); // wait a while before we retry.. 118 462 119 while ((ret = lirc_code2char(m_lircConfig, ir, &code)) == 0 && 120 code != NULL) 121 { 122 QKeySequence a(code); 463 continue; 464 } 123 465 124 int keycode = 0; 466 fd_set readfds; 467 FD_ZERO(&readfds); 468 FD_SET(lircd_socket, &readfds); 125 469 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)); 470 // the maximum time select() should wait 471 struct timeval timeout; 472 timeout.tv_sec = 1; // 1 second 473 timeout.tv_usec = 100 * 1000; // 100 ms 133 474 134 for (unsigned int i = 0; i < a.count(); i++) 135 { 136 keycode = a[i]; 475 int ret = select(lircd_socket + 1, &readfds, NULL, NULL, &timeout); 137 476 138 QApplication::postEvent(m_mainWindow, 139 new LircKeycodeEvent(code, keycode, 140 true)); 141 QApplication::postEvent(m_mainWindow, 142 new LircKeycodeEvent(code, keycode, 143 false)); 477 if (ret < 0 && errno != EINTR) 478 { 479 VERBOSE(VB_IMPORTANT, LOC_ERR + "select() failed" + ENO); 480 continue; 481 } 144 482 145 SpawnApp(); 146 } 147 } 483 // 0: Timer expired with no data, repeat select 484 // -1: Iinterrupted while waiting, repeat select 485 if (ret <= 0) 486 continue; 148 487 149 free(ir); 150 if (ret == -1) 151 break; 488 QList<QByteArray> codes = GetCodes(); 489 for (uint i = 0; i < (uint) codes.size(); i++) 490 Process(codes[i]); 491 } 492 //VERBOSE(VB_GENERAL, LOC + "run -- end"); 493 } 494 495 QList<QByteArray> LIRC::GetCodes(void) 496 { 497 QList<QByteArray> ret; 498 ssize_t len = -1; 499 500 while (true) 501 { 502 len = read(lircd_socket, 503 buf.data() + buf_offset, 504 buf.size() - buf_offset - 1); 505 506 if (len >= 0) 507 break; 508 509 if (EINTR == errno) 510 continue; 511 else if (EAGAIN == errno) 512 return ret; 513 else if (107 == errno) 514 { 515 if (!eofCount) 516 VERBOSE(VB_GENERAL, LOC + "GetCodes -- EOF?"); 517 eofCount++; 518 return ret; 152 519 } 520 else 521 { 522 VERBOSE(VB_IMPORTANT, LOC + "Error reading socket" + ENO); 523 return ret; 524 } 525 526 break; 153 527 } 528 529 if (0 == len) 530 { 531 if (!eofCount) 532 VERBOSE(VB_GENERAL, LOC + "GetCodes -- eof?"); 533 eofCount++; 534 return ret; 535 } 536 537 eofCount = 0; 538 retryCount = 0; 539 540 buf_offset += len; 541 if ((uint)buf.size() < buf_offset + 128) 542 buf.reserve(buf.size() * 2); 543 uint tmpc = std::max(buf.capacity() - 1,128); 544 545 buf.resize(buf_offset); 546 ret = buf.split('\n'); 547 buf.resize(tmpc); 548 if (buf.endsWith('\n')) 549 { 550 buf_offset = 0; 551 return ret; 552 } 553 554 buf = ret.back(); 555 ret.pop_back(); 556 buf_offset = std::max(buf.size() - 1, 0); 557 buf.resize(tmpc); 558 559 return ret; 154 560 } 155 561 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) 562 void LIRC::SpawnApp(void) 161 563 { 564 // Spawn app to illuminate led (or what ever the user has picked if 565 // anything) to give positive feedback that a key was received 162 566 if (m_externalApp.isEmpty()) 163 567 return; 164 568 -
libs/libmythui/lircevent.h
47 47 void unlock(); 48 48 49 49 private: 50 bool m_eventsLocked;50 bool events_locked; 51 51 }; 52 52 53 53 #endif -
libs/libmythui/mythmainwindow.h
95 95 int NormY(const int y); 96 96 int fonTweak; 97 97 98 void StartLIRC(void); 99 98 100 /* compatability functions, to go away once everything's mythui */ 99 101 void attach(QWidget *child); 100 102 void detach(QWidget *child); -
libs/libmythui/lircevent.cpp
4 4 #include "mythmainwindow.h" 5 5 #include "lircevent.h" 6 6 7 LircEventLock::LircEventLock(bool lock_events) 8 : m_eventsLocked(false)7 LircEventLock::LircEventLock(bool lock_events) 8 : events_locked(false) 9 9 { 10 10 if (lock_events) 11 11 lock(); … … 13 13 14 14 LircEventLock::~LircEventLock() 15 15 { 16 if ( m_eventsLocked)16 if (events_locked) 17 17 unlock(); 18 18 } 19 19 … … 22 22 MythMainWindow *mw = GetMythMainWindow(); 23 23 if (mw) 24 24 { 25 m_eventsLocked = true;25 events_locked = true; 26 26 QApplication::postEvent((QObject *)mw, 27 new LircMuteEvent( m_eventsLocked));27 new LircMuteEvent(events_locked)); 28 28 } 29 29 } 30 30 … … 33 33 MythMainWindow *mw = GetMythMainWindow(); 34 34 if (mw) 35 35 { 36 m_eventsLocked = false;36 events_locked = false; 37 37 QApplication::postEvent((QObject *)mw, 38 new LircMuteEvent( m_eventsLocked));38 new LircMuteEvent(events_locked)); 39 39 } 40 40 } -
programs/mythfrontend/globalsettings.cpp
2313 2313 return ge; 2314 2314 } 2315 2315 2316 static HostLineEdit *LircDaemonDevice() 2317 { 2318 HostLineEdit *ge = new HostLineEdit("LircSocket"); 2319 ge->setLabel(QObject::tr("LIRC Daemon Socket")); 2320 ge->setValue("/dev/lircd"); 2321 QString help = QObject::tr( 2322 "UNIX socket or IP address[:port] to connect in " 2323 "order to communicate with the LIRC Daemon."); 2324 ge->setHelpText(help); 2325 return ge; 2326 } 2327 2316 2328 static HostLineEdit *LircKeyPressedApp() 2317 2329 { 2318 2330 HostLineEdit *ge = new HostLineEdit("LircKeyPressedApp"); 2319 ge->setLabel(QObject::tr(" Keypress Application"));2331 ge->setLabel(QObject::tr("LIRC Keypress Application")); 2320 2332 ge->setValue(""); 2321 2333 ge->setHelpText(QObject::tr("External application or script to run when " 2322 2334 "a keypress is received by LIRC.")); … … 2326 2338 static HostLineEdit *ScreenShotPath() 2327 2339 { 2328 2340 HostLineEdit *ge = new HostLineEdit("ScreenShotPath"); 2329 ge->setLabel(QObject::tr("Screen ShotPath"));2341 ge->setLabel(QObject::tr("Screen Shot Path")); 2330 2342 ge->setValue("/tmp/"); 2331 2343 ge->setHelpText(QObject::tr("Path to screenshot storage location. Should be writable by the frontend")); 2332 2344 return ge; … … 4630 4642 general->setLabel(QObject::tr("General")); 4631 4643 general->addChild(UseArrowAccels()); 4632 4644 general->addChild(EnableXbox()); 4633 general->addChild(LircKeyPressedApp());4634 4645 general->addChild(ScreenShotPath()); 4635 general->addChild(NetworkControlEnabled());4636 general->addChild(NetworkControlPort());4637 4646 addChild(general); 4638 4647 4639 4648 VerticalConfigurationGroup *media = … … 4660 4669 exit->addChild(shutdownSettings); 4661 4670 addChild(exit); 4662 4671 4672 VerticalConfigurationGroup *remotecontrol = 4673 new VerticalConfigurationGroup(false, true, false, false); 4674 remotecontrol->setLabel(QObject::tr("Remote Control")); 4675 remotecontrol->addChild(LircDaemonDevice()); 4676 remotecontrol->addChild(LircKeyPressedApp()); 4677 remotecontrol->addChild(NetworkControlEnabled()); 4678 remotecontrol->addChild(NetworkControlPort()); 4679 addChild(remotecontrol); 4680 4663 4681 MythLogSettings *mythlog = new MythLogSettings(); 4664 4682 addChild(mythlog); 4665 4683 -
programs/mythfrontend/main.cpp
806 806 gContext->ActivateSettingsCache(true); 807 807 } 808 808 809 void signal_USR2_handler(int) 810 { 811 VERBOSE(VB_GENERAL, "SIG USR2 received, restart LIRC handler"); 812 GetMythMainWindow()->StartLIRC(); 813 } 814 815 809 816 int internal_media_init() 810 817 { 811 818 REG_MEDIAPLAYER("Internal", "MythTV's native media player.", … … 1341 1348 1342 1349 // Setup handler for USR1 signals to reload theme 1343 1350 signal(SIGUSR1, &signal_USR1_handler); 1351 // Setup handler for USR2 signals to restart LIRC 1352 signal(SIGUSR2, &signal_USR2_handler); 1344 1353 1345 1354 qApp->exec(); 1346 1355