[Haiku-commits] r31322 - haiku/trunk/src/bin/desklink
axeld at BerliOS
axeld at mail.berlios.de
Tue Jun 30 12:14:54 CEST 2009
Author: axeld
Date: 2009-06-30 12:14:54 +0200 (Tue, 30 Jun 2009)
New Revision: 31322
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=31322&view=rev
Modified:
haiku/trunk/src/bin/desklink/MixerControl.cpp
haiku/trunk/src/bin/desklink/MixerControl.h
haiku/trunk/src/bin/desklink/VolumeControl.cpp
haiku/trunk/src/bin/desklink/VolumeControl.h
Log:
* With the help of Stippi's "I Will Survive" article, the VolumeControl
replicant should now handle media server restarts, or late starts gracefully.
* This fixed ticket #4002.
Modified: haiku/trunk/src/bin/desklink/MixerControl.cpp
===================================================================
--- haiku/trunk/src/bin/desklink/MixerControl.cpp 2009-06-29 22:38:15 UTC (rev 31321)
+++ haiku/trunk/src/bin/desklink/MixerControl.cpp 2009-06-30 10:14:54 UTC (rev 31322)
@@ -17,8 +17,7 @@
#include <ParameterWeb.h>
-MixerControl::MixerControl(int32 volumeWhich, float* _value,
- const char** _error)
+MixerControl::MixerControl(int32 volumeWhich)
:
fVolumeWhich(volumeWhich),
fGainMediaNode(media_node::null),
@@ -28,12 +27,28 @@
fMax(0.0f),
fStep(0.0f)
{
+}
+
+
+MixerControl::~MixerControl()
+{
+ _Disconnect();
+}
+
+
+bool
+MixerControl::Connect(int32 volumeWhich, float* _value, const char** _error)
+{
+ fVolumeWhich = volumeWhich;
+
+ _Disconnect();
+
bool retrying = false;
- status_t err = B_OK;
- /* BMediaRoster::Roster() doesn't set it if all is ok */
+ status_t status = B_OK;
+ // BMediaRoster::Roster() doesn't set it if all is ok
const char* errorString = NULL;
- BMediaRoster* roster = BMediaRoster::Roster(&err);
+ BMediaRoster* roster = BMediaRoster::Roster(&status);
retry:
// Here we release the BMediaRoster once if we can't access the system
@@ -49,22 +64,22 @@
roster->Quit();
}
snooze(10000);
- roster = BMediaRoster::Roster(&err);
+ roster = BMediaRoster::Roster(&status);
}
-
- if (roster && err == B_OK) {
+
+ if (roster != NULL && status == B_OK) {
switch (volumeWhich) {
case VOLUME_USE_MIXER:
- err = roster->GetAudioMixer(&fGainMediaNode);
+ status = roster->GetAudioMixer(&fGainMediaNode);
break;
case VOLUME_USE_PHYS_OUTPUT:
- err = roster->GetAudioOutput(&fGainMediaNode);
+ status = roster->GetAudioOutput(&fGainMediaNode);
break;
}
- if (err == B_OK) {
- err = roster->GetParameterWebFor(fGainMediaNode, &fParameterWeb);
- if (err == B_OK) {
- // Finding the Mixer slider in the audio output ParameterWeb
+ if (status == B_OK) {
+ status = roster->GetParameterWebFor(fGainMediaNode, &fParameterWeb);
+ if (status == B_OK) {
+ // Finding the Mixer slider in the audio output ParameterWeb
int32 numParams = fParameterWeb->CountParameters();
BParameter* p = NULL;
bool foundMixerLabel = false;
@@ -102,11 +117,14 @@
if (!strcmp(p->Kind(), B_MASTER_GAIN)) {
for (; i < numParams; i++) {
p = fParamWeb->ParameterAt(i);
- if (strcmp(p->Kind(), B_MASTER_GAIN)) p=NULL;
- else break;
+ if (strcmp(p->Kind(), B_MASTER_GAIN))
+ p = NULL;
+ else
+ break;
}
break;
- } else p = NULL;
+ } else
+ p = NULL;
#endif
p = NULL;
}
@@ -149,7 +167,7 @@
errorString = "No Media Roster";
}
- if (err != B_OK)
+ if (status != B_OK)
fGainMediaNode = media_node::null;
if (errorString) {
@@ -159,16 +177,15 @@
}
if (fMixerParameter == NULL && _value != NULL)
*_value = 0;
+
+ return errorString == NULL;
}
-MixerControl::~MixerControl()
+bool
+MixerControl::Connected()
{
- delete fParameterWeb;
-
- BMediaRoster* roster = BMediaRoster::CurrentRoster();
- if (roster != NULL && fGainMediaNode != media_node::null)
- roster->ReleaseNode(fGainMediaNode);
+ return fGainMediaNode != media_node::null;
}
@@ -220,3 +237,17 @@
SetVolume(volume + value);
}
+
+void
+MixerControl::_Disconnect()
+{
+ delete fParameterWeb;
+ fParameterWeb = NULL;
+ fMixerParameter = NULL;
+
+ BMediaRoster* roster = BMediaRoster::CurrentRoster();
+ if (roster != NULL && fGainMediaNode != media_node::null)
+ roster->ReleaseNode(fGainMediaNode);
+
+ fGainMediaNode = media_node::null;
+}
Modified: haiku/trunk/src/bin/desklink/MixerControl.h
===================================================================
--- haiku/trunk/src/bin/desklink/MixerControl.h 2009-06-29 22:38:15 UTC (rev 31321)
+++ haiku/trunk/src/bin/desklink/MixerControl.h 2009-06-30 10:14:54 UTC (rev 31322)
@@ -23,11 +23,13 @@
class MixerControl {
public:
- MixerControl(int32 volumeWhich,
- float* _value = NULL,
- const char** _error = NULL);
+ MixerControl(int32 volumeWhich);
~MixerControl();
+ bool Connect(int32 volumeWhich, float* _value = NULL,
+ const char** _error = NULL);
+ bool Connected();
+
int32 VolumeWhich() const;
float Volume() const;
@@ -40,6 +42,8 @@
media_node GainNode() { return fGainMediaNode; }
private:
+ void _Disconnect();
+
int32 fVolumeWhich;
media_node fGainMediaNode;
BParameterWeb* fParameterWeb;
Modified: haiku/trunk/src/bin/desklink/VolumeControl.cpp
===================================================================
--- haiku/trunk/src/bin/desklink/VolumeControl.cpp 2009-06-29 22:38:15 UTC (rev 31321)
+++ haiku/trunk/src/bin/desklink/VolumeControl.cpp 2009-06-30 10:14:54 UTC (rev 31322)
@@ -19,6 +19,7 @@
#include <Beep.h>
#include <ControlLook.h>
#include <Dragger.h>
+#include <MessageRunner.h>
#include <Roster.h>
#include <AppMisc.h>
@@ -28,17 +29,23 @@
#include "VolumeWindow.h"
+static const char* kMediaServerSignature = "application/x-vnd.Be.media-server";
+static const char* kAddOnServerSignature = "application/x-vnd.Be.addon-host";
+
+static const uint32 kMsgReconnectVolume = 'rcms';
+
+
VolumeControl::VolumeControl(int32 volumeWhich, bool beep, BMessage* message)
: BSlider("VolumeControl", "Volume", message, 0, 1, B_HORIZONTAL),
+ fMixerControl(new MixerControl(volumeWhich)),
fBeep(beep),
- fSnapping(false)
+ fSnapping(false),
+ fConnectRetries(0)
{
font_height fontHeight;
GetFontHeight(&fontHeight);
SetBarThickness(ceilf((fontHeight.ascent + fontHeight.descent) * 0.7));
- _InitVolume(volumeWhich);
-
BRect rect(Bounds());
rect.top = rect.bottom - 7;
rect.left = rect.right - 7;
@@ -49,7 +56,10 @@
VolumeControl::VolumeControl(BMessage* archive)
- : BSlider(archive)
+ : BSlider(archive),
+ fMixerControl(NULL),
+ fSnapping(false),
+ fConnectRetries(0)
{
if (archive->FindBool("beep", &fBeep) != B_OK)
fBeep = false;
@@ -58,7 +68,7 @@
if (archive->FindInt32("volume which", &volumeWhich) != B_OK)
volumeWhich = VOLUME_USE_MIXER;
- _InitVolume(volumeWhich);
+ fMixerControl = new MixerControl(volumeWhich);
}
@@ -109,10 +119,16 @@
else
SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
- BMediaRoster* roster = BMediaRoster::CurrentRoster();
- if (roster != NULL && fMixerControl->GainNode() != media_node::null) {
- roster->StartWatching(this, fMixerControl->GainNode(),
- B_MEDIA_NEW_PARAMETER_VALUE);
+ be_roster->StartWatching(this, B_REQUEST_LAUNCHED | B_REQUEST_QUIT);
+
+ _ConnectVolume();
+
+ if (!fMixerControl->Connected()) {
+ // Wait a bit, and try again - the media server might not have been
+ // ready yet
+ BMessage reconnect(kMsgReconnectVolume);
+ BMessageRunner::StartSending(this, &reconnect, 1000000LL, 1);
+ fConnectRetries = 3;
}
}
@@ -120,11 +136,9 @@
void
VolumeControl::DetachedFromWindow()
{
- BMediaRoster* roster = BMediaRoster::CurrentRoster();
- if (roster != NULL && fMixerControl->GainNode() != media_node::null) {
- roster->StopWatching(this, fMixerControl->GainNode(),
- B_MEDIA_NEW_PARAMETER_VALUE);
- }
+ _DisconnectVolume();
+
+ be_roster->StopWatching(this);
}
@@ -267,6 +281,53 @@
"OK"))->Go(NULL);
break;
+ case B_SOME_APP_LAUNCHED:
+ case B_SOME_APP_QUIT:
+ {
+ const char* signature;
+ if (msg->FindString("be:signature", &signature) != B_OK)
+ break;
+
+ bool isMediaServer = !strcmp(signature, kMediaServerSignature);
+ bool isAddOnServer = !strcmp(signature, kAddOnServerSignature);
+ if (isMediaServer)
+ fMediaServerRunning = msg->what == B_SOME_APP_LAUNCHED;
+ if (isAddOnServer)
+ fAddOnServerRunning = msg->what == B_SOME_APP_LAUNCHED;
+
+ if (isMediaServer || isAddOnServer) {
+ if (!fMediaServerRunning && !fAddOnServerRunning) {
+ // No media server around
+ SetLabel("No media server running");
+ SetEnabled(false);
+ } else if (fMediaServerRunning && fAddOnServerRunning) {
+ // HACK!
+ // quit our now invalid instance of the media roster
+ // so that before new nodes are created,
+ // we get a new roster
+ BMediaRoster* roster = BMediaRoster::CurrentRoster();
+ if (roster != NULL) {
+ roster->Lock();
+ roster->Quit();
+ }
+
+ BMessage reconnect(kMsgReconnectVolume);
+ BMessageRunner::StartSending(this, &reconnect, 1000000LL, 1);
+ fConnectRetries = 3;
+ }
+ }
+ break;
+ }
+
+ case kMsgReconnectVolume:
+ _ConnectVolume();
+ if (!fMixerControl->Connected() && --fConnectRetries > 1) {
+ BMessage reconnect(kMsgReconnectVolume);
+ BMessageRunner::StartSending(this, &reconnect,
+ 6000000LL / fConnectRetries, 1);
+ }
+ break;
+
default:
return BView::MessageReceived(msg);
}
@@ -324,11 +385,24 @@
void
-VolumeControl::_InitVolume(int32 volumeWhich)
+VolumeControl::_DisconnectVolume()
{
+ BMediaRoster* roster = BMediaRoster::CurrentRoster();
+ if (roster != NULL && fMixerControl->GainNode() != media_node::null) {
+ roster->StopWatching(this, fMixerControl->GainNode(),
+ B_MEDIA_NEW_PARAMETER_VALUE);
+ }
+}
+
+
+void
+VolumeControl::_ConnectVolume()
+{
+ _DisconnectVolume();
+
const char* errorString = NULL;
float volume = 0.0;
- fMixerControl = new MixerControl(volumeWhich, &volume, &errorString);
+ fMixerControl->Connect(fMixerControl->VolumeWhich(), &volume, &errorString);
if (errorString != NULL) {
SetLabel(errorString);
@@ -337,6 +411,12 @@
SetLabel("Volume");
SetLimits((int32)floorf(fMixerControl->Minimum()),
(int32)ceilf(fMixerControl->Maximum()));
+
+ BMediaRoster* roster = BMediaRoster::CurrentRoster();
+ if (roster != NULL && fMixerControl->GainNode() != media_node::null) {
+ roster->StartWatching(this, fMixerControl->GainNode(),
+ B_MEDIA_NEW_PARAMETER_VALUE);
+ }
}
SetEnabled(errorString == NULL);
@@ -355,10 +435,10 @@
if (Orientation() == B_HORIZONTAL) {
return ceilf(1.0f * (value - min) / (max - min)
* (BarFrame().Width() - 2) + BarFrame().left + 1);
- } else {
- return ceilf(BarFrame().top - 1.0f * (value - min) / (max - min)
- * BarFrame().Height());
}
+
+ return ceilf(BarFrame().top - 1.0f * (value - min) / (max - min)
+ * BarFrame().Height());
}
Modified: haiku/trunk/src/bin/desklink/VolumeControl.h
===================================================================
--- haiku/trunk/src/bin/desklink/VolumeControl.h 2009-06-29 22:38:15 UTC (rev 31321)
+++ haiku/trunk/src/bin/desklink/VolumeControl.h 2009-06-30 10:14:54 UTC (rev 31322)
@@ -42,7 +42,8 @@
virtual const char* UpdateText() const;
private:
- void _InitVolume(int32 volumeWhich);
+ void _DisconnectVolume();
+ void _ConnectVolume();
bool _IsReplicant() const;
float _PointForValue(int32 value) const;
@@ -54,6 +55,10 @@
bool fSnapping;
float fMinSnap;
float fMaxSnap;
+
+ int32 fConnectRetries;
+ bool fMediaServerRunning;
+ bool fAddOnServerRunning;
};
#endif // VOLUME_SLIDER_H
More information about the Haiku-commits
mailing list