desklink: use media_server notifications instead of polling.
* This removes Pulse(), which would constantly reconnect to the mixer. With the previous changes to the DefaultMediaTheme, this also makes changes to the muted state instaneous when modified by some other app.
This commit is contained in:
parent
9c7d2b4668
commit
79b9bd9f37
|
@ -131,7 +131,6 @@ public:
|
|||
virtual void MouseDown(BPoint point);
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void Pulse();
|
||||
|
||||
private:
|
||||
status_t _LaunchByPath(const char* path);
|
||||
|
@ -143,6 +142,11 @@ private:
|
|||
void _SaveSettings();
|
||||
void _Init();
|
||||
|
||||
void _DisconnectMixer();
|
||||
status_t _ConnectMixer();
|
||||
|
||||
MixerControl* fMixerControl;
|
||||
|
||||
BBitmap* fIcon;
|
||||
BBitmap* fMutedIcon;
|
||||
VolumeWindow* fVolumeSlider;
|
||||
|
@ -179,6 +183,7 @@ MediaReplicant::~MediaReplicant()
|
|||
{
|
||||
delete fIcon;
|
||||
_SaveSettings();
|
||||
_DisconnectMixer();
|
||||
}
|
||||
|
||||
|
||||
|
@ -208,6 +213,8 @@ MediaReplicant::AttachedToWindow()
|
|||
{
|
||||
AdoptParentColors();
|
||||
|
||||
_ConnectMixer();
|
||||
|
||||
BView::AttachedToWindow();
|
||||
}
|
||||
|
||||
|
@ -267,13 +274,13 @@ MediaReplicant::MouseDown(BPoint point)
|
|||
where + BPoint(4, 4)));
|
||||
|
||||
} else if ((buttons & B_TERTIARY_MOUSE_BUTTON) != 0) {
|
||||
MixerControl mixerControl;
|
||||
if (mixerControl.Connect(fVolumeWhich)) {
|
||||
mixerControl.SetMute(!fMuted);
|
||||
fMuted = mixerControl.Mute();
|
||||
if (fMixerControl != NULL) {
|
||||
fMixerControl->SetMute(!fMuted);
|
||||
fMuted = fMixerControl->Mute();
|
||||
VolumeToolTip* tip = dynamic_cast<VolumeToolTip*>(ToolTip());
|
||||
if (tip != NULL) {
|
||||
tip->SetMuteMessage(fMuted ? B_TRANSLATE("Muted"): NULL);
|
||||
tip->Update();
|
||||
ShowToolTip(tip);
|
||||
}
|
||||
Invalidate();
|
||||
|
@ -288,28 +295,6 @@ MediaReplicant::MouseDown(BPoint point)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
MediaReplicant::Pulse()
|
||||
{
|
||||
bool setMuted = false;
|
||||
MixerControl mixerControl;
|
||||
const char* errorString = NULL;
|
||||
if (!mixerControl.Connect(fVolumeWhich, NULL, &errorString)) {
|
||||
fMuted = true;
|
||||
errorString = NULL;
|
||||
} else
|
||||
setMuted = mixerControl.Mute();
|
||||
|
||||
if (setMuted != fMuted) {
|
||||
fMuted = setMuted;
|
||||
VolumeToolTip* tip = dynamic_cast<VolumeToolTip*>(ToolTip());
|
||||
if (tip != NULL)
|
||||
tip->SetMuteMessage(errorString);
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MediaReplicant::MessageReceived(BMessage* message)
|
||||
{
|
||||
|
@ -350,8 +335,18 @@ MediaReplicant::MessageReceived(BMessage* message)
|
|||
fVolumeWhich = item->IsMarked()
|
||||
? VOLUME_USE_PHYS_OUTPUT : VOLUME_USE_MIXER;
|
||||
|
||||
if (VolumeToolTip* tip = dynamic_cast<VolumeToolTip*>(ToolTip()))
|
||||
if (_ConnectMixer() != B_OK
|
||||
&& fVolumeWhich == VOLUME_USE_PHYS_OUTPUT) {
|
||||
// unable to switch to physical output
|
||||
item->SetMarked(false);
|
||||
fVolumeWhich = VOLUME_USE_MIXER;
|
||||
_ConnectMixer();
|
||||
}
|
||||
|
||||
if (VolumeToolTip* tip = dynamic_cast<VolumeToolTip*>(ToolTip())) {
|
||||
tip->SetWhich(fVolumeWhich);
|
||||
tip->Update();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -359,10 +354,8 @@ MediaReplicant::MessageReceived(BMessage* message)
|
|||
{
|
||||
float deltaY;
|
||||
if (message->FindFloat("be:wheel_delta_y", &deltaY) == B_OK
|
||||
&& deltaY != 0.0) {
|
||||
MixerControl mixerControl;
|
||||
mixerControl.Connect(fVolumeWhich);
|
||||
mixerControl.ChangeVolumeBy(deltaY < 0 ? 6 : -6);
|
||||
&& deltaY != 0.0 && fMixerControl != NULL) {
|
||||
fMixerControl->ChangeVolumeBy(deltaY < 0 ? 6 : -6);
|
||||
|
||||
VolumeToolTip* tip = dynamic_cast<VolumeToolTip*>(ToolTip());
|
||||
if (tip != NULL) {
|
||||
|
@ -373,6 +366,46 @@ MediaReplicant::MessageReceived(BMessage* message)
|
|||
break;
|
||||
}
|
||||
|
||||
case B_MEDIA_NEW_PARAMETER_VALUE:
|
||||
{
|
||||
if (fMixerControl != NULL && !fMixerControl->Connected())
|
||||
return;
|
||||
|
||||
bool setMuted = fMixerControl->Mute();
|
||||
if (setMuted != fMuted) {
|
||||
fMuted = setMuted;
|
||||
VolumeToolTip* tip = dynamic_cast<VolumeToolTip*>(ToolTip());
|
||||
if (tip != NULL) {
|
||||
tip->SetMuteMessage(fMuted ? B_TRANSLATE("Muted") : NULL);
|
||||
tip->Update();
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case B_MEDIA_SERVER_STARTED:
|
||||
_ConnectMixer();
|
||||
break;
|
||||
|
||||
case B_MEDIA_NODE_CREATED:
|
||||
{
|
||||
// It's not enough to wait for B_MEDIA_SERVER_STARTED message, as
|
||||
// the mixer will still be getting loaded by the media server
|
||||
media_node mixerNode;
|
||||
media_node_id mixerNodeID;
|
||||
BMediaRoster* roster = BMediaRoster::CurrentRoster();
|
||||
if (roster != NULL
|
||||
&& message->FindInt32("media_node_id",&mixerNodeID) == B_OK
|
||||
&& roster->GetNodeFor(mixerNodeID, &mixerNode) == B_OK) {
|
||||
if (mixerNode.kind == B_SYSTEM_MIXER) {
|
||||
_ConnectMixer();
|
||||
roster->ReleaseNode(mixerNode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BView::MessageReceived(message);
|
||||
break;
|
||||
|
@ -509,6 +542,56 @@ MediaReplicant::_Init()
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
MediaReplicant::_DisconnectMixer()
|
||||
{
|
||||
BMediaRoster* roster = BMediaRoster::CurrentRoster();
|
||||
if (roster == NULL)
|
||||
return;
|
||||
|
||||
roster->StopWatching(this, B_MEDIA_SERVER_STARTED | B_MEDIA_NODE_CREATED);
|
||||
|
||||
if (fMixerControl->MuteNode() != media_node::null) {
|
||||
roster->StopWatching(this, fMixerControl->MuteNode(),
|
||||
B_MEDIA_NEW_PARAMETER_VALUE);
|
||||
}
|
||||
|
||||
delete fMixerControl;
|
||||
fMixerControl = NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaReplicant::_ConnectMixer()
|
||||
{
|
||||
_DisconnectMixer();
|
||||
|
||||
BMediaRoster* roster = BMediaRoster::Roster();
|
||||
if (roster == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
roster->StartWatching(this, B_MEDIA_SERVER_STARTED | B_MEDIA_NODE_CREATED);
|
||||
|
||||
fMixerControl = new MixerControl(fVolumeWhich);
|
||||
|
||||
const char* errorString = NULL;
|
||||
float volume = 0.0;
|
||||
fMixerControl->Connect(fVolumeWhich, &volume, &errorString);
|
||||
|
||||
if (errorString != NULL) {
|
||||
SetToolTip(errorString);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (fMixerControl->MuteNode() != media_node::null) {
|
||||
roster->StartWatching(this, fMixerControl->MuteNode(),
|
||||
B_MEDIA_NEW_PARAMETER_VALUE);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ MixerControl::MixerControl(int32 volumeWhich)
|
|||
:
|
||||
fVolumeWhich(volumeWhich),
|
||||
fGainMediaNode(media_node::null),
|
||||
fMuteMediaNode(media_node::null),
|
||||
fParameterWeb(NULL),
|
||||
fMixerParameter(NULL),
|
||||
fMuteParameter(NULL),
|
||||
|
@ -74,8 +75,10 @@ MixerControl::Connect(int32 volumeWhich, float* _value, const char** _error)
|
|||
p = fParameterWeb->ParameterAt(i);
|
||||
|
||||
// assume the mute preceeding master gain control
|
||||
if (!strcmp(p->Kind(), B_MUTE))
|
||||
if (!strcmp(p->Kind(), B_MUTE)) {
|
||||
fMuteParameter = p;
|
||||
fMuteMediaNode = fMuteParameter->Web()->Node();
|
||||
}
|
||||
|
||||
PRINT(("BParameter[%i]: %s\n", i, p->Name()));
|
||||
if (volumeWhich == VOLUME_USE_MIXER) {
|
||||
|
@ -151,8 +154,10 @@ MixerControl::Connect(int32 volumeWhich, float* _value, const char** _error)
|
|||
} else
|
||||
errorString = "Media services not running";
|
||||
|
||||
if (status != B_OK)
|
||||
if (status != B_OK) {
|
||||
fGainMediaNode = media_node::null;
|
||||
fMuteMediaNode = media_node::null;
|
||||
}
|
||||
|
||||
if (errorString) {
|
||||
fprintf(stderr, "MixerControl: %s.\n", errorString);
|
||||
|
|
|
@ -44,12 +44,14 @@ public:
|
|||
float Maximum() const { return fMax; }
|
||||
|
||||
media_node GainNode() { return fGainMediaNode; }
|
||||
media_node MuteNode() { return fMuteMediaNode; }
|
||||
|
||||
private:
|
||||
void _Disconnect();
|
||||
|
||||
int32 fVolumeWhich;
|
||||
media_node fGainMediaNode;
|
||||
media_node fMuteMediaNode;
|
||||
BParameterWeb* fParameterWeb;
|
||||
BContinuousParameter* fMixerParameter;
|
||||
BParameter* fMuteParameter;
|
||||
|
|
Loading…
Reference in New Issue