Ticket #4075: backend-autoselect-3.patch
File backend-autoselect-3.patch, 46.3 KB (added by , 16 years ago) |
---|
-
configure
1562 1562 enable appleremote 1563 1563 enable backend 1564 1564 enable darwin 1565 enable dvdv 1565 1566 disable ivtv 1566 1567 disable need_memalign 1567 1568 disable opengl_video … … 2141 2142 echo "" 2142 2143 fi 2143 2144 fi 2145 ## similar for Mac OS X (Intel Macs currently require SSE) 2146 #if test $targetos = darwin; then 2147 # if ! check_header "CoreServices/CoreServices.h" $ARCHFLAGS ; then 2148 # echo "ERROR: Flags '$ARCHFLAGS' failed compile test. Removing" 2149 # ARCHFLAGS="" 2150 # fi 2151 #fi 2144 2152 2145 2153 2146 2154 enabled vis && add_cflags "-mcpu=ultrasparc -mtune=ultrasparc" -
libs/libmythtv/libmythtv.pro
508 508 inc.files = programinfo.h remoteutil.h recordingtypes.h 509 509 510 510 INSTALLS += inc 511 512 CONFIG += debug -
libs/libmythui/mythmainwindow.cpp
1108 1108 { 1109 1109 QKeyEvent *ke = dynamic_cast<QKeyEvent*>(e); 1110 1110 1111 // Work around weird GCC bug. Only manifest on Mac OS X 1112 if (!ke) 1113 ke = (QKeyEvent *)e; 1114 1111 1115 if (currentWidget()) 1112 1116 { 1113 1117 ke->accept(); -
libs/libmythui/myththemedmenu.cpp
2238 2238 */ 2239 2239 bool MythThemedMenuPrivate::handleAction(const QString &action) 2240 2240 { 2241 printf("MythThemedMenuPrivate::handleAction(%s)\n", action.ascii()); 2241 2242 if (action.left(5) == "EXEC ") 2242 2243 { 2243 2244 QString rest = action.right(action.length() - 5); … … 2333 2334 else if (action.left(5) == "JUMP ") 2334 2335 { 2335 2336 QString rest = action.right(action.length() - 5); 2337 printf("JUMPing to %s\n", rest.ascii()); 2336 2338 GetMythMainWindow()->JumpTo(rest, false); 2337 2339 } 2338 2340 else -
libs/libmyth/dbsettings.cpp
6 6 7 7 class MythDbSettings1: public VerticalConfigurationGroup { 8 8 public: 9 MythDbSettings1( );9 MythDbSettings1(const QString &DBhostOverride = QString::null); 10 10 11 11 void load(); 12 12 void save(); … … 20 20 TransLineEditSetting *dbUserName; 21 21 TransLineEditSetting *dbPassword; 22 22 TransComboBoxSetting *dbType; 23 24 QString m_DBhostOverride; 23 25 }; 24 26 25 27 class MythDbSettings2: public VerticalConfigurationGroup { … … 71 73 } 72 74 }; 73 75 74 MythDbSettings1::MythDbSettings1( ) :76 MythDbSettings1::MythDbSettings1(const QString &DbHostOverride) : 75 77 VerticalConfigurationGroup(false, true, false, false) 76 78 { 79 m_DBhostOverride = DbHostOverride; 80 77 81 setLabel(QObject::tr("Database Configuration") + " 1/2"); 78 82 79 83 info = new TransLabelSetting(); … … 236 240 info->setValue(info->getValue() + "\nRequired fields are marked " 237 241 "with an asterisk (*)."); 238 242 239 dbHostName->setValue(params.dbHostName);240 243 if (params.dbHostName.isEmpty()) 244 { 241 245 dbHostName->setLabel("* " + dbHostName->getLabel()); 246 dbHostName->setValue(m_DBhostOverride); 247 } 248 else 249 dbHostName->setValue(params.dbHostName); 242 250 243 251 dbHostPing->setValue(params.dbHostPing); 244 252 … … 304 312 gContext->SaveDatabaseParams(params); 305 313 } 306 314 307 DatabaseSettings::DatabaseSettings( )315 DatabaseSettings::DatabaseSettings(const QString &DBhostOverride) 308 316 { 309 addChild(new MythDbSettings1( ));317 addChild(new MythDbSettings1(DBhostOverride)); 310 318 addChild(new MythDbSettings2()); 311 319 } 312 320 -
libs/libmyth/dbsettings.h
5 5 6 6 class MPUBLIC DatabaseSettings: public ConfigurationWizard { 7 7 public: 8 DatabaseSettings( );8 DatabaseSettings(const QString &DBhostOverride = QString::null); 9 9 10 10 // This routine calls wizard->addChild() for each of 11 11 // the database configuration screens. This allows -
libs/libmyth/mythcontext.cpp
27 27 #include "mythplugin.h" 28 28 #include "screensaver.h" 29 29 #include "DisplayRes.h" 30 #include "backendselect.h" 30 31 #include "dbsettings.h" 31 32 #include "langsettings.h" 32 33 #include "mythdbcon.h" … … 35 36 #include "themeinfo.h" 36 37 37 38 #include "libmythui/mythmainwindow.h" 39 #include "libmythupnp/mythxmlclient.h" 40 #include "libmythupnp/upnp.h" 38 41 39 42 // These defines provide portability for different 40 43 // plugin file names. … … 55 58 56 59 QMutex avcodeclock(true); 57 60 61 // Some common UPnP search and XML value strings 62 const QString kDefaultPIN = "UPnP/MythFrontend/DefaultBackend/SecurityPin"; 63 const QString kDefaultUSN = "UPnP/MythFrontend/DefaultBackend/USN"; 64 const QString gBackendURI = "urn:schemas-mythtv-org:device:MasterMediaServer:1"; 65 66 58 67 int parse_verbose_arg(QString arg) 59 68 { 60 69 QString option; … … 190 199 } 191 200 } 192 201 202 193 203 class MythContextPrivate 194 204 { 195 205 public: 196 206 MythContextPrivate(MythContext *lparent); 197 207 ~MythContextPrivate(); 198 208 199 bool Init(bool gui, DatabaseParams *pParams = NULL ); 200 bool FindDatabase(const DatabaseParams *pParams); 209 bool Init (const bool gui, UPnp *UPnPclient, 210 const bool prompt, const bool noPrompt); 211 bool FindDatabase(const bool prompt, const bool noPrompt); 201 212 202 213 bool IsWideMode() const {return (m_baseWidth == 1280);} 203 214 void SetWideMode() {m_baseWidth = 1280; m_baseHeight = 720;} … … 211 222 void StoreGUIsettings(void); 212 223 213 224 void LoadLogSettings(void); 214 bool LoadDatabaseSettings(const DatabaseParams *pParams = NULL);225 void LoadDatabaseSettings(void); 215 226 216 227 bool LoadSettingsFile(void); 217 228 bool WriteSettingsFile(const DatabaseParams ¶ms, … … 220 231 221 232 QString getResponse(const QString &query, const QString &def); 222 233 int intResponse(const QString &query, int def); 223 bool PromptForDatabaseParams( QStringerror);234 bool PromptForDatabaseParams(const QString &error); 224 235 QString TestDBconnection(void); 225 236 void ResetDatabase(void); 226 237 238 bool InitUPnP(void); 239 void CleanUPnP(void); 240 int ChooseBackend(const QString &error); 241 int UPnPautoconf(const int milliSeconds = 2000); 242 bool DefaultUPnP(QString &error); 243 bool UPnPconnect(const DeviceLocation *device, const QString &PIN); 227 244 245 228 246 MythContext *parent; 229 247 230 248 Settings *m_settings; ///< connection stuff, theme, button style … … 257 275 QString m_localhostname; ///< hostname from mysql.txt or gethostname() 258 276 259 277 DatabaseParams m_DBparams; ///< Current database host & WOL details 278 QString m_DBhostCp; ///< dbHostName backup 260 279 280 UPnp *m_UPnP; ///< For automatic backend discover 281 XmlConfiguration *m_XML; 282 HttpServer *m_HTTP; 283 261 284 QMutex serverSockLock; 262 285 bool attemptingToConnect; 263 286 … … 322 345 m_xbase(0), m_ybase(0), m_height(0), m_width(0), 323 346 m_baseWidth(800), m_baseHeight(600), 324 347 m_localhostname(QString::null), 348 m_UPnP(NULL), m_XML(NULL), m_HTTP(NULL), 325 349 serverSockLock(false), 326 350 attemptingToConnect(false), 327 351 language(""), … … 350 374 { 351 375 imageCache.clear(); 352 376 377 CleanUPnP(); 353 378 if (m_settings) 354 379 delete m_settings; 355 380 if (m_qtThemeSettings) … … 378 403 */ 379 404 void MythContextPrivate::TempMainWindow(bool languagePrompt) 380 405 { 406 if (mainWindow) 407 return; 408 409 // We clear the hostname so MSqlQuery will fail, instead of long 410 // timeouts per DB value, or hundreds of lines of DB connect errors. 411 // We save the value for later possible editing in the DbSettings pages 412 if (m_DBparams.dbHostName.length()) 413 { 414 m_DBhostCp = m_DBparams.dbHostName; 415 m_DBparams.dbHostName = ""; 416 } 417 381 418 m_settings->SetSetting("Theme", "blue"); 382 419 #ifdef Q_WS_MACX 383 420 // Myth looks horrible in default Mac style for Qt … … 482 519 } 483 520 } 484 521 485 bool MythContextPrivate::Init(bool gui, DatabaseParams *pParams) 522 bool MythContextPrivate::Init(const bool gui, UPnp *UPnPclient, 523 const bool promptForBackend, const bool noPrompt) 486 524 { 487 525 m_gui = gui; 526 if (UPnPclient) 527 { 528 m_UPnP = UPnPclient; 529 m_XML = (XmlConfiguration *)UPnp::g_pConfig; 530 } 488 531 489 532 // Creates screen saver control if we will have a GUI 490 533 if (gui) … … 492 535 493 536 // ---- database connection stuff ---- 494 537 495 if (!FindDatabase(p Params))538 if (!FindDatabase(promptForBackend, noPrompt)) 496 539 return false; 497 540 498 541 // ---- keep all DB-using stuff below this line ---- … … 508 551 509 552 /** 510 553 * Get database connection settings and test connectivity. 554 * 555 * Can use UPnP AutoDiscovery to locate backends, and get their DB settings. 556 * The user can force the AutoDiscovery chooser with the --prompt argument, 557 * and disable it by using the --disable-autodiscovery argument. 558 * There is also an autoconfigure function, which counts the backends, 559 * and if there is exactly one, uses it as above. 560 * 561 * Despite its name, the disable argument currently only disables the chooser. 562 * If set, autoconfigure will still be attempted in some situations. 511 563 */ 512 bool MythContextPrivate::FindDatabase(const DatabaseParams *pParams)564 bool MythContextPrivate::FindDatabase(const bool prompt, const bool noPrompt) 513 565 { 514 // Attempts to read DB info from "mysql.txt" from the 515 // filesystem, or create it if it does not exist. 516 if (!LoadDatabaseSettings(pParams)) 517 return false; 566 // The two bool. args actually form a Yes/Maybe/No (A tristate bool :-) 567 bool manualSelect = prompt && !noPrompt; 518 568 519 // Attempt to connect to the database, get message for user if it failed.520 QString failure = TestDBconnection();569 // In addition to the UI chooser, we can also try to autoconfigure 570 bool autoSelect = !manualSelect; 521 571 572 QString failure; 573 574 575 // 1. Load either mysql.txt, or use sensible "localhost" defaults: 576 LoadDatabaseSettings(); 577 578 579 // 2. If the user isn't forcing up the chooser UI, look for a default 580 // backend in config.xml, then test DB settings we've got so far: 581 if (!manualSelect) 582 { 583 // config.xml may contain a backend host UUID and PIN. 584 // If so, try to AutoDiscover UPnP server, and use its DB settings: 585 586 if (DefaultUPnP(failure)) // Probably a valid backend, 587 autoSelect = manualSelect = false; // so disable any further UPnP 588 else 589 VERBOSE(VB_IMPORTANT, failure); 590 591 failure = TestDBconnection(); 592 if (failure.isEmpty()) 593 goto DBfound; 594 } 595 596 597 // 3. Try to automatically find the single backend: 598 if (autoSelect) 599 { 600 int count = UPnPautoconf(); 601 602 if (count == 0) 603 failure = "No UPnP backends found"; 604 605 if (count == 1) 606 { 607 failure = TestDBconnection(); 608 if (failure.isEmpty()) 609 goto DBfound; 610 } 611 612 if (count > 1 || count == -1) // Multiple BEs, or needs PIN. 613 manualSelect = !noPrompt; // If allowed, prompt user 614 } 615 616 if (!m_gui) 617 manualSelect = false; // no interactive command-line chooser yet 618 619 620 621 // Last, get the user to select a backend from a possible list: 622 if (manualSelect) 623 { 624 switch (ChooseBackend(QString::null)) 625 { 626 case -1: // User asked to configure database manually 627 if (PromptForDatabaseParams("")) 628 break; 629 else 630 goto NoDBfound; // User cancelled - changed their mind? 631 632 case 0: // User cancelled. Exit application 633 goto NoDBfound; 634 635 case 1: // User selected a backend, so m_DBparams 636 break; // should now contain the database details 637 638 default: 639 goto NoDBfound; 640 } 641 failure = TestDBconnection(); 642 } 643 644 522 645 // Queries the user for the DB info, using the command 523 646 // line or the GUI depending on the application. 524 647 while (failure.length()) 525 648 { 526 649 VERBOSE(VB_IMPORTANT, failure); 527 if (PromptForDatabaseParams(failure)) 650 if (( manualSelect && ChooseBackend(failure)) || 651 (!manualSelect && PromptForDatabaseParams(failure))) 528 652 { 529 653 failure = TestDBconnection(); 530 654 if (failure.length()) 531 655 VERBOSE(VB_IMPORTANT, failure); 532 656 } 533 657 else 534 return false;658 goto NoDBfound; 535 659 } 536 660 661 DBfound: 662 //VERBOSE(VB_GENERAL, "FindDatabase() - Success!"); 663 ResetDatabase(); 664 CleanUPnP(); 537 665 return true; 666 667 NoDBfound: 668 //VERBOSE(VB_GENERAL, "FindDatabase() - failed"); 669 CleanUPnP(); 670 return false; 538 671 } 539 672 540 673 /** … … 610 743 } 611 744 612 745 /** 613 * Load database and host settings from mysql.txt and UPnP BE discovery. 614 * 615 * \note Creating a default mysql.txt is actually not necessary. 616 * The defaults are enough for a simple "localhost" FE & MBE, 617 * and UPnP covers the other situations. 746 * Load database and host settings from mysql.txt, or set some defaults 747 * 748 * \returns true if mysql.txt was parsed 618 749 */ 619 bool MythContextPrivate::LoadDatabaseSettings(const DatabaseParams *pParams)750 void MythContextPrivate::LoadDatabaseSettings(void) 620 751 { 621 // Always load settings first from mysql.txt so LocalHostName can be used.622 623 752 if (!LoadSettingsFile()) 624 753 { 625 754 VERBOSE(VB_IMPORTANT, "Unable to read configuration file mysql.txt"); … … 638 767 m_DBparams.wolReconnect = 0; 639 768 m_DBparams.wolRetry = 5; 640 769 m_DBparams.wolCommand = "echo 'WOLsqlServerCommand not set'"; 641 642 VERBOSE(VB_IMPORTANT, "Trying to create a basic mysql.txt file");643 if (!WriteSettingsFile(m_DBparams))644 return false;645 770 } 646 771 647 // Overlay mysql.txt settings if we were passed a DatabaseParams648 649 if (pParams != NULL)650 {651 m_DBparams.dbHostName = pParams->dbHostName;652 m_DBparams.dbPort = pParams->dbPort;653 m_DBparams.dbUserName = pParams->dbUserName;654 m_DBparams.dbPassword = pParams->dbPassword;655 m_DBparams.dbName = pParams->dbName;656 m_DBparams.dbType = pParams->dbType;657 //m_DBparams.wolEnabled = pParams->wolEnabled;658 m_DBparams.wolReconnect = pParams->wolReconnect;659 m_DBparams.wolRetry = pParams->wolRetry;660 m_DBparams.wolCommand = pParams->wolCommand;661 }662 663 772 // Even if we have loaded the settings file, it may be incomplete, 664 773 // so we check for missing values and warn user 665 774 FindSettingsProbs(); … … 673 782 { 674 783 VERBOSE(VB_IMPORTANT, 675 784 "MCP: Error, could not determine host name." + ENO); 676 return false;785 localhostname[0] = '\0'; 677 786 } 678 787 m_localhostname = localhostname; 679 788 VERBOSE(VB_IMPORTANT, "Empty LocalHostName."); 680 789 } 681 790 VERBOSE(VB_GENERAL, "Using localhost value of " + m_localhostname); 682 683 return true;684 791 } 685 792 686 793 /** … … 889 996 return (ok ? resp : def); 890 997 } 891 998 892 bool MythContextPrivate::PromptForDatabaseParams( QStringerror)999 bool MythContextPrivate::PromptForDatabaseParams(const QString &error) 893 1000 { 894 1001 bool accepted = false; 895 1002 if (m_gui) … … 901 1008 MythPopupBox::showOkPopup(mainWindow, "DB connect failure", error); 902 1009 903 1010 // ask user for database parameters 904 DatabaseSettings settings ;1011 DatabaseSettings settings(m_DBhostCp); 905 1012 accepted = (settings.exec() == QDialog::Accepted); 906 1013 if (!accepted) 907 VERBOSE(VB_IMPORTANT, "User cancel ed database configuration");1014 VERBOSE(VB_IMPORTANT, "User cancelled database configuration"); 908 1015 909 1016 EndTempWindow(); 910 1017 } … … 986 1093 VERBOSE(VB_GENERAL, "Testing network connectivity to " + host); 987 1094 if (doPing && !ping(host, 3)) // Fail after trying for 3 seconds 988 1095 { 1096 // Save, to display in DatabaseSettings screens 1097 m_DBhostCp = m_DBparams.dbHostName; 1098 989 1099 // Cause MSqlQuery to fail, instead of minutes timeout per DB value 990 1100 m_DBparams.dbHostName = ""; 991 1101 … … 998 1108 999 1109 if (port && !telnet(host, port)) 1000 1110 { 1001 // Cause MSqlQuery to fail, instead of several error lines per DB value1002 m_DBparams.dbHostName = "";1003 1004 1111 err = parent->tr("Cannot connect to port %1 on database host %2"); 1005 1112 return err.arg(port).arg(host); 1006 1113 } … … 1009 1116 // 3. Finally, try to login, et c: 1010 1117 1011 1118 if (!MSqlQuery::testDBConnection()) 1012 {1013 // Cause MSqlQuery to fail, instead of several error lines per DB value1014 m_DBparams.dbHostName = "";1015 1016 1119 return parent->tr(QString("Cannot login to database?")); 1017 }1018 1120 1019 1121 1020 1122 return QString::null; … … 1038 1140 } 1039 1141 1040 1142 1143 bool MythContextPrivate::InitUPnP(void) 1144 { 1145 if (m_UPnP) 1146 return true; 1147 1148 VERBOSE(VB_UPNP, "Setting UPnP client for backend autodiscovery..."); 1149 1150 if (!m_XML) 1151 m_XML = new XmlConfiguration(""); // No file - use defaults only 1152 1153 m_UPnP = new UPnp(); 1154 m_UPnP->SetConfiguration(m_XML); 1155 1156 int port=6549; 1157 m_HTTP = new HttpServer(port); 1158 1159 if (!m_HTTP->ok()) 1160 { 1161 VERBOSE(VB_IMPORTANT, "MCP::InitUPnP() - HttpServer Create Error"); 1162 CleanUPnP(); 1163 return false; 1164 } 1165 1166 if (!m_UPnP->Initialize(port, m_HTTP)) 1167 { 1168 VERBOSE(VB_IMPORTANT, "MCP::InitUPnP() - UPnp::Initialize() Error"); 1169 CleanUPnP(); 1170 return false; 1171 } 1172 1173 m_UPnP->Start(); 1174 1175 return true; 1176 } 1177 1178 void MythContextPrivate::CleanUPnP(void) 1179 { 1180 if (m_UPnP && !m_HTTP) // Init was passed an existing UPnP 1181 return; // so let the caller delete it cleanly 1182 1183 if (m_UPnP) 1184 { 1185 // This takes a few seconds, so inform the user: 1186 VERBOSE(VB_GENERAL, "Deleting UPnP client..."); 1187 1188 delete m_UPnP; // This also deletes m_XML 1189 m_UPnP = NULL; 1190 m_XML = NULL; 1191 } 1192 1193 if (m_HTTP) 1194 { 1195 delete m_HTTP; 1196 m_HTTP = NULL; 1197 } 1198 } 1199 1200 /** 1201 * Search for backends via UPnP, put up a UI for the user to choose one 1202 */ 1203 int MythContextPrivate::ChooseBackend(const QString &error) 1204 { 1205 if (!InitUPnP()) 1206 return -1; 1207 1208 TempMainWindow(); 1209 1210 // Tell the user what went wrong: 1211 if (error.length()) 1212 MythPopupBox::showOkPopup(mainWindow, "DB connect failure", error); 1213 1214 VERBOSE(VB_GENERAL, "Putting up the UPnP backend chooser"); 1215 1216 BackendSelect *BEsel = new BackendSelect(mainWindow, &m_DBparams); 1217 switch (BEsel->exec()) 1218 { 1219 case kDialogCodeRejected: 1220 VERBOSE(VB_IMPORTANT, "User canceled database configuration"); 1221 return 0; 1222 1223 case kDialogCodeButton0: 1224 VERBOSE(VB_IMPORTANT, "User requested Manual Config"); 1225 return -1; 1226 } 1227 BEsel->hide(); 1228 //BEsel->deleteLater(); 1229 1230 QStringList buttons; 1231 QString message; 1232 1233 buttons += QObject::tr("Save database details"); 1234 buttons += QObject::tr("Save backend details"); 1235 buttons += QObject::tr("Don't Save"); 1236 1237 message = parent->tr("Save that backend or database as the default?"); 1238 1239 DialogCode selected = MythPopupBox::ShowButtonPopup( 1240 mainWindow, "Save default", message, buttons, kDialogCodeButton2); 1241 switch (selected) 1242 { 1243 case kDialogCodeButton0: 1244 WriteSettingsFile(m_DBparams, true); 1245 break; 1246 case kDialogCodeButton1: 1247 if (BEsel->m_PIN.length()) 1248 m_XML->SetValue(kDefaultPIN, BEsel->m_PIN); 1249 m_XML->SetValue(kDefaultUSN, BEsel->m_USN); 1250 m_XML->Save(); 1251 break; 1252 } 1253 1254 delete BEsel; 1255 EndTempWindow(); 1256 1257 return 1; 1258 } 1259 1260 /** 1261 * If there is only a single UPnP backend, use it. 1262 * 1263 * This does <i>not</i> prompt for PIN entry. If the backend requires one, 1264 * it will fail, and the caller needs to put up a UI to ask for one. 1265 */ 1266 int MythContextPrivate::UPnPautoconf(const int milliSeconds) 1267 { 1268 if (!InitUPnP()) 1269 return 0; 1270 1271 SSDPCacheEntries *backends = NULL; 1272 int count; 1273 QString LOC = "UPnPautoconf() - "; 1274 QTime timer; 1275 1276 m_UPnP->PerformSearch(gBackendURI); 1277 for (timer.start(); timer.elapsed() < milliSeconds; usleep(25000)) 1278 { 1279 backends = m_UPnP->g_SSDPCache.Find(gBackendURI); 1280 if (backends) 1281 { 1282 backends->AddRef(); 1283 break; 1284 } 1285 putchar('.'); 1286 } 1287 putchar('\n'); 1288 1289 if (!backends) 1290 { 1291 VERBOSE(VB_GENERAL, LOC + "No UPnP backends found"); 1292 return 0; 1293 } 1294 1295 1296 // This could be tied to VB_UPNP? 1297 //m_UPnP->g_SSDPCache.Dump(); 1298 1299 1300 count = backends->Count(); 1301 switch (count) 1302 { 1303 case 0: 1304 VERBOSE(VB_IMPORTANT, 1305 LOC + "No UPnP backends found, but SSDP::Find() not NULL!"); 1306 break; 1307 case 1: 1308 VERBOSE(VB_GENERAL, LOC + "Found one UPnP backend"); 1309 break; 1310 default: 1311 VERBOSE(VB_GENERAL, 1312 (LOC + "More than one UPnP backend found (%1)").arg(count)); 1313 } 1314 1315 if (count != 1) 1316 { 1317 backends->Release(); 1318 return count; 1319 } 1320 1321 1322 // Get this backend's location: 1323 backends->Lock(); 1324 DeviceLocation *BE = backends->GetEntryMap()->begin().data(); 1325 backends->Unlock(); 1326 backends->Release(); 1327 1328 // We don't actually know the backend's access PIN, so this will 1329 // only work for ones that have PIN access disabled (i.e. 0000) 1330 if (UPnPconnect(BE, QString::null)) 1331 return 1; 1332 1333 return -1; // Try to force chooser & PIN 1334 } 1335 1336 /** 1337 * Get the default backend from config.xml, use UPnP to find it. 1338 * 1339 * Sets a string if there any connection problems 1340 */ 1341 bool MythContextPrivate::DefaultUPnP(QString &error) 1342 { 1343 XmlConfiguration *XML = new XmlConfiguration("config.xml"); 1344 QString loc = "MCP::DefaultUPnP() - "; 1345 QString PIN = XML->GetValue(kDefaultPIN, ""); 1346 QString USN = XML->GetValue(kDefaultUSN, ""); 1347 1348 delete XML; 1349 1350 if (USN.isEmpty()) 1351 { 1352 VERBOSE(VB_UPNP, loc + "No default UPnP backend"); 1353 return false; 1354 } 1355 1356 VERBOSE(VB_UPNP, loc + "config.xml has default PIN '" 1357 + PIN + "' and host USN: " + USN); 1358 1359 if (!InitUPnP()) 1360 { 1361 error = "UPnP is broken?"; 1362 return false; 1363 } 1364 1365 m_UPnP->PerformSearch(gBackendURI); 1366 DeviceLocation *pDevLoc = m_UPnP->g_SSDPCache.Find(gBackendURI, USN); 1367 if (!pDevLoc) 1368 { 1369 error = "Cannot find default UPnP backend"; 1370 return false; 1371 1372 } 1373 1374 if (UPnPconnect(pDevLoc, PIN)) 1375 return true; 1376 1377 error = "Cannot connect to defalt backend via UPnP. Wrong saved PIN?"; 1378 return false; 1379 } 1380 1381 /** 1382 * Query a backend via UPnP for its database connection parameters 1383 */ 1384 bool MythContextPrivate::UPnPconnect(const DeviceLocation *backend, 1385 const QString &PIN) 1386 { 1387 QString error; 1388 QString LOC = "UPnPconnect() - "; 1389 QString URL = backend->m_sLocation; 1390 MythXMLClient XML(URL); 1391 1392 VERBOSE(VB_UPNP, LOC + "Trying host at " + URL); 1393 switch (XML.GetConnectionInfo(PIN, &m_DBparams, error)) 1394 { 1395 case UPnPResult_Success: 1396 break; 1397 1398 case UPnPResult_ActionNotAuthorized: 1399 // The stored PIN is probably not correct. 1400 // We could prompt for the PIN and try again, but that needs a UI. 1401 // Easier to fail for now, and put up the full UI selector later 1402 VERBOSE(VB_UPNP, LOC + error + ". Wrong PIN?"); 1403 return false; 1404 1405 default: 1406 VERBOSE(VB_UPNP, LOC + error); 1407 return false; 1408 } 1409 1410 QString DBhost = m_DBparams.dbHostName; 1411 VERBOSE(VB_UPNP, LOC + "Got database hostname: " + DBhost); 1412 1413 return true; 1414 } 1415 1416 1041 1417 MythContext::MythContext(const QString &binversion) 1042 1418 : QObject(), d(NULL), app_binary_version(binversion) 1043 1419 { … … 1046 1422 d = new MythContextPrivate(this); 1047 1423 } 1048 1424 1049 bool MythContext::Init(bool gui, DatabaseParams *pParams ) 1425 bool MythContext::Init(const bool gui, UPnp *UPnPclient, 1426 const bool promptForBackend, 1427 const bool disableAutoDiscovery) 1050 1428 { 1051 1429 if (app_binary_version != MYTH_BINARY_VERSION) 1052 1430 { … … 1062 1440 d->TempMainWindow(false); 1063 1441 MythPopupBox::showOkPopup(d->mainWindow, 1064 1442 "Library version error", warning); 1065 SetMainWindow(NULL); 1066 DestroyMythMainWindow(); 1443 d->EndTempWindow(); 1067 1444 } 1068 1445 VERBOSE(VB_IMPORTANT, warning); 1069 1446 1070 1447 return false; 1071 1448 } 1072 1449 1073 if (!d->Init(gui, pParams))1450 if (!d->Init(gui, UPnPclient, promptForBackend, disableAutoDiscovery)) 1074 1451 return false; 1075 1452 1076 1453 ActivateSettingsCache(true); … … 2101 2478 .arg(err.databaseText()); 2102 2479 } 2103 2480 2104 /**2105 * \todo Remove MythContext::settings() - it is not used anywhere?2106 */2107 Settings *MythContext::settings(void)2108 {2109 return d->m_settings;2110 }2111 2112 2481 Settings *MythContext::qtconfig(void) 2113 2482 { 2114 2483 return d->m_qtThemeSettings; -
libs/libmyth/mythcontext.h
39 39 class DisplayRes; 40 40 class MDBManager; 41 41 class MythContextPrivate; 42 class UPnp; 42 43 43 44 /// This MAP is for the various VERBOSITY flags, used to select which 44 45 /// messages we want printed to the console. … … 248 249 MythContext(const QString &binversion); 249 250 virtual ~MythContext(); 250 251 251 bool Init(bool gui = true, DatabaseParams *pParams = NULL ); 252 bool Init(const bool gui = true, 253 UPnp *UPnPclient = NULL, 254 const bool promptForBackend = false, 255 const bool bypassAutoDiscovery = false); 252 256 253 257 QString GetMasterHostPrefix(void); 254 258 … … 334 338 void LogEntry(const QString &module, int priority, 335 339 const QString &message, const QString &details); 336 340 337 Settings *settings(void);338 341 Settings *qtconfig(void); 339 342 340 343 void SaveSetting(const QString &key, int newValue); … … 463 466 MYTH_SCHEMA_USE_EXISTING = 4 464 467 }; 465 468 469 /// Service type for the backend's UPnP server 470 extern MPUBLIC const QString gBackendURI; 471 466 472 #endif 467 473 468 474 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
libs/libmyth/libmyth.pro
16 16 HEADERS += mythdialogs.h audiooutput.h httpcomms.h mythmedia.h mythmediamonitor.h 17 17 HEADERS += uilistbtntype.h generictree.h screensaver.h 18 18 HEADERS += managedlist.h DisplayRes.h volumebase.h audiooutputbase.h 19 HEADERS += dbsettings.h screensaver-null.h output.h visual.h19 HEADERS += backendselect.h dbsettings.h screensaver-null.h output.h visual.h 20 20 HEADERS += langsettings.h audiooutputnull.h mythsocket.h 21 21 HEADERS += DisplayResScreen.h util-x11.h mythdeque.h qmdcodec.h 22 22 HEADERS += exitcodes.h virtualkeyboard.h mythobservable.h mythevent.h … … 30 30 SOURCES += httpcomms.cpp mythmedia.cpp mythmediamonitor.cpp uilistbtntype.cpp 31 31 SOURCES += generictree.cpp managedlist.cpp DisplayRes.cpp 32 32 SOURCES += volumecontrol.cpp volumebase.cpp audiooutputbase.cpp 33 SOURCES += dbsettings.cpp screensaver.cpp screensaver-null.cpp output.cpp33 SOURCES += backendselect.cpp dbsettings.cpp screensaver.cpp screensaver-null.cpp output.cpp 34 34 SOURCES += langsettings.cpp mythdbcon.cpp audiooutputnull.cpp 35 35 SOURCES += DisplayResScreen.cpp util-x11.cpp qmdcodec.cpp 36 36 SOURCES += virtualkeyboard.cpp mythobservable.cpp mythsocket.cpp themeinfo.cpp … … 38 38 39 39 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ 40 40 DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui 41 DEPENDPATH += ../libmythupnp 41 42 42 43 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION} 43 44 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION} … … 111 112 QMAKE_CXXFLAGS += -F/System/Library/Frameworks/$${FC}.framework/Frameworks 112 113 LIBS += -framework $$join(FWKS," -framework ") 113 114 114 # There is a dependence on some stuff in libmythui .115 # There is a dependence on some stuff in libmythui and libmythupnp. 115 116 # It isn't built yet, so we have to ignore these for now: 116 117 QMAKE_LFLAGS_SHLIB += -flat_namespace -undefined warning 117 118 -
libs/libmyth/mythmediamonitor.cpp
59 59 return c_monitor; 60 60 61 61 #ifdef USING_DARWIN_DA 62 62 c_monitor = new MediaMonitorDarwin(NULL, 500, true); 63 63 #else 64 64 #if defined(CONFIG_CYGWIN) || defined(_WIN32) 65 65 c_monitor = new MediaMonitorWindows(NULL, 500, true); 66 66 #else 67 67 c_monitor = new MediaMonitorUnix(NULL, 500, true); 68 68 #endif 69 69 #endif 70 70 -
libs/libmyth/backendselect.h
1 #ifndef __BACKENDSELECT_H__ 2 #define __BACKENDSELECT_H__ 3 4 #include "mythdialogs.h" 5 #include "mythwidgets.h" 6 7 #include "libmythupnp/upnpdevice.h" 8 9 class ListBoxDevice : public QListBoxText 10 { 11 public: 12 13 ListBoxDevice(QListBox *list, const QString &name, DeviceLocation *dev) 14 : QListBoxText(list, name) 15 { 16 if ((m_dev = dev) != NULL) 17 m_dev->AddRef(); 18 } 19 20 virtual ~ListBoxDevice() 21 { 22 if (m_dev != NULL) 23 m_dev->Release(); 24 } 25 26 DeviceLocation *m_dev; 27 }; 28 29 typedef QMap< QString, ListBoxDevice *> ItemMap; 30 31 32 class BackendSelect : public MythDialog 33 { 34 Q_OBJECT 35 36 public: 37 BackendSelect(MythMainWindow *parent, DatabaseParams *params); 38 virtual ~BackendSelect(); 39 40 void customEvent(QCustomEvent *e); 41 42 QString m_PIN; 43 QString m_USN; 44 45 46 public slots: 47 48 void FillListBox(void); 49 void Manual (void); ///< Linked to 'Configure Manually' button 50 void Search (void); 51 void Select (void); ///< Linked to the OK button 52 53 54 protected: 55 56 void AddItem(DeviceLocation *dev); 57 bool Connect(DeviceLocation *dev); 58 void RemoveItem(QString URN); 59 60 DatabaseParams *m_DBparams; 61 ItemMap m_devices; 62 QGridLayout *m_layout; 63 MythMainWindow *m_parent; 64 65 QListBox *m_Backends; 66 MythPushButton *m_Cancel; 67 MythPushButton *m_Manual; 68 MythPushButton *m_OK; 69 //MythPushButton *m_Search; 70 }; 71 72 #endif -
libs/libmyth/backendselect.cpp
Property changes on: libs/libmyth/backendselect.h ___________________________________________________________________ Name: svn:keywords + Date Revision Author Name: svn:eol-style + native
1 /** 2 * \class BackendSelect 3 * \desc Classes to Prompt user for a master backend. 4 * 5 * \author Originally based on masterselection.cpp/h by David Blain. 6 */ 7 8 #include "backendselect.h" 9 #include "mythdialogs.h" 10 11 #include "libmythupnp/mythxmlclient.h" 12 13 14 BackendSelect::BackendSelect(MythMainWindow *parent, DatabaseParams *params) 15 : MythDialog(parent, "BackEnd Selection", TRUE) 16 { 17 m_parent = parent; 18 m_DBparams = params; 19 20 //setFocusPolicy(QWidget::NoFocus); 21 22 // We should use MythListBox, but it doesn't do returnPressed() 23 m_Backends = new QListBox(this); 24 //m_Backends->setFrameShape(QFrame::WinPanel); 25 //m_Backends->setSelectionMode(QListBox::Single); 26 27 m_OK = new MythPushButton(tr("OK"), this); 28 m_Cancel = new MythPushButton(tr("Cancel"), this); 29 //m_Search = new MythPushButton(tr("Search"), this); 30 m_Manual = new MythPushButton(tr("Configure Manually"), this); 31 32 m_layout = new QGridLayout(this, 7, 5, 6); 33 34 m_layout->setMargin(50); 35 36 QString labeltext = tr("Select Default Myth Backend Server:"); 37 m_layout->addMultiCellWidget(new QLabel(labeltext, this), 1, 1, 0, 4); 38 m_layout->addMultiCellWidget(m_Backends, 3, 3, 0, 4); 39 m_layout->addMultiCellWidget(m_Manual, 5, 5, 0, 1); 40 //m_layout->addWidget(m_Search, 5, 0); 41 //m_layout->addWidget(m_Manual, 5, 1); 42 m_layout->addWidget(m_Cancel, 5, 3); 43 m_layout->addWidget(m_OK , 5, 4); 44 45 connect(m_OK , SIGNAL(clicked()), SLOT(Select())); 46 connect(m_Cancel, SIGNAL(clicked()), SLOT(reject())); 47 //connect(m_Search, SIGNAL(clicked()), SLOT(Search())); 48 connect(m_Manual, SIGNAL(clicked()), SLOT(Manual())); 49 connect(m_Backends, SIGNAL(returnPressed(QListBoxItem *)), SLOT(Select())); 50 51 UPnp::AddListener(this); 52 53 Search(); 54 FillListBox(); // Not necessary - custom events will fill it 55 56 //m_Backends->setFocus(); 57 } 58 59 BackendSelect::~BackendSelect() 60 { 61 UPnp::RemoveListener(this); 62 63 ItemMap::iterator it; 64 for (it = m_devices.begin(); it != m_devices.end(); ++it) 65 { 66 ListBoxDevice *item = it.data(); 67 68 if (item != NULL) 69 delete item; 70 } 71 72 m_devices.clear(); 73 } 74 75 void BackendSelect::AddItem(DeviceLocation *dev) 76 { 77 if (!dev) 78 return; 79 80 QString USN = dev->m_sUSN; 81 82 // The devices' USN should be unique. Don't add if it is already there: 83 if (m_devices.find(USN) == m_devices.end()) 84 { 85 ListBoxDevice *item; 86 QString name; 87 88 if (print_verbose_messages & VB_UPNP) 89 name = dev->GetNameAndDetails(true); 90 else 91 name = dev->GetFriendlyName(true); 92 93 item = new ListBoxDevice(m_Backends, name, dev); 94 m_devices.insert(USN, item); 95 96 m_Backends->setFocus(); 97 } 98 99 dev->Release(); 100 } 101 102 void BackendSelect::RemoveItem(QString USN) 103 { 104 ItemMap::iterator it = m_devices.find(USN); 105 106 if (it != m_devices.end()) 107 { 108 ListBoxDevice *item = it.data(); 109 110 if (item != NULL) 111 delete item; 112 113 m_devices.remove(it); 114 } 115 } 116 117 void BackendSelect::Select(void) 118 { 119 DeviceLocation *dev; 120 QListBoxItem *selected; 121 122 switch (m_Backends->numRows()) 123 { 124 case 0: 125 return; 126 case 1: 127 m_Backends->setSelected(0, true); // Hard for user to select, 128 selected = m_Backends->item(0); // so we do it for them 129 break; 130 default: 131 selected = m_Backends->selectedItem(); 132 } 133 134 if (!selected) 135 return; 136 137 138 dev = ((ListBoxDevice *)selected)->m_dev; 139 140 if (!dev) 141 reject(); 142 143 dev->AddRef(); 144 if (Connect(dev)) 145 accept(); 146 } 147 148 void BackendSelect::Manual(void) 149 { 150 done(kDialogCodeButton0); 151 } 152 153 void BackendSelect::Search(void) 154 { 155 UPnp::PerformSearch(gBackendURI); 156 } 157 158 bool BackendSelect::Connect(DeviceLocation *dev) 159 { 160 QString error; 161 QString message; 162 UPnPResultCode stat; 163 MythXMLClient *xml; 164 165 m_USN = dev->m_sUSN; 166 xml = new MythXMLClient(dev->m_sLocation); 167 stat = xml->GetConnectionInfo(m_PIN, m_DBparams, message); 168 error = dev->GetFriendlyName(true); 169 if (error == "<Unknown>") 170 error = dev->m_sLocation; 171 error += ". " + message; 172 dev->Release(); 173 174 switch (stat) 175 { 176 case UPnPResult_Success: 177 VERBOSE(VB_UPNP, "Connect() - success. New hostname: " 178 + m_DBparams->dbHostName); 179 return true; 180 181 case UPnPResult_HumanInterventionRequired: 182 VERBOSE(VB_UPNP, error); 183 MythPopupBox::showOkPopup(m_parent, "", QObject::tr(message)); 184 break; 185 186 case UPnPResult_ActionNotAuthorized: 187 VERBOSE(VB_UPNP, "Access denied for " + error + ". Wrong PIN?"); 188 message = "Please enter the backend access PIN"; 189 do 190 { 191 m_PIN = MythPopupBox::showPasswordPopup( 192 m_parent, "Backend PIN entry", QObject::tr(message)); 193 stat = xml->GetConnectionInfo(m_PIN, m_DBparams, message); 194 } 195 while (stat == UPnPResult_ActionNotAuthorized); 196 if (stat == UPnPResult_Success) 197 return true; 198 199 default: 200 VERBOSE(VB_UPNP, "GetConnectionInfo() failed for " + error); 201 MythPopupBox::showOkPopup(m_parent, "", QObject::tr(message)); 202 } 203 204 // Back to the list, so the user can choose a different backend: 205 m_Backends->setFocus(); 206 return false; 207 } 208 209 void BackendSelect::FillListBox(void) 210 { 211 EntryMap::Iterator it; 212 EntryMap ourMap; 213 SSDPCacheEntries *entries = UPnp::g_SSDPCache.Find(gBackendURI); 214 215 if (entries != NULL) 216 { 217 entries->AddRef(); 218 entries->Lock(); 219 220 EntryMap *map = entries->GetEntryMap(); 221 222 for (it = map->begin(); it != map->end(); ++it) 223 { 224 DeviceLocation *dev = (DeviceLocation *)it.data(); 225 226 if (dev != NULL) 227 { 228 dev->AddRef(); 229 ourMap.insert(dev->m_sUSN, dev); 230 } 231 } 232 233 entries->Unlock(); 234 entries->Release(); 235 } 236 237 for (it = ourMap.begin(); it != ourMap.end(); ++it) 238 AddItem((DeviceLocation *)it.data()); 239 } 240 241 void BackendSelect::customEvent(QCustomEvent *e) 242 { 243 if (MythEvent::MythEventMessage != ((MythEvent::Type)(e->type()))) 244 return; 245 246 247 MythEvent *me = (MythEvent *)e; 248 QString message = me->Message(); 249 QString URI = me->ExtraData(0); 250 QString URN = me->ExtraData(1); 251 QString URL = me->ExtraData(2); 252 253 254 VERBOSE(VB_UPNP, "MasterSelectionDialog::customEvent(" + message 255 + ", " + URI + ", " + URN + ", " + URL + ")"); 256 257 if (message.startsWith("SSDP_ADD") && 258 URI.startsWith("urn:schemas-mythtv-org:device:MasterMediaServer:")) 259 { 260 DeviceLocation *devLoc = UPnp::g_SSDPCache.Find(URI, URN); 261 262 if (devLoc != NULL) 263 { 264 devLoc->AddRef(); 265 AddItem(devLoc); 266 } 267 } 268 else if (message.startsWith("SSDP_REMOVE")) 269 { 270 //-=>Note: This code will never get executed until 271 // SSDPCache is changed to handle NotifyRemove correctly 272 RemoveItem(URN); 273 } 274 } -
libs/libmythupnp/upnpdevice.h
Property changes on: libs/libmyth/backendselect.cpp ___________________________________________________________________ Name: svn:keywords + Date Revision Author Name: svn:eol-style + native
264 264 UPnpDeviceDesc *pDevice = GetDeviceDesc( bInQtThread ); 265 265 266 266 if ( pDevice == NULL) 267 return "<Unknown> ";267 return "<Unknown> (" + m_sLocation + ")"; 268 268 269 269 return pDevice->m_rootDevice.m_sFriendlyName 270 270 + " (" + pDevice->m_sHostName + "), " -
libs/libmythupnp/upnputil.cpp
47 47 48 48 UPnp::g_pConfig->SetValue( sName, sUDN ); 49 49 50 UPnp::g_pConfig->Save();50 //UPnp::g_pConfig->Save(); 51 51 } 52 52 53 53 return( sUDN ); -
libs/libmythupnp/upnp.cpp
144 144 { 145 145 VERBOSE(VB_UPNP, QString( "UPnp::UPnp:Starting SSDP Thread (Multicast)" )); 146 146 g_pSSDP->start(); 147 VERBOSE(VB_UPNP, QString( "Enabling Notifications" )); 147 148 g_pSSDP->EnableNotifications(); 148 149 } 149 150 } -
programs/mythfrontend/mediarenderer.cpp
117 117 if (m_pHttpServer) 118 118 delete m_pHttpServer; 119 119 } 120 121 /////////////////////////////////////////////////////////////////////////////122 // Caller MUST call Release on returned pointer123 /////////////////////////////////////////////////////////////////////////////124 125 DeviceLocation *MediaRenderer::GetDefaultMaster()126 {127 UPnp::PerformSearch( "urn:schemas-mythtv-org:device:MasterMediaServer:1" );128 129 QString sUSN = g_pConfig->GetValue( "UPnP/MythFrontend/DefaultBackend/USN" , "" );130 QString sPin = g_pConfig->GetValue( "UPnP/MythFrontend/DefaultBackend/SecurityPin", "" );131 132 if (sUSN.isEmpty())133 return NULL;134 135 DeviceLocation *pDeviceLoc = NULL;136 137 // Lets wait up to 2 seconds for the backend to answer our Search request;138 139 QTime timer;140 timer.start();141 142 while (timer.elapsed() < 2000 )143 {144 pDeviceLoc = UPnp::g_SSDPCache.Find( "urn:schemas-mythtv-org:device:MasterMediaServer:1",145 sUSN );146 147 if ( pDeviceLoc != NULL)148 {149 pDeviceLoc->AddRef();150 151 pDeviceLoc->m_sSecurityPin = sPin;152 153 return pDeviceLoc;154 }155 156 usleep(10000);157 }158 159 return NULL;160 }161 162 /////////////////////////////////////////////////////////////////////////////163 //164 /////////////////////////////////////////////////////////////////////////////165 166 void MediaRenderer::SetDefaultMaster( DeviceLocation *pDeviceLoc, const QString &sPin )167 {168 if ( pDeviceLoc != NULL)169 {170 pDeviceLoc->m_sSecurityPin = sPin;171 172 g_pConfig->SetValue( "UPnP/MythFrontend/DefaultBackend/USN" , pDeviceLoc->m_sUSN );173 g_pConfig->SetValue( "UPnP/MythFrontend/DefaultBackend/SecurityPin", sPin );174 g_pConfig->Save();175 }176 } -
programs/mythfrontend/main.cpp
53 53 #include "libmythui/myththemedmenu.h" 54 54 #include "libmythui/myththemebase.h" 55 55 #include "mediarenderer.h" 56 #include "masterselection.h"57 56 58 57 #define NO_EXIT 0 59 58 #define QUIT 1 … … 1059 1058 gContext = new MythContext(MYTH_BINARY_VERSION); 1060 1059 g_pUPnp = new MediaRenderer(); 1061 1060 1062 DatabaseParams *pParams = NULL; 1063 1064 if (!bBypassAutoDiscovery) 1061 if (!gContext->Init(true, g_pUPnp, bPromptForBackend, bBypassAutoDiscovery)) 1065 1062 { 1066 pParams = new DatabaseParams;1067 1068 int nRetCode = MasterSelection::GetConnectionInfo( g_pUPnp,1069 pParams,1070 bPromptForBackend );1071 switch( nRetCode )1072 {1073 case -1: // Exit Application1074 return FRONTEND_EXIT_OK;1075 1076 case 0: // Continue with no Connection Infomation1077 {1078 delete pParams;1079 pParams = NULL;1080 1081 break;1082 }1083 1084 case 1: // Connection Information found1085 default:1086 break;1087 }1088 }1089 1090 if (!gContext->Init( true, pParams ))1091 {1092 1063 VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting."); 1093 1064 return FRONTEND_EXIT_NO_MYTHCONTEXT; 1094 1065 } 1095 1066 1096 if (pParams != NULL)1097 {1098 delete pParams;1099 pParams = NULL;1100 }1101 1102 1067 for(int argpos = 1; argpos < a.argc(); ++argpos) 1103 1068 { 1104 1069 if (!strcmp(a.argv()[argpos],"-l") || … … 1480 1445 DestroyMythMainWindow(); 1481 1446 delete themeBase; 1482 1447 delete gContext; 1448 // This takes a few seconds, so inform the user: 1449 VERBOSE(VB_GENERAL, "Deleting UPnP client..."); 1483 1450 delete g_pUPnp; 1484 1451 1485 1452 return FRONTEND_EXIT_OK; -
programs/mythfrontend/mythfrontend.pro
26 26 HEADERS += manualbox.h playbackbox.h viewscheduled.h globalsettings.h 27 27 HEADERS += manualschedule.h programrecpriority.h channelrecpriority.h 28 28 HEADERS += statusbox.h networkcontrol.h custompriority.h 29 HEADERS += mediarenderer.h masterselection.h29 HEADERS += mediarenderer.h 30 30 31 31 SOURCES += main.cpp manualbox.cpp playbackbox.cpp viewscheduled.cpp 32 32 SOURCES += globalsettings.cpp manualschedule.cpp programrecpriority.cpp 33 33 SOURCES += channelrecpriority.cpp statusbox.cpp networkcontrol.cpp 34 SOURCES += mediarenderer.cpp masterselection.cpp34 SOURCES += mediarenderer.cpp 35 35 SOURCES += custompriority.cpp 36 36 37 37 macx { -
programs/mythbackend/mythxml.cpp
1471 1471 (sServerIP != "localhost") && 1472 1472 (sServerIP != sPeerIP )) 1473 1473 { 1474 VERBOSE(VB_IMPORTANT, "MythXML::GetConnectionInfo() - DBHostName of 'localhost' is inappropriate. Changing to " + sServerIP); 1474 1475 params.dbHostName = sServerIP; 1475 1476 } 1476 1477