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:
Jessica Hamilton 2017-01-15 15:40:54 +00:00
parent 9c7d2b4668
commit 79b9bd9f37
3 changed files with 124 additions and 34 deletions

View File

@ -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 -

View File

@ -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);

View File

@ -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;