Ticket #4075: backend-autoselect-3.patch

File backend-autoselect-3.patch, 46.3 KB (added by anonymous, 13 years ago)

Patch 2 was missing backendselect.cpp & h

  • configure

     
    15621562    enable  appleremote
    15631563    enable  backend
    15641564    enable  darwin
     1565    enable  dvdv
    15651566    disable ivtv
    15661567    disable need_memalign
    15671568    disable opengl_video
     
    21412142        echo ""
    21422143    fi
    21432144fi
     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
    21442152
    21452153
    21462154enabled vis && add_cflags "-mcpu=ultrasparc -mtune=ultrasparc"
  • libs/libmythtv/libmythtv.pro

     
    508508inc.files = programinfo.h remoteutil.h recordingtypes.h
    509509
    510510INSTALLS += inc
     511
     512CONFIG += debug
  • libs/libmythui/mythmainwindow.cpp

     
    11081108        {
    11091109            QKeyEvent *ke = dynamic_cast<QKeyEvent*>(e);
    11101110
     1111            // Work around weird GCC bug. Only manifest on Mac OS X
     1112            if (!ke)
     1113                ke = (QKeyEvent *)e;
     1114
    11111115            if (currentWidget())
    11121116            {
    11131117                ke->accept();
  • libs/libmythui/myththemedmenu.cpp

     
    22382238 */
    22392239bool MythThemedMenuPrivate::handleAction(const QString &action)
    22402240{
     2241printf("MythThemedMenuPrivate::handleAction(%s)\n", action.ascii());
    22412242    if (action.left(5) == "EXEC ")
    22422243    {
    22432244        QString rest = action.right(action.length() - 5);
     
    23332334    else if (action.left(5) == "JUMP ")
    23342335    {
    23352336        QString rest = action.right(action.length() - 5);
     2337printf("JUMPing to %s\n", rest.ascii());
    23362338        GetMythMainWindow()->JumpTo(rest, false);
    23372339    }
    23382340    else
  • libs/libmyth/dbsettings.cpp

     
    66
    77class MythDbSettings1: public VerticalConfigurationGroup {
    88public:
    9     MythDbSettings1();
     9    MythDbSettings1(const QString &DBhostOverride = QString::null);
    1010
    1111    void load();
    1212    void save();
     
    2020    TransLineEditSetting *dbUserName;
    2121    TransLineEditSetting *dbPassword;
    2222    TransComboBoxSetting *dbType;
     23
     24    QString              m_DBhostOverride;
    2325};
    2426
    2527class MythDbSettings2: public VerticalConfigurationGroup {
     
    7173    }
    7274};
    7375
    74 MythDbSettings1::MythDbSettings1() :
     76MythDbSettings1::MythDbSettings1(const QString &DbHostOverride) :
    7577    VerticalConfigurationGroup(false, true, false, false)
    7678{
     79    m_DBhostOverride = DbHostOverride;
     80
    7781    setLabel(QObject::tr("Database Configuration") + " 1/2");
    7882
    7983    info = new TransLabelSetting();
     
    236240        info->setValue(info->getValue() + "\nRequired fields are marked "
    237241                                          "with an asterisk (*).");
    238242
    239     dbHostName->setValue(params.dbHostName);
    240243    if (params.dbHostName.isEmpty())
     244    {
    241245        dbHostName->setLabel("* " + dbHostName->getLabel());
     246        dbHostName->setValue(m_DBhostOverride);
     247    }
     248    else
     249        dbHostName->setValue(params.dbHostName);
    242250
    243251    dbHostPing->setValue(params.dbHostPing);
    244252
     
    304312    gContext->SaveDatabaseParams(params);
    305313}
    306314
    307 DatabaseSettings::DatabaseSettings()
     315DatabaseSettings::DatabaseSettings(const QString &DBhostOverride)
    308316{
    309     addChild(new MythDbSettings1());
     317    addChild(new MythDbSettings1(DBhostOverride));
    310318    addChild(new MythDbSettings2());
    311319}
    312320
  • libs/libmyth/dbsettings.h

     
    55
    66class MPUBLIC DatabaseSettings: public ConfigurationWizard {
    77public:
    8     DatabaseSettings();
     8    DatabaseSettings(const QString &DBhostOverride = QString::null);
    99   
    1010    // This routine calls wizard->addChild() for each of
    1111    // the database configuration screens.  This allows
  • libs/libmyth/mythcontext.cpp

     
    2727#include "mythplugin.h"
    2828#include "screensaver.h"
    2929#include "DisplayRes.h"
     30#include "backendselect.h"
    3031#include "dbsettings.h"
    3132#include "langsettings.h"
    3233#include "mythdbcon.h"
     
    3536#include "themeinfo.h"
    3637
    3738#include "libmythui/mythmainwindow.h"
     39#include "libmythupnp/mythxmlclient.h"
     40#include "libmythupnp/upnp.h"
    3841
    3942// These defines provide portability for different
    4043// plugin file names.
     
    5558
    5659QMutex avcodeclock(true);
    5760
     61// Some common UPnP search and XML value strings
     62const QString kDefaultPIN = "UPnP/MythFrontend/DefaultBackend/SecurityPin";
     63const QString kDefaultUSN = "UPnP/MythFrontend/DefaultBackend/USN";
     64const QString gBackendURI = "urn:schemas-mythtv-org:device:MasterMediaServer:1";
     65
     66
    5867int parse_verbose_arg(QString arg)
    5968{
    6069    QString option;
     
    190199    }
    191200}
    192201
     202
    193203class MythContextPrivate
    194204{
    195205  public:
    196206    MythContextPrivate(MythContext *lparent);
    197207   ~MythContextPrivate();
    198208
    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);
    201212
    202213    bool IsWideMode() const {return (m_baseWidth == 1280);}
    203214    void SetWideMode() {m_baseWidth = 1280; m_baseHeight = 720;}
     
    211222    void StoreGUIsettings(void);
    212223
    213224    void LoadLogSettings(void);
    214     bool LoadDatabaseSettings(const DatabaseParams *pParams = NULL);
     225    void LoadDatabaseSettings(void);
    215226   
    216227    bool LoadSettingsFile(void);
    217228    bool WriteSettingsFile(const DatabaseParams &params,
     
    220231
    221232    QString getResponse(const QString &query, const QString &def);
    222233    int     intResponse(const QString &query, int def);
    223     bool    PromptForDatabaseParams(QString error);
     234    bool    PromptForDatabaseParams(const QString &error);
    224235    QString TestDBconnection(void);
    225236    void    ResetDatabase(void);
    226237
     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);
    227244
     245
    228246    MythContext *parent;
    229247
    230248    Settings *m_settings;          ///< connection stuff, theme, button style
     
    257275    QString m_localhostname;     ///< hostname from mysql.txt or gethostname()
    258276
    259277    DatabaseParams  m_DBparams;  ///< Current database host & WOL details
     278    QString         m_DBhostCp;  ///< dbHostName backup
    260279
     280    UPnp             *m_UPnP;    ///< For automatic backend discover
     281    XmlConfiguration *m_XML;
     282    HttpServer       *m_HTTP;
     283
    261284    QMutex serverSockLock;
    262285    bool attemptingToConnect;
    263286
     
    322345      m_xbase(0), m_ybase(0), m_height(0), m_width(0),
    323346      m_baseWidth(800), m_baseHeight(600),
    324347      m_localhostname(QString::null),
     348      m_UPnP(NULL), m_XML(NULL), m_HTTP(NULL),
    325349      serverSockLock(false),
    326350      attemptingToConnect(false),
    327351      language(""),
     
    350374{
    351375    imageCache.clear();
    352376
     377    CleanUPnP();
    353378    if (m_settings)
    354379        delete m_settings;
    355380    if (m_qtThemeSettings)
     
    378403 */
    379404void MythContextPrivate::TempMainWindow(bool languagePrompt)
    380405{
     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
    381418    m_settings->SetSetting("Theme", "blue");
    382419#ifdef Q_WS_MACX
    383420    // Myth looks horrible in default Mac style for Qt
     
    482519    }
    483520}
    484521
    485 bool MythContextPrivate::Init(bool gui, DatabaseParams *pParams)
     522bool MythContextPrivate::Init(const bool gui, UPnp *UPnPclient,
     523                              const bool promptForBackend, const bool noPrompt)
    486524{
    487525    m_gui = gui;
     526    if (UPnPclient)
     527    {
     528        m_UPnP = UPnPclient;
     529        m_XML  = (XmlConfiguration *)UPnp::g_pConfig;
     530    }
    488531
    489532    // Creates screen saver control if we will have a GUI
    490533    if (gui)
     
    492535
    493536    // ---- database connection stuff ----
    494537
    495     if (!FindDatabase(pParams))
     538    if (!FindDatabase(promptForBackend, noPrompt))
    496539        return false;
    497540
    498541    // ---- keep all DB-using stuff below this line ----
     
    508551
    509552/**
    510553 * 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.
    511563 */
    512 bool MythContextPrivate::FindDatabase(const DatabaseParams *pParams)
     564bool MythContextPrivate::FindDatabase(const bool prompt, const bool noPrompt)
    513565{
    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;
    518568
    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;
    521571
     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
    522645    // Queries the user for the DB info, using the command
    523646    // line or the GUI depending on the application.
    524647    while (failure.length())
    525648    {
    526649        VERBOSE(VB_IMPORTANT, failure);
    527         if (PromptForDatabaseParams(failure))
     650        if (( manualSelect && ChooseBackend(failure)) ||
     651            (!manualSelect && PromptForDatabaseParams(failure)))
    528652        {
    529653            failure = TestDBconnection();
    530654            if (failure.length())
    531655                VERBOSE(VB_IMPORTANT, failure);
    532656        }
    533657        else
    534             return false;
     658            goto NoDBfound;
    535659    }
    536660
     661DBfound:
     662    //VERBOSE(VB_GENERAL, "FindDatabase() - Success!");
     663    ResetDatabase();
     664    CleanUPnP();
    537665    return true;
     666
     667NoDBfound:
     668    //VERBOSE(VB_GENERAL, "FindDatabase() - failed");
     669    CleanUPnP();
     670    return false;
    538671}
    539672
    540673/**
     
    610743}
    611744
    612745/**     
    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
    618749 */
    619 bool MythContextPrivate::LoadDatabaseSettings(const DatabaseParams *pParams)
     750void MythContextPrivate::LoadDatabaseSettings(void)
    620751{
    621     // Always load settings first from mysql.txt so LocalHostName can be used.
    622 
    623752    if (!LoadSettingsFile())
    624753    {
    625754        VERBOSE(VB_IMPORTANT, "Unable to read configuration file mysql.txt");
     
    638767        m_DBparams.wolReconnect  = 0;
    639768        m_DBparams.wolRetry      = 5;
    640769        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;
    645770    }
    646771
    647     // Overlay mysql.txt settings if we were passed a DatabaseParams
    648 
    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 
    663772    // Even if we have loaded the settings file, it may be incomplete,
    664773    // so we check for missing values and warn user
    665774    FindSettingsProbs();
     
    673782        {
    674783            VERBOSE(VB_IMPORTANT,
    675784                    "MCP: Error, could not determine host name." + ENO);
    676             return false;
     785            localhostname[0] = '\0';
    677786        }
    678787        m_localhostname = localhostname;
    679788        VERBOSE(VB_IMPORTANT, "Empty LocalHostName.");
    680789    }
    681790    VERBOSE(VB_GENERAL, "Using localhost value of " + m_localhostname);
    682 
    683     return true;
    684791}
    685792
    686793/**
     
    889996    return (ok ? resp : def);
    890997}
    891998
    892 bool MythContextPrivate::PromptForDatabaseParams(QString error)
     999bool MythContextPrivate::PromptForDatabaseParams(const QString &error)
    8931000{
    8941001    bool accepted = false;
    8951002    if (m_gui)
     
    9011008            MythPopupBox::showOkPopup(mainWindow, "DB connect failure", error);
    9021009       
    9031010        // ask user for database parameters
    904         DatabaseSettings settings;
     1011        DatabaseSettings settings(m_DBhostCp);
    9051012        accepted = (settings.exec() == QDialog::Accepted);
    9061013        if (!accepted)
    907             VERBOSE(VB_IMPORTANT, "User canceled database configuration");
     1014            VERBOSE(VB_IMPORTANT, "User cancelled database configuration");
    9081015
    9091016        EndTempWindow();
    9101017    }
     
    9861093        VERBOSE(VB_GENERAL, "Testing network connectivity to " + host);
    9871094    if (doPing && !ping(host, 3))  // Fail after trying for 3 seconds
    9881095    {
     1096        // Save, to display in DatabaseSettings screens
     1097        m_DBhostCp = m_DBparams.dbHostName;
     1098
    9891099        // Cause MSqlQuery to fail, instead of minutes timeout per DB value
    9901100        m_DBparams.dbHostName = "";
    9911101
     
    9981108
    9991109    if (port && !telnet(host, port))
    10001110    {
    1001         // Cause MSqlQuery to fail, instead of several error lines per DB value
    1002         m_DBparams.dbHostName = "";
    1003 
    10041111        err = parent->tr("Cannot connect to port %1 on database host %2");
    10051112        return err.arg(port).arg(host);
    10061113    }
     
    10091116    // 3. Finally, try to login, et c:
    10101117
    10111118    if (!MSqlQuery::testDBConnection())
    1012     {
    1013         // Cause MSqlQuery to fail, instead of several error lines per DB value
    1014         m_DBparams.dbHostName = "";
    1015 
    10161119        return parent->tr(QString("Cannot login to database?"));
    1017     }
    10181120
    10191121
    10201122    return QString::null;
     
    10381140}
    10391141
    10401142
     1143bool 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
     1178void 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 */
     1203int 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 */
     1266int 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 */
     1341bool 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 */
     1384bool 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
    10411417MythContext::MythContext(const QString &binversion)
    10421418    : QObject(), d(NULL), app_binary_version(binversion)
    10431419{
     
    10461422    d = new MythContextPrivate(this);
    10471423}
    10481424
    1049 bool MythContext::Init(bool gui, DatabaseParams *pParams )
     1425bool MythContext::Init(const bool gui, UPnp *UPnPclient,
     1426                       const bool promptForBackend,
     1427                       const bool disableAutoDiscovery)
    10501428{
    10511429    if (app_binary_version != MYTH_BINARY_VERSION)
    10521430    {
     
    10621440            d->TempMainWindow(false);
    10631441            MythPopupBox::showOkPopup(d->mainWindow,
    10641442                                      "Library version error", warning);
    1065             SetMainWindow(NULL);
    1066             DestroyMythMainWindow();
     1443            d->EndTempWindow();
    10671444        }
    10681445        VERBOSE(VB_IMPORTANT, warning);
    10691446
    10701447        return false;
    10711448    }
    10721449
    1073     if (!d->Init(gui, pParams))
     1450    if (!d->Init(gui, UPnPclient, promptForBackend, disableAutoDiscovery))
    10741451        return false;
    10751452
    10761453    ActivateSettingsCache(true);
     
    21012478        .arg(err.databaseText());
    21022479}
    21032480
    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 
    21122481Settings *MythContext::qtconfig(void)
    21132482{
    21142483    return d->m_qtThemeSettings;
  • libs/libmyth/mythcontext.h

     
    3939class DisplayRes;
    4040class MDBManager;
    4141class MythContextPrivate;
     42class UPnp;
    4243
    4344/// This MAP is for the various VERBOSITY flags, used to select which
    4445/// messages we want printed to the console.
     
    248249    MythContext(const QString &binversion);
    249250    virtual ~MythContext();
    250251
    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);
    252256
    253257    QString GetMasterHostPrefix(void);
    254258
     
    334338    void LogEntry(const QString &module, int priority,
    335339                  const QString &message, const QString &details);
    336340
    337     Settings *settings(void);
    338341    Settings *qtconfig(void);
    339342
    340343    void SaveSetting(const QString &key, int newValue);
     
    463466    MYTH_SCHEMA_USE_EXISTING = 4
    464467};
    465468
     469/// Service type for the backend's UPnP server
     470extern MPUBLIC const QString gBackendURI;
     471
    466472#endif
    467473
    468474/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmyth/libmyth.pro

     
    1616HEADERS += mythdialogs.h audiooutput.h httpcomms.h mythmedia.h mythmediamonitor.h
    1717HEADERS += uilistbtntype.h generictree.h screensaver.h
    1818HEADERS += managedlist.h DisplayRes.h volumebase.h audiooutputbase.h
    19 HEADERS += dbsettings.h screensaver-null.h output.h visual.h
     19HEADERS += backendselect.h dbsettings.h screensaver-null.h output.h visual.h
    2020HEADERS += langsettings.h audiooutputnull.h mythsocket.h
    2121HEADERS += DisplayResScreen.h util-x11.h mythdeque.h qmdcodec.h
    2222HEADERS += exitcodes.h virtualkeyboard.h mythobservable.h mythevent.h
     
    3030SOURCES += httpcomms.cpp mythmedia.cpp mythmediamonitor.cpp uilistbtntype.cpp
    3131SOURCES += generictree.cpp managedlist.cpp DisplayRes.cpp
    3232SOURCES += volumecontrol.cpp volumebase.cpp audiooutputbase.cpp
    33 SOURCES += dbsettings.cpp screensaver.cpp screensaver-null.cpp output.cpp
     33SOURCES += backendselect.cpp dbsettings.cpp screensaver.cpp screensaver-null.cpp output.cpp
    3434SOURCES += langsettings.cpp mythdbcon.cpp audiooutputnull.cpp
    3535SOURCES += DisplayResScreen.cpp util-x11.cpp qmdcodec.cpp
    3636SOURCES += virtualkeyboard.cpp mythobservable.cpp mythsocket.cpp themeinfo.cpp
     
    3838
    3939INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../
    4040DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui
     41DEPENDPATH += ../libmythupnp
    4142
    4243LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION}
    4344LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION}
     
    111112    QMAKE_CXXFLAGS += -F/System/Library/Frameworks/$${FC}.framework/Frameworks
    112113    LIBS           += -framework $$join(FWKS," -framework ")
    113114
    114     # There is a dependence on some stuff in libmythui.
     115    # There is a dependence on some stuff in libmythui and libmythupnp.
    115116    # It isn't built yet, so we have to ignore these for now:
    116117    QMAKE_LFLAGS_SHLIB += -flat_namespace -undefined warning
    117118
  • libs/libmyth/mythmediamonitor.cpp

     
    5959        return c_monitor;
    6060
    6161#ifdef USING_DARWIN_DA
    62         c_monitor = new MediaMonitorDarwin(NULL, 500, true);
     62    c_monitor = new MediaMonitorDarwin(NULL, 500, true);
    6363#else
    6464  #if defined(CONFIG_CYGWIN) || defined(_WIN32)
    65         c_monitor = new MediaMonitorWindows(NULL, 500, true);
     65    c_monitor = new MediaMonitorWindows(NULL, 500, true);
    6666  #else
    67         c_monitor = new MediaMonitorUnix(NULL, 500, true);
     67    c_monitor = new MediaMonitorUnix(NULL, 500, true);
    6868  #endif
    6969#endif
    7070
  • 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
     9class 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
     29typedef QMap< QString, ListBoxDevice *> ItemMap;
     30
     31
     32class 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
     14BackendSelect::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
     59BackendSelect::~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
     75void 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
     102void 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
     117void 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
     148void BackendSelect::Manual(void)
     149{
     150    done(kDialogCodeButton0);
     151}
     152
     153void BackendSelect::Search(void)
     154{
     155    UPnp::PerformSearch(gBackendURI);
     156}
     157
     158bool 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
     209void 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
     241void 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
    
     
    264264            UPnpDeviceDesc *pDevice = GetDeviceDesc( bInQtThread );
    265265
    266266            if ( pDevice == NULL)
    267                return "<Unknown>";
     267               return "<Unknown> (" + m_sLocation + ")";
    268268
    269269            return pDevice->m_rootDevice.m_sFriendlyName
    270270                   + " (" + pDevice->m_sHostName + "), "
  • libs/libmythupnp/upnputil.cpp

     
    4747
    4848        UPnp::g_pConfig->SetValue( sName, sUDN );
    4949
    50         UPnp::g_pConfig->Save();
     50        //UPnp::g_pConfig->Save();
    5151    }
    5252
    5353    return( sUDN );
  • libs/libmythupnp/upnp.cpp

     
    144144    {
    145145        VERBOSE(VB_UPNP, QString(  "UPnp::UPnp:Starting SSDP Thread (Multicast)" ));
    146146        g_pSSDP->start();
     147        VERBOSE(VB_UPNP, QString(  "Enabling Notifications" ));
    147148        g_pSSDP->EnableNotifications();
    148149    }
    149150}
  • programs/mythfrontend/mediarenderer.cpp

     
    117117    if (m_pHttpServer)
    118118        delete m_pHttpServer;
    119119}
    120 
    121 /////////////////////////////////////////////////////////////////////////////
    122 // Caller MUST call Release on returned pointer
    123 /////////////////////////////////////////////////////////////////////////////
    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

     
    5353#include "libmythui/myththemedmenu.h"
    5454#include "libmythui/myththemebase.h"
    5555#include "mediarenderer.h"
    56 #include "masterselection.h"
    5756
    5857#define NO_EXIT  0
    5958#define QUIT     1
     
    10591058    gContext = new MythContext(MYTH_BINARY_VERSION);
    10601059    g_pUPnp  = new MediaRenderer();
    10611060
    1062     DatabaseParams *pParams = NULL;
    1063 
    1064     if (!bBypassAutoDiscovery)
     1061    if (!gContext->Init(true, g_pUPnp, bPromptForBackend, bBypassAutoDiscovery))
    10651062    {
    1066         pParams = new DatabaseParams;
    1067 
    1068         int nRetCode = MasterSelection::GetConnectionInfo( g_pUPnp,
    1069                                                            pParams,
    1070                                                            bPromptForBackend );
    1071         switch( nRetCode )
    1072         {
    1073             case -1:    // Exit Application
    1074                 return FRONTEND_EXIT_OK;
    1075 
    1076             case  0:    // Continue with no Connection Infomation
    1077             {
    1078                 delete pParams;
    1079                 pParams = NULL;
    1080 
    1081                 break;
    1082             }
    1083 
    1084             case 1:     // Connection Information found
    1085             default:
    1086                 break;
    1087         }
    1088     }
    1089 
    1090     if (!gContext->Init( true, pParams ))
    1091     {
    10921063        VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting.");
    10931064        return FRONTEND_EXIT_NO_MYTHCONTEXT;
    10941065    }
    10951066
    1096     if (pParams != NULL)
    1097     {
    1098         delete pParams;
    1099         pParams = NULL;
    1100     }
    1101 
    11021067    for(int argpos = 1; argpos < a.argc(); ++argpos)
    11031068    {
    11041069        if (!strcmp(a.argv()[argpos],"-l") ||
     
    14801445    DestroyMythMainWindow();
    14811446    delete themeBase;
    14821447    delete gContext;
     1448    // This takes a few seconds, so inform the user:
     1449    VERBOSE(VB_GENERAL, "Deleting UPnP client...");
    14831450    delete g_pUPnp;
    14841451
    14851452    return FRONTEND_EXIT_OK;
  • programs/mythfrontend/mythfrontend.pro

     
    2626HEADERS += manualbox.h playbackbox.h viewscheduled.h globalsettings.h
    2727HEADERS += manualschedule.h programrecpriority.h channelrecpriority.h
    2828HEADERS += statusbox.h networkcontrol.h custompriority.h
    29 HEADERS += mediarenderer.h masterselection.h
     29HEADERS += mediarenderer.h
    3030
    3131SOURCES += main.cpp manualbox.cpp playbackbox.cpp viewscheduled.cpp
    3232SOURCES += globalsettings.cpp manualschedule.cpp programrecpriority.cpp
    3333SOURCES += channelrecpriority.cpp statusbox.cpp networkcontrol.cpp
    34 SOURCES += mediarenderer.cpp masterselection.cpp
     34SOURCES += mediarenderer.cpp
    3535SOURCES += custompriority.cpp
    3636
    3737macx {
  • programs/mythbackend/mythxml.cpp

     
    14711471        (sServerIP         != "localhost") &&
    14721472        (sServerIP         != sPeerIP    ))
    14731473    {
     1474        VERBOSE(VB_IMPORTANT, "MythXML::GetConnectionInfo() - DBHostName of 'localhost' is inappropriate. Changing to " + sServerIP);
    14741475        params.dbHostName = sServerIP;
    14751476    }
    14761477