diff --git a/src/bin/desklink/DeskButton.cpp b/src/bin/desklink/DeskButton.cpp index e7b2379fd5..61f7c2d45b 100644 --- a/src/bin/desklink/DeskButton.cpp +++ b/src/bin/desklink/DeskButton.cpp @@ -110,7 +110,7 @@ DeskButton::MessageReceived(BMessage *message) case B_ABOUT_REQUESTED: (new BAlert("About Desklink", "Desklink (Replicant)\n" " Brought to you by Jérôme DUVAL.\n\n" - "Copyright " B_UTF8_COPYRIGHT "2003-2007, Haiku","OK"))->Go(); + "Copyright " B_UTF8_COPYRIGHT "2003-2009, Haiku","OK"))->Go(); break; case OPEN_REF: be_roster->Launch(&fRef); diff --git a/src/bin/desklink/Jamfile b/src/bin/desklink/Jamfile index 723e3ba727..2c668d21de 100644 --- a/src/bin/desklink/Jamfile +++ b/src/bin/desklink/Jamfile @@ -2,18 +2,12 @@ SubDir HAIKU_TOP src bin desklink ; SetSubDirSupportedPlatformsBeOSCompatible ; -if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) { - UseHeaders [ FDirName $(HAIKU_TOP) headers os interface ] : true ; - # We need the public interface headers also when not compiling for Haiku. - UseHeaders [ FDirName $(HAIKU_TOP) headers os ] : true ; - # We need the public headers also when not compiling for Haiku. -} - BinCommand desklink : desklink.cpp VolumeSlider.cpp DeskButton.cpp + MixerControl.cpp + : be libmedia.so : desklink.rdef - ; - +; diff --git a/src/bin/desklink/MixerControl.cpp b/src/bin/desklink/MixerControl.cpp new file mode 100644 index 0000000000..c704f50007 --- /dev/null +++ b/src/bin/desklink/MixerControl.cpp @@ -0,0 +1,212 @@ +/* + * Copyright 2003-2009, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Authors: + * Jérôme Duval + * François Revol + */ + + +#include "MixerControl.h" + +#include +#include + + +MixerControl::MixerControl(int32 volumeWhich, float* _value, + const char** _error) + : + fAudioMixerNode(NULL), + fParameterWeb(NULL), + fMixerParameter(NULL), + fMin(0.0f), + fMax(0.0f), + fStep(0.0f) +{ + bool retrying = false; + fAudioMixerNode = new media_node(); + + status_t err = B_OK; + /* BMediaRoster::Roster() doesn't set it if all is ok */ + const char* errorString = NULL; + BMediaRoster* roster = BMediaRoster::Roster(&err); + +retry: + // Here we release the BMediaRoster once if we can't access the system + // mixer, to make sure it really isn't there, and it's not BMediaRoster + // that is messed up. + if (retrying) { + errorString = NULL; + PRINT(("retrying to get a Media Roster\n")); + /* BMediaRoster looks doomed */ + roster = BMediaRoster::CurrentRoster(); + if (roster) { + roster->Lock(); + roster->Quit(); + } + snooze(10000); + roster = BMediaRoster::Roster(&err); + } + + if (roster && err == B_OK) { + switch (volumeWhich) { + case VOLUME_USE_MIXER: + err = roster->GetAudioMixer(fAudioMixerNode); + break; + case VOLUME_USE_PHYS_OUTPUT: + err = roster->GetAudioOutput(fAudioMixerNode); + break; + } + if (err == B_OK) { + err = roster->GetParameterWebFor(*fAudioMixerNode, &fParameterWeb); + if (err == B_OK) { + // Finding the Mixer slider in the audio output ParameterWeb + int32 numParams = fParameterWeb->CountParameters(); + BParameter* p = NULL; + bool foundMixerLabel = false; + for (int i = 0; i < numParams; i++) { + p = fParameterWeb->ParameterAt(i); + PRINT(("BParameter[%i]: %s\n", i, p->Name())); + if (volumeWhich == VOLUME_USE_MIXER) { + if (!strcmp(p->Kind(), B_MASTER_GAIN)) + break; + } else if (volumeWhich == VOLUME_USE_PHYS_OUTPUT) { + /* not all cards use the same name, and + * they don't seem to use Kind() == B_MASTER_GAIN + */ + if (!strcmp(p->Kind(), B_MASTER_GAIN)) + break; + PRINT(("not MASTER_GAIN \n")); + + /* some audio card + */ + if (!strcmp(p->Name(), "Master")) + break; + PRINT(("not 'Master' \n")); + + /* some Ensonic card have all controls names 'Volume', so + * need to fint the one that has the 'Mixer' text label + */ + if (foundMixerLabel && !strcmp(p->Name(), "Volume")) + break; + if (!strcmp(p->Name(), "Mixer")) + foundMixerLabel = true; + PRINT(("not 'Mixer' \n")); + } +#if 0 + //if (!strcmp(p->Name(), "Master")) { + 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; + } + break; + } else p = NULL; +#endif + p = NULL; + } + if (p == NULL) { + errorString = volumeWhich + ? "Could not find the soundcard":"Could not find the mixer"; + } else if (p->Type() != BParameter::B_CONTINUOUS_PARAMETER) { + errorString = volumeWhich + ? "Soundcard control unknown":"Mixer control unknown"; + } else { + fMixerParameter = dynamic_cast(p); + fMin = fMixerParameter->MinValue(); + fMax = fMixerParameter->MaxValue(); + fStep = fMixerParameter->ValueStep(); + + if (_value != NULL) { + float volume; + bigtime_t lastChange; + size_t size = sizeof(float); + fMixerParameter->GetValue(&volume, &size, &lastChange); + + *_value = volume; + } + } + } else { + errorString = "No parameter web"; + } + } else { + if (!retrying) { + retrying = true; + goto retry; + } + errorString = volumeWhich ? "No Audio output" : "No Mixer"; + } + } else { + if (!retrying) { + retrying = true; + goto retry; + } + errorString = "No Media Roster"; + } + + if (err != B_OK) { + delete fAudioMixerNode; + fAudioMixerNode = NULL; + } + if (errorString) { + fprintf(stderr, "MixerControl: %s.\n", errorString); + if (_error) + *_error = errorString; + } + if (fMixerParameter == NULL && _value != NULL) + *_value = 0; +} + + +MixerControl::~MixerControl() +{ + delete fParameterWeb; + + BMediaRoster* roster = BMediaRoster::CurrentRoster(); + if (roster != NULL && fAudioMixerNode != NULL) + roster->ReleaseNode(*fAudioMixerNode); +} + + +void +MixerControl::SetVolume(float volume) +{ + if (fMixerParameter == NULL) + return; + + if (volume < fMin) + volume = fMin; + else if (volume > fMax) + volume = fMax; + + if (volume != _GetVolume()) + fMixerParameter->SetValue(&volume, sizeof(float), system_time()); +} + + +void +MixerControl::ChangeVolumeBy(float value) +{ + if (fMixerParameter == NULL || value == 0.0f) + return; + + float volume = _GetVolume(); + SetVolume(volume + value); +} + + +float +MixerControl::_GetVolume() +{ + if (fMixerParameter == NULL) + return 0.0f; + + float volume = 0; + bigtime_t lastChange; + size_t size = sizeof(float); + fMixerParameter->GetValue(&volume, &size, &lastChange); + + return volume; +} diff --git a/src/bin/desklink/MixerControl.h b/src/bin/desklink/MixerControl.h new file mode 100644 index 0000000000..a787ce21fd --- /dev/null +++ b/src/bin/desklink/MixerControl.h @@ -0,0 +1,46 @@ +/* + * Copyright 2003-2009, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Authors: + * Jérôme Duval + * François Revol + */ +#ifndef MIXER_CONTROL_H +#define MIXER_CONTROL_H + + +#include + +class BParameterWeb; +class BContinuousParameter; + + +// The volume which choices +#define VOLUME_USE_MIXER 0 // default +#define VOLUME_USE_PHYS_OUTPUT 1 + + +class MixerControl { +public: + MixerControl(int32 volumeWhich, float *value = NULL, + const char **error = NULL); + ~MixerControl(); + + void SetVolume(float volume); + void ChangeVolumeBy(float value); + + float Minimum() const { return fMin; } + float Maximum() const { return fMax; } + +private: + float _GetVolume(); + void _SetVolume(float volume); + + media_node* fAudioMixerNode; + BParameterWeb* fParameterWeb; + BContinuousParameter* fMixerParameter; + float fMin, fMax, fStep; +}; + +#endif // MIXER_CONTROL_H diff --git a/src/bin/desklink/VolumeSlider.cpp b/src/bin/desklink/VolumeSlider.cpp index 724132a128..b01e5c3fd7 100644 --- a/src/bin/desklink/VolumeSlider.cpp +++ b/src/bin/desklink/VolumeSlider.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2007, Haiku, Inc. + * Copyright 2003-2009, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: @@ -7,322 +7,52 @@ * François Revol */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include #include "VolumeSlider.h" -#include "iconfile.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "MixerControl.h" #define VOLUME_CHANGED 'vlcg' #define VOLUME_UPDATED 'vlud' -#define REDZONESTART 151 + +class SliderView : public BSlider { +public: + SliderView(const char* name, const char* label, + BMessage *message, int32 minValue, + int32 maxValue); + virtual ~SliderView(); + + virtual void MouseDown(BPoint where); + virtual void MessageReceived(BMessage* msg); + virtual void DrawBar(); + virtual const char* UpdateText() const; + +private: + mutable char fText[64]; +}; -MixerControl::MixerControl(int32 volumeWhich, float *value, const char **error) - : - fAudioMixerNode(NULL), - fParamWeb(NULL), - fMixerParam(NULL), - fMin(0.0), - fMax(0.0), - fStep(0.0) - { - bool retrying = false; - fAudioMixerNode = new media_node(); - - status_t err = B_OK; /* BMediaRoster::Roster() doesn't set it if all is ok */ - const char *errString = NULL; - BMediaRoster* roster = BMediaRoster::Roster(&err); - - retry: - /* here we release the BMediaRoster once if we can't access the system mixer, - * to make sure it really isn't there, and it's not BMediaRoster that is messed up. - */ - if (retrying) { - errString = NULL; - PRINT(("retrying to get a Media Roster\n")); - /* BMediaRoster looks doomed */ - roster = BMediaRoster::CurrentRoster(); - if (roster) { - roster->Lock(); - roster->Quit(); - } - snooze(10000); - roster = BMediaRoster::Roster(&err); - } - - if (roster && err == B_OK) { - switch (volumeWhich) { - case VOLUME_USE_MIXER: - err = roster->GetAudioMixer(fAudioMixerNode); - break; - case VOLUME_USE_PHYS_OUTPUT: - err = roster->GetAudioOutput(fAudioMixerNode); - break; - } - if (err == B_OK) { - if ((err = roster->GetParameterWebFor(*fAudioMixerNode, &fParamWeb)) == B_OK) { - // Finding the Mixer slider in the audio output ParameterWeb - int32 numParams = fParamWeb->CountParameters(); - BParameter* p = NULL; - bool foundMixerLabel = false; - for (int i = 0; i < numParams; i++) { - p = fParamWeb->ParameterAt(i); - PRINT(("BParameter[%i]: %s\n", i, p->Name())); - if (volumeWhich == VOLUME_USE_MIXER) { - if (!strcmp(p->Kind(), B_MASTER_GAIN)) - break; - } else if (volumeWhich == VOLUME_USE_PHYS_OUTPUT) { - /* not all cards use the same name, and - * they don't seem to use Kind() == B_MASTER_GAIN - */ - if (!strcmp(p->Kind(), B_MASTER_GAIN)) - break; - PRINT(("not MASTER_GAIN \n")); - - /* some audio card - */ - if (!strcmp(p->Name(), "Master")) - break; - PRINT(("not 'Master' \n")); - - /* some Ensonic card have all controls names 'Volume', so - * need to fint the one that has the 'Mixer' text label - */ - if (foundMixerLabel && !strcmp(p->Name(), "Volume")) - break; - if (!strcmp(p->Name(), "Mixer")) - foundMixerLabel = true; - PRINT(("not 'Mixer' \n")); - } -#if 0 - //if (!strcmp(p->Name(), "Master")) { - 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; - } - break; - } else p = NULL; -#endif - p = NULL; - } - if (p == NULL) { - errString = volumeWhich - ? "Could not find the soundcard":"Could not find the mixer"; - } else if (p->Type() != BParameter::B_CONTINUOUS_PARAMETER) { - errString = volumeWhich - ? "Soundcard control unknown":"Mixer control unknown"; - } else { - fMixerParam = dynamic_cast(p); - fMin = fMixerParam->MinValue(); - fMax = fMixerParam->MaxValue(); - fStep = fMixerParam->ValueStep(); - - float chanData[2]; - bigtime_t lastChange; - size_t size = sizeof(chanData); - - fMixerParam->GetValue(&chanData, &size, &lastChange); - - if (value) - *value = (chanData[0] - fMin) * 100 / ((fMax - fMin) ? (fMax - fMin) : 1); - } - } else { - errString = "No parameter web"; - } - } else { - if (!retrying) { - retrying = true; - goto retry; - } - errString = volumeWhich ? "No Audio output" : "No Mixer"; - } - } else { - if (!retrying) { - retrying = true; - goto retry; - } - errString = "No Media Roster"; - } - - if (err != B_OK) { - delete fAudioMixerNode; - fAudioMixerNode = NULL; - } - if (errString) { - fprintf(stderr, "MixerControl: %s.\n", errString); - if (error) - *error = errString; - } - if (fMixerParam == NULL) - *value = -1; -} - - -MixerControl::~MixerControl() +SliderView::SliderView(const char* name, const char* label, BMessage *message, + int32 minValue, int32 maxValue) + : BSlider("slider", label, message, minValue, maxValue, B_HORIZONTAL) { - delete fParamWeb; - BMediaRoster* roster = BMediaRoster::CurrentRoster(); - if (roster && fAudioMixerNode) - roster->ReleaseNode(*fAudioMixerNode); -} + font_height fontHeight; + GetFontHeight(&fontHeight); + SetBarThickness(ceilf((fontHeight.ascent + fontHeight.descent) * 0.7)); - -void -MixerControl::UpdateVolume(int32 value) -{ - if (!fMixerParam) - return; - - float chanData[2]; - bigtime_t lastChange; - size_t size = sizeof(chanData); - - fMixerParam->GetValue(&chanData, &size, &lastChange); - - for (int i = 0; i < 2; i++) { - chanData[i] = (value * (fMax - fMin) / 100) / fStep * fStep + fMin; - } - - PRINT(("Min value: %f Max Value: %f\nData: %f %f\n", - fMixerParam->MinValue(), fMixerParam->MaxValue(), chanData[0], chanData[1])); - fMixerParam->SetValue(&chanData, sizeof(chanData), system_time()+1000); -} - - -void -MixerControl::ChangeVolumeBy(int32 value) -{ - if (!fMixerParam) - return; - - float chanData[2]; - bigtime_t lastChange; - size_t size = sizeof(chanData); - - fMixerParam->GetValue(&chanData, &size, &lastChange); - - for (int i = 0; i < 2; i++) { - chanData[i] += fStep * value; - if (chanData[i] < fMin) - chanData[i] = fMin; - else if (chanData[i] > fMax) - chanData[i] = fMax; - } - - PRINT(("Min value: %f Max Value: %f\nData: %f %f\n", - fMixerParam->MinValue(), fMixerParam->MaxValue(), chanData[0], chanData[1])); - fMixerParam->SetValue(&chanData, sizeof(chanData), system_time()+1000); -} - - -// #pragma mark - - - -VolumeSlider::VolumeSlider(BRect frame, bool dontBeep, int32 volumeWhich) - : BWindow(frame, "VolumeSlider", B_BORDERED_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL, - B_ASYNCHRONOUS_CONTROLS | B_WILL_ACCEPT_FIRST_CLICK, 0) -{ - // Make sure it's not outside the screen. - const int32 kMargin = 3; - BRect windowRect = ConvertToScreen(Bounds()); - BRect screenFrame(BScreen(B_MAIN_SCREEN_ID).Frame()); - if (screenFrame.right < windowRect.right + kMargin) - MoveBy(- kMargin - windowRect.right + screenFrame.right, 0); - if (screenFrame.bottom < windowRect.bottom + kMargin) - MoveBy(0, - kMargin - windowRect.bottom + screenFrame.bottom); - if (screenFrame.left > windowRect.left - kMargin) - MoveBy(kMargin + screenFrame.left - windowRect.left, 0); - if (screenFrame.top > windowRect.top - kMargin) - MoveBy(0, kMargin + screenFrame.top - windowRect.top); - - float value = 0.0; - fDontBeep = dontBeep; - const char *errString = NULL; - fMixerControl = new MixerControl(volumeWhich, &value, &errString); - - BBox *box = new BBox(Bounds(), "sliderbox", B_FOLLOW_LEFT | B_FOLLOW_TOP, - B_WILL_DRAW | B_FRAME_EVENTS, B_PLAIN_BORDER); - AddChild(box); - - fHasChanged = false; /* make sure we don't beep if we don't change anything */ - fSlider = new SliderView(box->Bounds().InsetByCopy(1, 1), new BMessage(VOLUME_CHANGED), - errString == NULL ? "Volume" : errString, B_FOLLOW_LEFT | B_FOLLOW_TOP, (int32)value); - box->AddChild(fSlider); - - fSlider->SetTarget(this); - - SetPulseRate(100); -} - - -VolumeSlider::~VolumeSlider() -{ - delete fMixerControl; -} - - -void -VolumeSlider::WindowActivated(bool active) -{ - /* don't Quit() ! thanks for FFM users */ -} - - -void -VolumeSlider::MessageReceived(BMessage *msg) -{ - switch (msg->what) { - case VOLUME_UPDATED: - PRINT(("VOLUME_UPDATED\n")); - fMixerControl->UpdateVolume(fSlider->Value()); - fHasChanged = true; - break; - - case VOLUME_CHANGED: - if (fHasChanged) { - PRINT(("VOLUME_CHANGED\n")); - fMixerControl->UpdateVolume(fSlider->Value()); - if (!fDontBeep) - beep(); - } - Quit(); - break; - - default: - BWindow::MessageReceived(msg); // not a slider message, not our problem - } -} - - -// #pragma mark - - - -SliderView::SliderView(BRect rect, BMessage *msg, const char *title, - uint32 resizeFlags, int32 value) - : BControl(rect, "slider", NULL, msg, resizeFlags, B_WILL_DRAW | B_PULSE_NEEDED), - fLeftBitmap(BRect(0, 0, kLeftWidth - 1, kLeftHeight - 1), B_CMAP8), - fRightBitmap(BRect(0, 0, kRightWidth - 1, kRightHeight - 1), B_CMAP8), - fButtonBitmap(BRect(0, 0, kButtonWidth - 1, kButtonHeight - 1), B_CMAP8), - fTitle(title) -{ - fLeftBitmap.SetBits(kLeftBits, kLeftWidth * kLeftHeight, 0, B_CMAP8); - fRightBitmap.SetBits(kRightBits, kRightWidth * kRightHeight, 0, B_CMAP8); - fButtonBitmap.SetBits(kButtonBits, kButtonWidth * kButtonHeight, 0, B_CMAP8); - - SetValue(value); SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); } @@ -333,49 +63,12 @@ SliderView::~SliderView() void -SliderView::Draw(BRect updateRect) +SliderView::MouseDown(BPoint where) { - SetHighColor(189,186,189); - StrokeLine(BPoint(11,1), BPoint(192,1)); - SetHighColor(0,0,0); - StrokeLine(BPoint(11,2), BPoint(192,2)); - SetHighColor(255,255,255); - StrokeLine(BPoint(11,14), BPoint(192,14)); - SetHighColor(231,227,231); - StrokeLine(BPoint(11,15), BPoint(192,15)); + if (!IsEnabled() || !Bounds().Contains(where)) + Invoke(); - SetLowColor(ViewColor()); - - SetDrawingMode(B_OP_OVER); - - DrawBitmapAsync(&fLeftBitmap, BPoint(5,1)); - DrawBitmapAsync(&fRightBitmap, BPoint(193,1)); - - float position = 11 + (192-11) * ((Value() == -1) ? 0 : Value()) / 100; - float right = (position < REDZONESTART) ? position : REDZONESTART; - SetHighColor(99,151,99); - FillRect(BRect(11,3,right,4)); - SetHighColor(156,203,156); - FillRect(BRect(11,5,right,13)); - if (right == REDZONESTART) { - SetHighColor(156,101,99); - FillRect(BRect(REDZONESTART,3,position,4)); - SetHighColor(255,154,156); - FillRect(BRect(REDZONESTART,5,position,13)); - } - SetHighColor(156,154,156); - FillRect(BRect(position,3,192,13)); - - float width = be_plain_font->StringWidth(fTitle); - - SetHighColor(49,154,49); - DrawString(fTitle, BPoint(11 + (192-11-width)/2, 12)); - - DrawBitmapAsync(&fButtonBitmap, BPoint(position-5,3)); - - Sync(); - - SetDrawingMode(B_OP_COPY); + BSlider::MouseDown(where); } @@ -422,62 +115,124 @@ SliderView::MessageReceived(BMessage* msg) void -SliderView::MouseDown(BPoint point) +SliderView::DrawBar() { - if (Bounds().Contains(point)) { - SetTracking(true); - MouseMoved(point, B_INSIDE_VIEW, NULL); - } else - Invoke(); + BRect frame = BarFrame(); + BView* view = OffscreenView(); + + if (be_control_look != NULL) { + uint32 flags = be_control_look->Flags(this); + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + rgb_color rightFillColor = (rgb_color){255, 109, 38, 255}; + rgb_color leftFillColor = (rgb_color){116, 224, 0, 255}; + + int32 min, max; + GetLimits(&min, &max); + float position = 1.0f * (max - min - max) / (max - min); + + be_control_look->DrawSliderBar(view, frame, frame, base, leftFillColor, + rightFillColor, position, flags, Orientation()); + return; + } + + BSlider::DrawBar(); } -void -SliderView::MouseMoved(BPoint point, uint32 transit, const BMessage *message) +const char* +SliderView::UpdateText() const { - if (!IsTracking()) - return; + snprintf(fText, sizeof(fText), "%ld dB", Value()); + return fText; +} - int32 mouseButtons; - Window()->CurrentMessage()->FindInt32("buttons", &mouseButtons); - // button not pressed, exit - if (!(mouseButtons & B_PRIMARY_MOUSE_BUTTON)) { - Invoke(); - SetTracking(false); - } +// #pragma mark - - if (Value() == -1) - return; - float v = MIN(MAX(point.x, 11), 192); - v = (v - 11) / (192-11) * 100; - v = MAX(MIN(v,100), 0); - SetValue((int32)v); - Draw(Bounds()); - Flush(); +VolumeSlider::VolumeSlider(BRect frame, bool dontBeep, int32 volumeWhich) + : BWindow(frame, "VolumeSlider", B_BORDERED_WINDOW_LOOK, + B_FLOATING_ALL_WINDOW_FEEL, + B_ASYNCHRONOUS_CONTROLS | B_WILL_ACCEPT_FIRST_CLICK, 0) +{ + fDontBeep = dontBeep; - if (Window()) - Window()->PostMessage(VOLUME_UPDATED); + const char *errorString = NULL; + float value = 0.0; + fMixerControl = new MixerControl(volumeWhich, &value, &errorString); + + SetLayout(new BGroupLayout(B_HORIZONTAL)); + + BGroupLayout* layout = new BGroupLayout(B_HORIZONTAL); + layout->SetInsets(10, 0, 10, 0); + + BBox* box = new BBox("sliderbox"); + box->SetLayout(layout); + box->SetBorder(B_PLAIN_BORDER); + AddChild(box); + + fHasChanged = false; + // make sure we don't beep if we don't change anything + + fSlider = new SliderView("volume", errorString ? errorString : "Volume", + new BMessage(VOLUME_CHANGED), fMixerControl->Minimum(), + fMixerControl->Maximum()); + fSlider->SetValue((int32)value); + fSlider->SetModificationMessage(new BMessage(VOLUME_UPDATED)); + if (errorString != NULL) + fSlider->SetEnabled(false); + box->AddChild(fSlider); + + fSlider->SetTarget(this); + SetPulseRate(100); + ResizeTo(300, 50); + + // Make sure it's not outside the screen. + const int32 kMargin = 3; + BRect windowRect = Frame(); + BRect screenFrame(BScreen(B_MAIN_SCREEN_ID).Frame()); + if (screenFrame.right < windowRect.right + kMargin) + MoveBy(- kMargin - windowRect.right + screenFrame.right, 0); + if (screenFrame.bottom < windowRect.bottom + kMargin) + MoveBy(0, - kMargin - windowRect.bottom + screenFrame.bottom); + if (screenFrame.left > windowRect.left - kMargin) + MoveBy(kMargin + screenFrame.left - windowRect.left, 0); + if (screenFrame.top > windowRect.top - kMargin) + MoveBy(0, kMargin + screenFrame.top - windowRect.top); +} + + +VolumeSlider::~VolumeSlider() +{ + delete fMixerControl; } void -SliderView::MouseUp(BPoint point) +VolumeSlider::MessageReceived(BMessage *msg) { - if (!IsTracking()) - return; + switch (msg->what) { + case VOLUME_UPDATED: +puts("updated"); + PRINT(("VOLUME_UPDATED\n")); + fMixerControl->SetVolume(fSlider->Value()); + fHasChanged = true; + break; - if (Value() != -1 && Bounds().InsetBySelf(2, 2).Contains(point)) { - float v = MIN(MAX(point.x, 11), 192); - v = (v - 11) / (192-11) * 100; - v = MAX(MIN(v,100), 0); - SetValue((int32)v); + case VOLUME_CHANGED: +puts("changed"); + if (fHasChanged) { + PRINT(("VOLUME_CHANGED\n")); + fMixerControl->SetVolume(fSlider->Value()); + if (!fDontBeep) + beep(); + } + Quit(); + break; + + default: + BWindow::MessageReceived(msg); + break; } - - Invoke(); - SetTracking(false); - Draw(Bounds()); - Flush(); } diff --git a/src/bin/desklink/VolumeSlider.h b/src/bin/desklink/VolumeSlider.h index a1805e46ae..2152ad4d7b 100644 --- a/src/bin/desklink/VolumeSlider.h +++ b/src/bin/desklink/VolumeSlider.h @@ -1,68 +1,35 @@ /* - * Copyright (c) 2003-2007, Haiku, Inc. + * Copyright 2003-2009, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: * Jérôme Duval * François Revol */ -#ifndef VOLUMESLIDER_H -#define VOLUMESLIDER_H +#ifndef VOLUME_SLIDER_H +#define VOLUME_SLIDER_H + #include -#include -#include -#include - -#define VOLUME_USE_MIXER 0 /* default */ -#define VOLUME_USE_PHYS_OUTPUT 1 -class MixerControl { - public: - MixerControl(int32 volumeWhich, float *value = NULL, const char **error = NULL); - ~MixerControl(); - - void UpdateVolume(int32 value); - void ChangeVolumeBy(int32 incr); - private: - media_node *fAudioMixerNode; - BParameterWeb* fParamWeb; - BContinuousParameter* fMixerParam; - float fMin, fMax, fStep; -}; - - -class SliderView : public BControl { - public: - SliderView(BRect rect, BMessage *msg, const char* title, uint32 resizeFlags, - int32 value); - ~SliderView(); - - virtual void Draw(BRect); - virtual void MessageReceived(BMessage*); - virtual void MouseDown(BPoint point); - virtual void MouseMoved(BPoint point, uint32 transit, const BMessage *message); - virtual void MouseUp(BPoint point); - - private: - BBitmap fLeftBitmap, fRightBitmap, fButtonBitmap; - const char* fTitle; -}; +class BSlider; +class MixerControl; class VolumeSlider : public BWindow { - public: - VolumeSlider(BRect frame, bool dontBeep=false, int32 volumeWhich=0); - ~VolumeSlider(); +public: + VolumeSlider(BRect frame, bool dontBeep = false, + int32 volumeWhich = 0); + ~VolumeSlider(); - void MessageReceived(BMessage*); - void WindowActivated(bool active); +protected: + void MessageReceived(BMessage* message); - private: - MixerControl *fMixerControl; - bool fHasChanged; - bool fDontBeep; - SliderView *fSlider; +private: + MixerControl* fMixerControl; + bool fHasChanged; + bool fDontBeep; + BSlider* fSlider; }; -#endif // VOLUMESLIDER_H +#endif // VOLUME_SLIDER_H diff --git a/src/bin/desklink/desklink.cpp b/src/bin/desklink/desklink.cpp index 21e1995613..d76cf706cf 100644 --- a/src/bin/desklink/desklink.cpp +++ b/src/bin/desklink/desklink.cpp @@ -11,9 +11,8 @@ //! VolumeControl and link items in Deskbar -#include "VolumeSlider.h" -#include "DeskButton.h" -#include "iconfile.h" +#include +#include #include #include @@ -33,8 +32,11 @@ #include #include -#include -#include +#include "DeskButton.h" +#include "iconfile.h" +#include "MixerControl.h" +#include "VolumeSlider.h" + #define MEDIA_SETTINGS 'mese' #define SOUND_SETTINGS 'sose' @@ -161,7 +163,7 @@ MediaReplicant::MessageReceived(BMessage *message) case B_ABOUT_REQUESTED: (new BAlert("About Volume Control", "Volume Control (Replicant)\n" " Brought to you by Jérôme DUVAL.\n\n" - "Copyright " B_UTF8_COPYRIGHT "2003-2008, Haiku","OK"))->Go(NULL); + "Copyright " B_UTF8_COPYRIGHT "2003-2009, Haiku","OK"))->Go(NULL); break; case OPEN_MEDIA_PLAYER: @@ -424,6 +426,9 @@ MediaReplicant::_AlertFindDirectory(status_t status, const char *where) } +// #pragma mark - + + int main(int, char **argv) { @@ -455,6 +460,16 @@ main(int, char **argv) return 0; } +#if 0 + if (strcmp(argv[i], "--volume") == 0) { + entry_ref ref; + if (get_ref_for_path(argv[0], &ref) == B_OK) { + deskbar.AddItem(&ref); + } + return 0; + } +#endif + if (strncmp(argv[i], "--remove", 8) == 0) { BString replicant = "DeskButton"; if (strncmp(argv[i] + 8, "=", 1) == 0) { diff --git a/src/bin/desklink/desklink.rdef b/src/bin/desklink/desklink.rdef index d47a0e13a0..986ac02808 100644 --- a/src/bin/desklink/desklink.rdef +++ b/src/bin/desklink/desklink.rdef @@ -15,7 +15,7 @@ resource app_version { internal = 0, short_info = "desklink", - long_info = "desklink ©2003-2007 Haiku" + long_info = "desklink ©2003-2009 Haiku" }; resource app_flags B_MULTIPLE_LAUNCH | B_ARGV_ONLY | B_BACKGROUND_APP ; diff --git a/src/bin/desklink/iconfile.h b/src/bin/desklink/iconfile.h index 5568dd2277..2c8012d578 100644 --- a/src/bin/desklink/iconfile.h +++ b/src/bin/desklink/iconfile.h @@ -29,65 +29,3 @@ const unsigned char kSpeakerBits [] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x0f,0x0f,0xff,0xff,0xff,0xff,0xff }; -const int32 kButtonWidth = 16; -const int32 kButtonHeight = 11; -const color_space kButtonColorSpace = B_CMAP8; - -const unsigned char kButtonBits [] = { - 0xff,0xff,0xff,0x18,0x1d,0x3f,0x1d,0x19,0x12,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0x15,0x1d,0x1e,0x1e,0x1d,0x1e,0x1b,0x19,0x12,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0x1e,0x1e,0x1d,0x1d,0x3f,0x1d,0x1d,0x1b,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x1a,0x1e,0x1d,0x1d,0x1d,0xff,0x1d,0x1d,0x1d,0x19,0x12,0xff,0xff,0xff,0xff,0xff, - 0x1e,0x1e,0x1d,0x1d,0x1d,0x3f,0x1d,0x1d,0x1d,0x19,0x11,0xff,0xff,0xff,0xff,0xff, - 0x3f,0x1d,0x1d,0x1d,0x1d,0xff,0x1d,0x1d,0x1d,0x1c,0x0e,0xff,0xff,0xff,0xff,0xff, - 0x1e,0x1e,0x1d,0x1d,0x1d,0x3f,0x1d,0x1d,0x1d,0x19,0x11,0xff,0xff,0xff,0xff,0xff, - 0x1a,0x1d,0x1d,0x1d,0x1d,0xff,0x1d,0x1d,0x1d,0x15,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0x1a,0x19,0x1d,0x1d,0x1d,0x1d,0x1d,0x17,0x12,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0x16,0xff,0x15,0x19,0x1c,0x19,0x15,0x12,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0x14,0x11,0x0e,0x11,0x14,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff -}; - -const int32 kLeftWidth = 16; -const int32 kLeftHeight = 15; -const color_space kLeftColorSpace = B_CMAP8; - -const unsigned char kLeftBits [] = { - 0xff,0xff,0xff,0xff,0x19,0x19,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0x1a,0x18,0x11,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0x19,0x15,0x0b,0x06,0x0a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x1a,0x15,0x09,0x09,0xb6,0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x18,0x0b,0x09,0x8f,0x8f,0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x11,0x07,0xb6,0x8f,0x8f,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x0c,0x0c,0x8f,0x8f,0x68,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x07,0x10,0x8f,0x68,0x68,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x16,0x12,0x8f,0x68,0x68,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x1a,0x16,0x11,0x68,0x68,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0x1a,0x18,0x68,0x68,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0x1c,0x19,0x68,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0x1d,0x1c,0x19,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0x1d,0x1e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff -}; - -const int32 kRightWidth = 16; -const int32 kRightHeight = 15; -const color_space kRightColorSpace = B_CMAP8; - -const unsigned char kRightBits [] = { - 0x19,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x11,0x18,0x1a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x08,0x0d,0x16,0x1a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x11,0x0c,0x0f,0x17,0x1a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x13,0x13,0x10,0x14,0x19,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x13,0x13,0x13,0x15,0x19,0x1a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x13,0x13,0x13,0x16,0x1a,0x1a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x13,0x13,0x13,0x15,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x13,0x13,0x13,0x19,0x1e,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x13,0x13,0x15,0x1d,0x1d,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x13,0x14,0x1a,0x1e,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x15,0xff,0x3f,0x1d,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x1d,0x1e,0x1d,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x1d,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff -}; -