# Fix several segv faults and logic problems with mythfrontend during backend
# configuration either after a fresh install or by using -p option
# 1 Can't select Manual dbase configuration
# 2 Can't Cancel
# 3 Segv after selecting Save on win32
# 4 Segv in ShowOkPopup due to stale static data
# 5 Segv in MythScreenStack::PopScreen due to null pointer
diff --git a/mythtv/libs/libmyth/backendselect.cpp b/mythtv/libs/libmyth/backendselect.cpp
index 3c31dbb..45a1ec3 100644
a
|
b
|
BackendSelection::~BackendSelection() |
43 | 43 | m_devices.clear(); |
44 | 44 | } |
45 | 45 | |
46 | | bool BackendSelection::m_backendChanged = false; |
| 46 | BackendSelection::EAction BackendSelection::m_backendChanged; |
47 | 47 | |
48 | | bool BackendSelection::prompt(DatabaseParams *dbParams, |
| 48 | BackendSelection::EAction |
| 49 | BackendSelection::prompt(DatabaseParams *dbParams, |
49 | 50 | XmlConfiguration *xmlConfig) |
50 | 51 | { |
51 | | m_backendChanged = false; |
| 52 | m_backendChanged = kCancel; |
52 | 53 | |
53 | 54 | MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); |
54 | 55 | if (!mainStack) |
55 | | return false; |
| 56 | return kCancel; |
56 | 57 | |
57 | 58 | BackendSelection *backendSettings = new BackendSelection(mainStack, |
58 | 59 | dbParams, |
… |
… |
void BackendSelection::Accept(MythUIButtonListItem *item) |
100 | 101 | if (!item) |
101 | 102 | return; |
102 | 103 | |
103 | | DeviceLocation *dev = qVariantValue<DeviceLocation *>(item->GetData()); |
104 | | |
105 | | if (!dev) |
106 | | Close(); |
107 | | |
108 | | if (ConnectBackend(dev)) // this does a Release() |
| 104 | if (m_XML) |
109 | 105 | { |
110 | | if (m_pinCode.length()) |
111 | | m_XML->SetValue(kDefaultPIN, m_pinCode); |
112 | | m_XML->SetValue(kDefaultUSN, m_USN); |
113 | | m_XML->Save(); |
114 | | Close(); |
| 106 | DeviceLocation *dev = qVariantValue<DeviceLocation *>(item->GetData()); |
| 107 | |
| 108 | if (dev && ConnectBackend(dev)) // this does a Release() |
| 109 | { |
| 110 | if (m_pinCode.length()) |
| 111 | m_XML->SetValue(kDefaultPIN, m_pinCode); |
| 112 | m_XML->SetValue(kDefaultUSN, m_USN); |
| 113 | m_XML->Save(); |
| 114 | } |
115 | 115 | } |
| 116 | |
| 117 | m_backendChanged = kSave; |
| 118 | Close(); |
116 | 119 | } |
117 | 120 | |
118 | 121 | void BackendSelection::Accept(void) |
119 | 122 | { |
120 | | MythUIButtonListItem *item = m_backendList->GetItemCurrent(); |
121 | | |
122 | | if (!item) |
123 | | return; |
124 | | |
125 | | Accept(item); |
| 123 | Accept(m_backendList->GetItemCurrent()); |
126 | 124 | } |
127 | 125 | |
128 | 126 | |
… |
… |
bool BackendSelection::ConnectBackend(DeviceLocation *dev) |
226 | 224 | |
227 | 225 | void BackendSelection::Cancel() |
228 | 226 | { |
| 227 | m_backendChanged = kCancel; |
229 | 228 | Close(); |
230 | 229 | } |
231 | 230 | |
… |
… |
void BackendSelection::Init(void) |
277 | 276 | |
278 | 277 | void BackendSelection::Manual(void) |
279 | 278 | { |
| 279 | m_backendChanged = kManual; |
280 | 280 | Close(); |
281 | 281 | } |
282 | 282 | |
diff --git a/mythtv/libs/libmyth/backendselect.h b/mythtv/libs/libmyth/backendselect.h
index 825db2b..f26f666 100644
a
|
b
|
class BackendSelection : public MythScreenType |
42 | 42 | bool Create(void); |
43 | 43 | void customEvent(QEvent *event); |
44 | 44 | |
45 | | static bool prompt(DatabaseParams *dbParams, XmlConfiguration *xmlConfig); |
| 45 | enum EAction { kCancel, kSave, kManual }; |
| 46 | static EAction prompt(DatabaseParams *dbParams, XmlConfiguration *xmlConfig); |
46 | 47 | |
47 | 48 | signals: |
48 | 49 | // void |
… |
… |
class BackendSelection : public MythScreenType |
77 | 78 | QString m_pinCode; |
78 | 79 | QString m_USN; |
79 | 80 | |
80 | | static bool m_backendChanged; |
| 81 | static EAction m_backendChanged; |
81 | 82 | }; |
82 | 83 | |
83 | 84 | Q_DECLARE_METATYPE(DeviceLocation*) |
diff --git a/mythtv/libs/libmyth/mythcontext.cpp b/mythtv/libs/libmyth/mythcontext.cpp
index 99d0abc..40dee32 100644
a
|
b
|
bool MythContextPrivate::Init(const bool gui, UPnp *UPnPclient, |
285 | 285 | { |
286 | 286 | m_UPnP = UPnPclient; |
287 | 287 | m_ExternalUPnP = true; |
288 | | #ifndef _WIN32 |
289 | 288 | m_XML = (XmlConfiguration *)UPnp::g_pConfig; |
290 | | #endif |
291 | 289 | } |
292 | 290 | |
293 | 291 | // Creates screen saver control if we will have a GUI |
… |
… |
bool MythContextPrivate::FindDatabase(const bool prompt, const bool noPrompt) |
404 | 402 | switch (ChooseBackend(QString::null)) |
405 | 403 | { |
406 | 404 | case -1: // User asked to configure database manually |
| 405 | manualSelect = false; |
407 | 406 | if (PromptForDatabaseParams("")) |
408 | 407 | break; |
409 | 408 | else |
… |
… |
bool MythContextPrivate::FindDatabase(const bool prompt, const bool noPrompt) |
427 | 426 | while (!failure.isEmpty()) |
428 | 427 | { |
429 | 428 | VERBOSE(VB_IMPORTANT, QString("%1").arg(failure)); |
430 | | if (( manualSelect && ChooseBackend(failure)) || |
431 | | (!manualSelect && PromptForDatabaseParams(failure))) |
| 429 | if (manualSelect) switch (ChooseBackend(failure)) |
432 | 430 | { |
433 | | failure = TestDBconnection(); |
434 | | if (failure.length()) |
435 | | VERBOSE(VB_IMPORTANT, QString("%1").arg(failure)); |
436 | | } |
437 | | else |
| 431 | case -1: // User asked to configure database manually |
| 432 | manualSelect = false; |
| 433 | continue; |
| 434 | case 1: // User selected a backend |
| 435 | break; |
| 436 | case 0: // User cancelled. Exit application |
| 437 | default: |
438 | 438 | goto NoDBfound; |
| 439 | } |
| 440 | else if (!PromptForDatabaseParams(failure)) |
| 441 | goto NoDBfound; // User cancelled - changed their mind? |
| 442 | |
| 443 | failure = TestDBconnection(); |
| 444 | if (failure.length()) |
| 445 | VERBOSE(VB_IMPORTANT, QString("%1").arg(failure)); |
439 | 446 | } |
440 | 447 | |
441 | 448 | DBfound: |
… |
… |
int MythContextPrivate::ChooseBackend(const QString &error) |
938 | 945 | |
939 | 946 | VERBOSE(VB_GENERAL, "Putting up the UPnP backend chooser"); |
940 | 947 | |
941 | | BackendSelection::prompt(&m_DBparams, m_XML); |
| 948 | int ret; |
| 949 | switch (BackendSelection::prompt(&m_DBparams, m_XML)) |
| 950 | { |
| 951 | case BackendSelection::kCancel: ret = 0; break; |
| 952 | case BackendSelection::kSave: ret = 1; break; |
| 953 | case BackendSelection::kManual: ret = -1; break; |
| 954 | } |
942 | 955 | |
943 | 956 | EndTempWindow(); |
944 | 957 | |
945 | | return 1; |
| 958 | return ret; |
946 | 959 | } |
947 | 960 | |
948 | 961 | /** |
diff --git a/mythtv/libs/libmythui/mythdialogbox.cpp b/mythtv/libs/libmythui/mythdialogbox.cpp
index 3b10033..151af08 100644
a
|
b
|
MythConfirmationDialog *ShowOkPopup(const QString &message, QObject *parent, |
371 | 371 | { |
372 | 372 | QString LOC = "ShowOkPopup('" + message + "') - "; |
373 | 373 | MythConfirmationDialog *pop; |
374 | | static MythScreenStack *stk = NULL; |
| 374 | MythScreenStack *stk; |
375 | 375 | |
| 376 | MythMainWindow *win = GetMythMainWindow(); |
376 | 377 | |
377 | | if (!stk) |
| 378 | if (win) |
| 379 | stk = win->GetStack("popup stack"); |
| 380 | else |
378 | 381 | { |
379 | | MythMainWindow *win = GetMythMainWindow(); |
380 | | |
381 | | if (win) |
382 | | stk = win->GetStack("popup stack"); |
383 | | else |
384 | | { |
385 | | VERBOSE(VB_IMPORTANT, LOC + "no main window?"); |
386 | | return NULL; |
387 | | } |
| 382 | VERBOSE(VB_IMPORTANT, LOC + "no main window?"); |
| 383 | return NULL; |
| 384 | } |
388 | 385 | |
389 | | if (!stk) |
390 | | { |
391 | | VERBOSE(VB_IMPORTANT, LOC + "no popup stack?\n" |
392 | | "Is there a MythThemeBase?"); |
393 | | return NULL; |
394 | | } |
| 386 | if (!stk) |
| 387 | { |
| 388 | VERBOSE(VB_IMPORTANT, LOC + "no popup stack?\n" |
| 389 | "Is there a MythThemeBase?"); |
| 390 | return NULL; |
395 | 391 | } |
396 | 392 | |
397 | 393 | pop = new MythConfirmationDialog(stk, message, showCancel); |
diff --git a/mythtv/libs/libmythui/mythmainwindow.cpp b/mythtv/libs/libmythui/mythmainwindow.cpp
index 7ecb158..e82e8d7 100644
a
|
b
|
MythMainWindow::~MythMainWindow() |
496 | 496 | d->drawTimer->stop(); |
497 | 497 | |
498 | 498 | while (!d->stackList.isEmpty()) |
499 | | { |
500 | | delete d->stackList.back(); |
501 | | d->stackList.pop_back(); |
502 | | } |
| 499 | PopScreenStack(); |
503 | 500 | |
504 | 501 | delete d->m_themeBase; |
505 | 502 | |
… |
… |
void MythMainWindow::AddScreenStack(MythScreenStack *stack, bool main) |
568 | 565 | |
569 | 566 | void MythMainWindow::PopScreenStack() |
570 | 567 | { |
571 | | delete d->stackList.back(); |
| 568 | MythScreenStack *stack = d->stackList.back(); |
572 | 569 | d->stackList.pop_back(); |
| 570 | if (stack == d->mainStack) |
| 571 | d->mainStack = NULL; |
| 572 | delete stack; |
573 | 573 | } |
574 | 574 | |
575 | 575 | int MythMainWindow::GetStackCount(void) |
diff --git a/mythtv/libs/libmythui/mythscreenstack.cpp b/mythtv/libs/libmythui/mythscreenstack.cpp
index fc2108f..105f38a 100644
a
|
b
|
void MythScreenStack::PopScreen(MythScreenType *screen, bool allowFade, |
169 | 169 | { |
170 | 170 | // Screen still needs to be redrawn if we have popped the last screen |
171 | 171 | // off the popup stack, or similar |
172 | | MythScreenType *mainscreen = mainwindow->GetMainStack()->GetTopScreen(); |
173 | | if (mainscreen) |
174 | | mainscreen->SetRedraw(); |
| 172 | MythScreenStack *mainstack = mainwindow->GetMainStack(); |
| 173 | if (mainstack) |
| 174 | { |
| 175 | MythScreenType *mainscreen = mainstack->GetTopScreen(); |
| 176 | if (mainscreen) |
| 177 | mainscreen->SetRedraw(); |
| 178 | } |
175 | 179 | |
176 | 180 | if (!allowFade || !m_DoTransitions) |
177 | 181 | emit topScreenChanged(NULL); |