From ab9873555a6d8ba5ee85bb5e3163780cf44458a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 8 Apr 2009 14:59:25 +0000 Subject: [PATCH] * Restructured the sources a bit, renamed SliderView to VolumeControl, VolumeSlider to VolumeWindow. * The VolumeControl is now a replicant, and be be dragged to the Tracker. * Hence, moved all volume control stuff from VolumeWindow into the VolumeControl class directly. * Changed menu a bit. Note that controlling the physical output currently does not work, but that's a problem of the media node in question (probably the multi audio add-on, I'll have a look). * Added a small delay when clicking on the slider directly before the window is hidden, so that you'll get some feedback of your action. * Added --add-volume, and --volume-control options to "desklink", the former adds the volume control icon to the deskbar, the latter opens the volume control window directly. * Further cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30031 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/bin/desklink/Jamfile | 6 +- src/bin/desklink/MediaReplicant.cpp | 401 +++++++++++++++++++++++++ src/bin/desklink/MixerControl.cpp | 58 ++-- src/bin/desklink/MixerControl.h | 16 +- src/bin/desklink/VolumeControl.cpp | 250 ++++++++++++++++ src/bin/desklink/VolumeControl.h | 48 +++ src/bin/desklink/VolumeSlider.cpp | 238 --------------- src/bin/desklink/VolumeSlider.h | 35 --- src/bin/desklink/VolumeWindow.cpp | 95 ++++++ src/bin/desklink/VolumeWindow.h | 32 ++ src/bin/desklink/desklink.cpp | 435 ++-------------------------- src/bin/desklink/desklink.h | 18 ++ 12 files changed, 914 insertions(+), 718 deletions(-) create mode 100644 src/bin/desklink/MediaReplicant.cpp create mode 100644 src/bin/desklink/VolumeControl.cpp create mode 100644 src/bin/desklink/VolumeControl.h delete mode 100644 src/bin/desklink/VolumeSlider.cpp delete mode 100644 src/bin/desklink/VolumeSlider.h create mode 100644 src/bin/desklink/VolumeWindow.cpp create mode 100644 src/bin/desklink/VolumeWindow.h create mode 100644 src/bin/desklink/desklink.h diff --git a/src/bin/desklink/Jamfile b/src/bin/desklink/Jamfile index 2c668d21de..6637818879 100644 --- a/src/bin/desklink/Jamfile +++ b/src/bin/desklink/Jamfile @@ -2,11 +2,15 @@ SubDir HAIKU_TOP src bin desklink ; SetSubDirSupportedPlatformsBeOSCompatible ; +UsePrivateHeaders app ; + BinCommand desklink : desklink.cpp - VolumeSlider.cpp DeskButton.cpp + MediaReplicant.cpp MixerControl.cpp + VolumeControl.cpp + VolumeWindow.cpp : be libmedia.so : desklink.rdef diff --git a/src/bin/desklink/MediaReplicant.cpp b/src/bin/desklink/MediaReplicant.cpp new file mode 100644 index 0000000000..1ef6124b88 --- /dev/null +++ b/src/bin/desklink/MediaReplicant.cpp @@ -0,0 +1,401 @@ +/* + * Copyright 2003-2009, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Jérôme Duval + * François Revol + * Marcus Overhagen + * Jonas Sundström + * Axel Dörfler, axeld@pinc-software.de. + */ + +//! Volume control, and media shortcuts in Deskbar + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "desklink.h" +#include "iconfile.h" +#include "MixerControl.h" +#include "VolumeWindow.h" + + +static const uint32 kMsgOpenMediaSettings = 'mese'; +static const uint32 kMsgOpenSoundSettings = 'sose'; +static const uint32 kMsgOpenMediaPlayer = 'omep'; +static const uint32 kMsgToggleBeep = 'tdbp'; +static const uint32 kMsgVolumeWhich = 'svwh'; + +static const char* kReplicantName = "MediaReplicant"; + // R5 name needed, Media prefs manel removes by name + +static const char* kSettingsFile = "x-vnd.Haiku-desklink"; + + +class MediaReplicant : public BView { +public: + MediaReplicant(BRect frame, const char* name, + uint32 resizeMask = B_FOLLOW_ALL, + uint32 flags = B_WILL_DRAW | B_NAVIGABLE); + MediaReplicant(BMessage* archive); + + virtual ~MediaReplicant(); + + // archiving overrides + static MediaReplicant* Instantiate(BMessage* data); + virtual status_t Archive(BMessage* data, bool deep = true) const; + + // BView overrides + virtual void AttachedToWindow(); + virtual void MouseDown(BPoint point); + virtual void Draw(BRect updateRect); + virtual void MessageReceived(BMessage* message); + +private: + status_t _LaunchByPath(const char* path); + status_t _LaunchBySignature(const char* signature); + void _Launch(const char* prettyName, + const char* signature, directory_which base, + const char* fileName); + void _LoadSettings(); + void _SaveSettings(); + void _Init(); + + BBitmap* fIcon; + VolumeWindow* fVolumeSlider; + bool fDontBeep; + // don't beep on volume change + int32 fVolumeWhich; + // which volume parameter to act on (Mixer/Phys.Output) +}; + + +MediaReplicant::MediaReplicant(BRect frame, const char* name, + uint32 resizeMask, uint32 flags) + : BView(frame, name, resizeMask, flags), + fVolumeSlider(NULL) +{ + _Init(); +} + + +MediaReplicant::MediaReplicant(BMessage* message) + : BView(message), + fVolumeSlider(NULL) +{ + _Init(); +} + + +MediaReplicant::~MediaReplicant() +{ + delete fIcon; + _SaveSettings(); +} + + +MediaReplicant* +MediaReplicant::Instantiate(BMessage* data) +{ + if (!validate_instantiation(data, kReplicantName)) + return NULL; + + return new(std::nothrow) MediaReplicant(data); +} + + +status_t +MediaReplicant::Archive(BMessage* data, bool deep) const +{ + status_t status = BView::Archive(data, deep); + if (status < B_OK) + return status; + + return data->AddString("add_on", kAppSignature); +} + + +void +MediaReplicant::AttachedToWindow() +{ + BView *parent = Parent(); + if (parent) + SetViewColor(parent->ViewColor()); + + BView::AttachedToWindow(); +} + + +void +MediaReplicant::Draw(BRect rect) +{ + BView::Draw(rect); + + SetDrawingMode(B_OP_OVER); + DrawBitmap(fIcon); +} + + +void +MediaReplicant::MouseDown(BPoint point) +{ + int32 buttons = B_PRIMARY_MOUSE_BUTTON; + if (Looper() != NULL && Looper()->CurrentMessage() != NULL) + Looper()->CurrentMessage()->FindInt32("buttons", &buttons); + + BPoint where = ConvertToScreen(point); + + if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0) { + BPopUpMenu* menu = new BPopUpMenu("", false, false); + menu->SetFont(be_plain_font); + + menu->AddItem(new BMenuItem("Media Preferences" B_UTF8_ELLIPSIS, + new BMessage(kMsgOpenMediaSettings))); + menu->AddItem(new BMenuItem("Sound Preferences" B_UTF8_ELLIPSIS, + new BMessage(kMsgOpenSoundSettings))); + + menu->AddSeparatorItem(); + + menu->AddItem(new BMenuItem("Open MediaPlayer", + new BMessage(kMsgOpenMediaPlayer))); + + menu->AddSeparatorItem(); + + BMenu* subMenu = new BMenu("Options"); + menu->AddItem(subMenu); + + BMenuItem* item = new BMenuItem("Control Physical Output", + new BMessage(kMsgVolumeWhich)); + item->SetMarked(fVolumeWhich == VOLUME_USE_PHYS_OUTPUT); + subMenu->AddItem(item); + + item = new BMenuItem("Beep", new BMessage(kMsgToggleBeep)); + item->SetMarked(!fDontBeep); + subMenu->AddItem(item); + + menu->AddSeparatorItem(); + + menu->AddItem(new BMenuItem("About" B_UTF8_ELLIPSIS, + new BMessage(B_ABOUT_REQUESTED))); + + menu->SetTargetForItems(this); + subMenu->SetTargetForItems(this); + + menu->Go(where, true, true, BRect(where - BPoint(4, 4), + where + BPoint(4, 4))); + } else { + // Show VolumeWindow + fVolumeSlider = new VolumeWindow(BRect(where.x, where.y, + where.x + 207, where.y + 19), fDontBeep, fVolumeWhich); + fVolumeSlider->Show(); + } +} + + +void +MediaReplicant::MessageReceived(BMessage *message) +{ + switch (message->what) { + case B_ABOUT_REQUESTED: + (new BAlert("About Volume Control", "Volume Control\n" + " Brought to you by Jérôme DUVAL.\n\n" + "Copyright " B_UTF8_COPYRIGHT "2003-2009, Haiku", + "OK"))->Go(NULL); + break; + + case kMsgOpenMediaPlayer: + _Launch("MediaPlayer", "application/x-vnd.Haiku-MediaPlayer", + B_SYSTEM_APPS_DIRECTORY, "MediaPlayer"); + break; + + case kMsgOpenMediaSettings: + _Launch("Media Preferences", "application/x-vnd.Haiku-Media", + B_SYSTEM_PREFERENCES_DIRECTORY, "Media"); + break; + + case kMsgOpenSoundSettings: + _Launch("Sounds Preferences", "application/x-vnd.Haiku-Sounds", + B_SYSTEM_PREFERENCES_DIRECTORY, "Sounds"); + break; + + case kMsgToggleBeep: + { + BMenuItem* item; + if (message->FindPointer("source", (void**)&item) != B_OK) + return; + + item->SetMarked(!item->IsMarked()); + fDontBeep = !item->IsMarked(); + break; + } + + case kMsgVolumeWhich: + { + BMenuItem* item; + if (message->FindPointer("source", (void**)&item) != B_OK) + return; + + item->SetMarked(!item->IsMarked()); + fVolumeWhich = item->IsMarked() + ? VOLUME_USE_PHYS_OUTPUT : VOLUME_USE_MIXER; + break; + } + + case B_MOUSE_WHEEL_CHANGED: + { + float deltaY; + if (message->FindFloat("be:wheel_delta_y", &deltaY) == B_OK + && deltaY != 0.0) { + MixerControl mixerControl(fVolumeWhich); + mixerControl.ChangeVolumeBy(deltaY < 0 ? 6 : -6); + } + break; + } + + default: + BView::MessageReceived(message); + break; + } +} + + +status_t +MediaReplicant::_LaunchByPath(const char* path) +{ + entry_ref ref; + status_t status = get_ref_for_path(path, &ref); + if (status != B_OK) + return status; + + status = be_roster->Launch(&ref); + if (status != B_ALREADY_RUNNING) + return status; + + // The application runs already, bring it to front + + app_info appInfo; + status = be_roster->GetAppInfo(&ref, &appInfo); + if (status != B_OK) + return status; + + return be_roster->ActivateApp(appInfo.team); +} + + +status_t +MediaReplicant::_LaunchBySignature(const char* signature) +{ + status_t status = be_roster->Launch(signature); + if (status != B_ALREADY_RUNNING) + return status; + + // The application runs already, bring it to front + + app_info appInfo; + status = be_roster->GetAppInfo(signature, &appInfo); + if (status != B_OK) + return status; + + return be_roster->ActivateApp(appInfo.team); +} + + +void +MediaReplicant::_Launch(const char* prettyName, const char* signature, + directory_which base, const char* fileName) +{ + BPath path; + status_t status = find_directory(base, &path); + if (status == B_OK) + path.Append(fileName); + + // launch the application + if (_LaunchBySignature(signature) != B_OK + && _LaunchByPath(path.Path()) != B_OK) { + BString message = "Couldn't launch "; + message << prettyName; + + (new BAlert("desklink", message.String(), "OK"))->Go(); + } +} + + +void +MediaReplicant::_LoadSettings() +{ + fDontBeep = false; + fVolumeWhich = VOLUME_USE_MIXER; + + BPath path; + if (find_directory(B_USER_SETTINGS_DIRECTORY, &path, false) < B_OK) + return; + + path.Append(kSettingsFile); + + BFile settings(path.Path(), B_READ_ONLY); + if (settings.InitCheck() < B_OK) + return; + + BMessage msg; + if (msg.Unflatten(&settings) < B_OK) + return; + + msg.FindInt32("volwhich", &fVolumeWhich); + msg.FindBool("dontbeep", &fDontBeep); +} + + +void +MediaReplicant::_SaveSettings() +{ + BPath path; + if (find_directory(B_USER_SETTINGS_DIRECTORY, &path, false) < B_OK) + return; + + path.Append(kSettingsFile); + + BFile settings(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); + if (settings.InitCheck() < B_OK) + return; + + BMessage msg('CNFG'); + msg.AddInt32("volwhich", fVolumeWhich); + msg.AddBool("dontbeep", fDontBeep); + + ssize_t size = 0; + msg.Flatten(&settings, &size); +} + + +void +MediaReplicant::_Init() +{ + fIcon = new BBitmap(BRect(0, 0, kSpeakerWidth - 1, kSpeakerHeight - 1), + B_CMAP8); + fIcon->SetBits(kSpeakerBits, kSpeakerWidth*kSpeakerHeight, 0, B_CMAP8); + + _LoadSettings(); +} + + +// #pragma mark - + + +extern "C" BView* +instantiate_deskbar_item(void) +{ + return new MediaReplicant(BRect(0, 0, 16, 16), kReplicantName); +} + diff --git a/src/bin/desklink/MixerControl.cpp b/src/bin/desklink/MixerControl.cpp index c704f50007..ea159747cb 100644 --- a/src/bin/desklink/MixerControl.cpp +++ b/src/bin/desklink/MixerControl.cpp @@ -5,6 +5,7 @@ * Authors: * Jérôme Duval * François Revol + * Axel Dörfler, axeld@pinc-software.de. */ @@ -17,6 +18,7 @@ MixerControl::MixerControl(int32 volumeWhich, float* _value, const char** _error) : + fVolumeWhich(volumeWhich), fAudioMixerNode(NULL), fParameterWeb(NULL), fMixerParameter(NULL), @@ -170,35 +172,15 @@ MixerControl::~MixerControl() } -void -MixerControl::SetVolume(float volume) +int32 +MixerControl::VolumeWhich() const { - 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); + return fVolumeWhich; } float -MixerControl::_GetVolume() +MixerControl::Volume() const { if (fMixerParameter == NULL) return 0.0f; @@ -210,3 +192,31 @@ MixerControl::_GetVolume() return volume; } + + +void +MixerControl::SetVolume(float volume) +{ + if (fMixerParameter == NULL) + return; + + if (volume < fMin) + volume = fMin; + else if (volume > fMax) + volume = fMax; + + if (volume != Volume()) + fMixerParameter->SetValue(&volume, sizeof(float), system_time()); +} + + +void +MixerControl::ChangeVolumeBy(float value) +{ + if (fMixerParameter == NULL || value == 0.0f) + return; + + float volume = Volume(); + SetVolume(volume + value); +} + diff --git a/src/bin/desklink/MixerControl.h b/src/bin/desklink/MixerControl.h index a787ce21fd..8c874277c4 100644 --- a/src/bin/desklink/MixerControl.h +++ b/src/bin/desklink/MixerControl.h @@ -23,10 +23,14 @@ class BContinuousParameter; class MixerControl { public: - MixerControl(int32 volumeWhich, float *value = NULL, - const char **error = NULL); + MixerControl(int32 volumeWhich, + float* _value = NULL, + const char** _error = NULL); ~MixerControl(); + int32 VolumeWhich() const; + float Volume() const; + void SetVolume(float volume); void ChangeVolumeBy(float value); @@ -34,13 +38,13 @@ public: float Maximum() const { return fMax; } private: - float _GetVolume(); - void _SetVolume(float volume); - + int32 fVolumeWhich; media_node* fAudioMixerNode; BParameterWeb* fParameterWeb; BContinuousParameter* fMixerParameter; - float fMin, fMax, fStep; + float fMin; + float fMax; + float fStep; }; #endif // MIXER_CONTROL_H diff --git a/src/bin/desklink/VolumeControl.cpp b/src/bin/desklink/VolumeControl.cpp new file mode 100644 index 0000000000..dc46914181 --- /dev/null +++ b/src/bin/desklink/VolumeControl.cpp @@ -0,0 +1,250 @@ +/* + * Copyright 2003-2009, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Authors: + * Jérôme Duval + * François Revol + * Axel Dörfler, axeld@pinc-software.de. + */ + + +#include "VolumeControl.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "desklink.h" +#include "MixerControl.h" +#include "VolumeWindow.h" + + +VolumeControl::VolumeControl(int32 volumeWhich, bool beep, BMessage* message) + : BSlider("VolumeControl", "Volume", message, 0, 1, B_HORIZONTAL), + fBeep(beep) +{ + 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; + BDragger* dragger = new BDragger(rect, this, + B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); + AddChild(dragger); +} + + +VolumeControl::VolumeControl(BMessage* archive) + : BSlider(archive) +{ + if (archive->FindBool("beep", &fBeep) != B_OK) + fBeep = false; + + int32 volumeWhich; + if (archive->FindInt32("volume which", &volumeWhich) != B_OK) + volumeWhich = VOLUME_USE_MIXER; + + _InitVolume(volumeWhich); +} + + +VolumeControl::~VolumeControl() +{ + delete fMixerControl; +} + + +status_t +VolumeControl::Archive(BMessage* into, bool deep) const +{ + status_t status; + + status = BView::Archive(into, deep); + if (status < B_OK) + return status; + + status = into->AddString("add_on", kAppSignature); + if (status < B_OK) + return status; + + status = into->AddBool("beep", fBeep); + if (status != B_OK) + return status; + + return into->AddInt32("volume which", fMixerControl->VolumeWhich()); +} + + +VolumeControl* +VolumeControl::Instantiate(BMessage* archive) +{ + if (!validate_instantiation(archive, "VolumeControl")) + return NULL; + + return new VolumeControl(archive); +} + + +void +VolumeControl::AttachedToWindow() +{ + BSlider::AttachedToWindow(); + + SetEventMask(_IsReplicant() ? 0 : B_POINTER_EVENTS, B_NO_POINTER_HISTORY); +} + + +void +VolumeControl::MouseDown(BPoint where) +{ + // Ignore clicks on the dragger + int32 viewToken; + if (Bounds().Contains(where) && Looper()->CurrentMessage() != NULL + && Looper()->CurrentMessage()->FindInt32("_view_token", + &viewToken) == B_OK + && viewToken != _get_object_token_(this)) + return; + + // TODO: investigate why this does not work as expected (the dragger + // frame seems to be off) +#if 0 + if (BView* dragger = ChildAt(0)) { + if (!dragger->IsHidden() && dragger->Frame().Contains(where)) + return; + } +#endif + + if (!IsEnabled() || !Bounds().Contains(where)) { + Invoke(); + return; + } + + BSlider::MouseDown(where); +} + + +void +VolumeControl::MessageReceived(BMessage* msg) +{ + switch (msg->what) { + case B_MOUSE_WHEEL_CHANGED: + { + if (Value() == -1) + return; + + // Even though the volume bar is horizontal, we use the more common + // vertical mouse wheel change + float deltaY = 0.0f; + + msg->FindFloat("be:wheel_delta_y", &deltaY); + + if (deltaY == 0.0f) + return; + + int32 currentValue = Value(); + int32 newValue = currentValue - int32(deltaY) * 3; + + if (newValue != currentValue) { + SetValue(newValue); + if (ModificationMessage() != NULL) + Messenger().SendMessage(ModificationMessage()); + } + break; + } + + default: + return BView::MessageReceived(msg); + } +} + + +status_t +VolumeControl::Invoke(BMessage* message = NULL) +{ + if (fBeep && fOriginalValue != Value() && message == NULL) { + beep(); + fOriginalValue = Value(); + } + + fMixerControl->SetVolume(Value()); + + return BSlider::Invoke(message); +} + + +void +VolumeControl::DrawBar() +{ + BRect frame = BarFrame(); + BView* view = OffscreenView(); + + if (be_control_look != NULL) { + uint32 flags = be_control_look->Flags(this); + rgb_color base = LowColor(); + 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(); +} + + +const char* +VolumeControl::UpdateText() const +{ + if (!IsEnabled()) + return NULL; + + snprintf(fText, sizeof(fText), "%ld dB", Value()); + return fText; +} + + +void +VolumeControl::_InitVolume(int32 volumeWhich) +{ + const char* errorString = NULL; + float volume = 0.0; + fMixerControl = new MixerControl(volumeWhich, &volume, &errorString); + + if (errorString != NULL) { + SetLabel(errorString); + SetLimits(-60, 18); + } else { + SetLabel("Volume"); + SetLimits((int32)floorf(fMixerControl->Minimum()), + (int32)ceilf(fMixerControl->Maximum())); + } + + SetEnabled(errorString == NULL); + + fOriginalValue = (int32)volume; + SetValue((int32)volume); +} + + +bool +VolumeControl::_IsReplicant() const +{ + return dynamic_cast(Window()) == NULL; +} diff --git a/src/bin/desklink/VolumeControl.h b/src/bin/desklink/VolumeControl.h new file mode 100644 index 0000000000..423619f25f --- /dev/null +++ b/src/bin/desklink/VolumeControl.h @@ -0,0 +1,48 @@ +/* + * Copyright 2003-2009, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Authors: + * Jérôme Duval + * François Revol + * Axel Dörfler, axeld@pinc-software.de. + */ +#ifndef VOLUME_SLIDER_H +#define VOLUME_SLIDER_H + + +#include + +class MixerControl; + + +class VolumeControl : public BSlider { +public: + VolumeControl(int32 volumeWhich, bool beep, + BMessage* message); + VolumeControl(BMessage* archive); + virtual ~VolumeControl(); + + static VolumeControl* Instantiate(BMessage* archive); + virtual status_t Archive(BMessage* archive, bool deep = true) const; + +protected: + virtual void AttachedToWindow(); + virtual void MouseDown(BPoint where); + virtual void MessageReceived(BMessage* message); + virtual status_t Invoke(BMessage* message = NULL); + + virtual void DrawBar(); + virtual const char* UpdateText() const; + +private: + void _InitVolume(int32 volumeWhich); + bool _IsReplicant() const; + + mutable char fText[64]; + MixerControl* fMixerControl; + int32 fOriginalValue; + bool fBeep; +}; + +#endif // VOLUME_SLIDER_H diff --git a/src/bin/desklink/VolumeSlider.cpp b/src/bin/desklink/VolumeSlider.cpp deleted file mode 100644 index b01e5c3fd7..0000000000 --- a/src/bin/desklink/VolumeSlider.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2003-2009, Haiku, Inc. - * Distributed under the terms of the MIT license. - * - * Authors: - * Jérôme Duval - * François Revol - */ - - -#include "VolumeSlider.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "MixerControl.h" - -#define VOLUME_CHANGED 'vlcg' -#define VOLUME_UPDATED 'vlud' - - -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]; -}; - - - -SliderView::SliderView(const char* name, const char* label, BMessage *message, - int32 minValue, int32 maxValue) - : BSlider("slider", label, message, minValue, maxValue, B_HORIZONTAL) -{ - font_height fontHeight; - GetFontHeight(&fontHeight); - SetBarThickness(ceilf((fontHeight.ascent + fontHeight.descent) * 0.7)); - - SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); -} - - -SliderView::~SliderView() -{ -} - - -void -SliderView::MouseDown(BPoint where) -{ - if (!IsEnabled() || !Bounds().Contains(where)) - Invoke(); - - BSlider::MouseDown(where); -} - - -void -SliderView::MessageReceived(BMessage* msg) -{ - switch (msg->what) { - case B_MOUSE_WHEEL_CHANGED: - { - if (Value() == -1) - return; - - // Even though the volume bar is horizontal, we use the more common - // vertical mouse wheel change - float deltaY = 0.0f; - - msg->FindFloat("be:wheel_delta_y", &deltaY); - - if (deltaY == 0.0f) - return; - - int32 currentValue = Value(); - // deltaY is generally 1 or -1, so this should increase or decrease - // the 0-100 volume value by 5 each time. Also -5 is used because - // mousewheel up is negative but should increase the volume. - int32 newValue = MAX(MIN(currentValue + static_cast(deltaY * -5.0), 100), 0); - - if (newValue != currentValue) { - SetValue(newValue); - Draw(Bounds()); - Flush(); - - if (Window()) - Window()->PostMessage(VOLUME_UPDATED); - } - - break; - } - - default: - return BView::MessageReceived(msg); - } -} - - -void -SliderView::DrawBar() -{ - 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(); -} - - -const char* -SliderView::UpdateText() const -{ - snprintf(fText, sizeof(fText), "%ld dB", Value()); - return fText; -} - - -// #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) -{ - fDontBeep = dontBeep; - - 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 -VolumeSlider::MessageReceived(BMessage *msg) -{ - switch (msg->what) { - case VOLUME_UPDATED: -puts("updated"); - PRINT(("VOLUME_UPDATED\n")); - fMixerControl->SetVolume(fSlider->Value()); - fHasChanged = true; - break; - - 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; - } -} - diff --git a/src/bin/desklink/VolumeSlider.h b/src/bin/desklink/VolumeSlider.h deleted file mode 100644 index 2152ad4d7b..0000000000 --- a/src/bin/desklink/VolumeSlider.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2003-2009, Haiku, Inc. - * Distributed under the terms of the MIT license. - * - * Authors: - * Jérôme Duval - * François Revol - */ -#ifndef VOLUME_SLIDER_H -#define VOLUME_SLIDER_H - - -#include - - -class BSlider; -class MixerControl; - -class VolumeSlider : public BWindow { -public: - VolumeSlider(BRect frame, bool dontBeep = false, - int32 volumeWhich = 0); - ~VolumeSlider(); - -protected: - void MessageReceived(BMessage* message); - -private: - MixerControl* fMixerControl; - bool fHasChanged; - bool fDontBeep; - BSlider* fSlider; -}; - -#endif // VOLUME_SLIDER_H diff --git a/src/bin/desklink/VolumeWindow.cpp b/src/bin/desklink/VolumeWindow.cpp new file mode 100644 index 0000000000..9b4d4baf5b --- /dev/null +++ b/src/bin/desklink/VolumeWindow.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2003-2009, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Authors: + * Jérôme Duval + * François Revol + * Axel Dörfler, axeld@pinc-software.de. + */ + + +#include "VolumeWindow.h" + +#include +#include +#include +#include + +#include "VolumeControl.h" + + +static const uint32 kMsgVolumeUpdate = 'vlup'; +static const uint32 kMsgVolumeChanged = 'vlcg'; + + +VolumeWindow::VolumeWindow(BRect frame, bool dontBeep, int32 volumeWhich) + : BWindow(frame, "VolumeWindow", B_BORDERED_WINDOW_LOOK, + B_FLOATING_ALL_WINDOW_FEEL, + B_ASYNCHRONOUS_CONTROLS | B_WILL_ACCEPT_FIRST_CLICK + | B_AUTO_UPDATE_SIZE_LIMITS, 0), + fUpdatedCount(0) +{ + SetLayout(new BGroupLayout(B_HORIZONTAL)); + + BGroupLayout* layout = new BGroupLayout(B_HORIZONTAL); + layout->SetInsets(5, 5, 5, 5); + + BBox* box = new BBox("sliderbox"); + box->SetLayout(layout); + box->SetBorder(B_PLAIN_BORDER); + AddChild(box); + + BSlider* slider = new VolumeControl(volumeWhich, !dontBeep, + new BMessage(kMsgVolumeChanged)); + slider->SetModificationMessage(new BMessage(kMsgVolumeUpdate)); + box->AddChild(slider); + + slider->SetTarget(this); + 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); +} + + +VolumeWindow::~VolumeWindow() +{ +} + +#include +void +VolumeWindow::MessageReceived(BMessage *msg) +{ + switch (msg->what) { + case kMsgVolumeUpdate: + fUpdatedCount++; + break; + + case kMsgVolumeChanged: + if (fUpdatedCount < 2) { + // If the slider was set by click only, wait a bit until + // closing the window to give some feedback that how volume + // was changed, and that it is. + BMessage quit(B_QUIT_REQUESTED); + BMessageRunner::StartSending(this, &quit, 150000, 1); + } else + Quit(); + break; + + default: + BWindow::MessageReceived(msg); + break; + } +} + diff --git a/src/bin/desklink/VolumeWindow.h b/src/bin/desklink/VolumeWindow.h new file mode 100644 index 0000000000..87c468ce55 --- /dev/null +++ b/src/bin/desklink/VolumeWindow.h @@ -0,0 +1,32 @@ +/* + * Copyright 2003-2009, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Authors: + * Jérôme Duval + * François Revol + * Axel Dörfler, axeld@pinc-software.de. + */ +#ifndef VOLUME_WINDOW_H +#define VOLUME_WINDOW_H + + +#include + +#include "MixerControl.h" + + +class VolumeWindow : public BWindow { +public: + VolumeWindow(BRect frame, bool dontBeep = false, + int32 volumeWhich = VOLUME_USE_MIXER); + virtual ~VolumeWindow(); + +protected: + virtual void MessageReceived(BMessage* message); + +private: + int32 fUpdatedCount; +}; + +#endif // VOLUME_WINDOW_H diff --git a/src/bin/desklink/desklink.cpp b/src/bin/desklink/desklink.cpp index d76cf706cf..9621da998d 100644 --- a/src/bin/desklink/desklink.cpp +++ b/src/bin/desklink/desklink.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008, Haiku. All rights reserved. + * Copyright 2003-2009, Haiku. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -11,424 +11,27 @@ //! VolumeControl and link items in Deskbar +#include "desklink.h" + #include -#include +#include #include #include -#include -#include #include -#include -#include -#include -#include -#include -#include #include -#include -#include #include #include -#include #include "DeskButton.h" -#include "iconfile.h" -#include "MixerControl.h" -#include "VolumeSlider.h" +#include "VolumeWindow.h" -#define MEDIA_SETTINGS 'mese' -#define SOUND_SETTINGS 'sose' -#define OPEN_MEDIA_PLAYER 'omep' -#define TOGGLE_DONT_BEEP 'tdbp' -#define SET_VOLUME_WHICH 'svwh' - -#define VOLUME_CTL_NAME "MediaReplicant" - // R5 name needed, Media prefs manel removes by name - -#define SETTINGS_FILE "x-vnd.Haiku-desklink" - const char *kAppSignature = "application/x-vnd.Haiku-desklink"; // the application signature used by the replicant to find the // supporting code -class _EXPORT MediaReplicant; - // the dragger part has to be exported - -class MediaReplicant : public BView { -public: - MediaReplicant(BRect frame, const char *name, - uint32 resizeMask = B_FOLLOW_ALL, - uint32 flags = B_WILL_DRAW | B_NAVIGABLE); - MediaReplicant(BMessage *); - // BMessage * based constructor needed to support archiving - virtual ~MediaReplicant(); - - // archiving overrides - static MediaReplicant *Instantiate(BMessage *data); - virtual status_t Archive(BMessage *data, bool deep = true) const; - - // misc BView overrides - virtual void AttachedToWindow(); - virtual void MouseDown(BPoint); - virtual void MouseUp(BPoint); - virtual void Draw(BRect updateRect); - virtual void MessageReceived(BMessage* message); - -private: - void _AlertFindDirectory(status_t status, const char *where); - status_t _LaunchByPath(const char *path); - status_t _LaunchBySig(const char *sig); - void _LoadSettings(); - void _SaveSettings(); - - BBitmap* fSegments; - VolumeSlider* fVolumeSlider; - bool fDontBeep; - // don't beep on volume change - int32 fVolumeWhich; - // which volume parameter to act on (Mixer/Phys.Output) -}; - -// -// This is the exported function that will be used by Deskbar -// to create and add the replicant -// -extern "C" _EXPORT BView* instantiate_deskbar_item(); - -BView * -instantiate_deskbar_item() -{ - return new MediaReplicant(BRect(0, 0, 16, 16), VOLUME_CTL_NAME); -} - - -MediaReplicant::MediaReplicant(BRect frame, const char *name, - uint32 resizeMask, uint32 flags) - : BView(frame, name, resizeMask, flags), - fVolumeSlider(NULL) -{ - // Background Bitmap - fSegments = new BBitmap(BRect(0, 0, kSpeakerWidth - 1, kSpeakerHeight - 1), B_CMAP8); - fSegments->SetBits(kSpeakerBits, kSpeakerWidth*kSpeakerHeight, 0, B_CMAP8); - _LoadSettings(); -} - - -MediaReplicant::MediaReplicant(BMessage *message) - : BView(message), - fVolumeSlider(NULL) -{ - // Background Bitmap - fSegments = new BBitmap(BRect(0, 0, 16 - 1, 16 - 1), B_CMAP8); - fSegments->SetBits(kSpeakerBits, 16*16, 0, B_CMAP8); - _LoadSettings(); -} - - -MediaReplicant::~MediaReplicant() -{ - delete fSegments; - _SaveSettings(); -} - - -MediaReplicant * -MediaReplicant::Instantiate(BMessage *data) -{ - if (!validate_instantiation(data, VOLUME_CTL_NAME)) - return NULL; - - return new MediaReplicant(data); -} - - -status_t -MediaReplicant::Archive(BMessage *data, bool deep) const -{ - status_t status = BView::Archive(data, deep); - if (status < B_OK) - return status; - - return data->AddString("add_on", kAppSignature); -} - - -void -MediaReplicant::MessageReceived(BMessage *message) -{ - switch (message->what) { - 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-2009, Haiku","OK"))->Go(NULL); - break; - - case OPEN_MEDIA_PLAYER: - { - BPath mediaPlayerPath; - status_t status = find_directory(B_BEOS_APPS_DIRECTORY, &mediaPlayerPath); - if (status != B_OK) { - _AlertFindDirectory(status, __PRETTY_FUNCTION__); - break; - } - mediaPlayerPath.Append("MediaPlayer"); - - // launch the media player app - if (_LaunchBySig("application/x-vnd.Haiku-MediaPlayer") == B_OK - || _LaunchBySig("application/x-vnd.Be.MediaPlayer") == B_OK - || _LaunchByPath(mediaPlayerPath.Path()) == B_OK) - break; - - (new BAlert("desklink", "Couldn't launch MediaPlayer", "OK"))->Go(); - break; - } - - case MEDIA_SETTINGS: - { - BPath mediaPrefsPath; - status_t status = find_directory(B_BEOS_PREFERENCES_DIRECTORY, - &mediaPrefsPath); - if (status != B_OK) { - _AlertFindDirectory(status, __PRETTY_FUNCTION__); - break; - } - mediaPrefsPath.Append("Media"); - - // launch the media prefs app - if (_LaunchBySig("application/x-vnd.Haiku-Media") == B_OK - || _LaunchBySig("application/x-vnd.Be.MediaPrefs") == B_OK - || _LaunchByPath(mediaPrefsPath.Path()) == B_OK) - break; - - (new BAlert("desklink", "Couldn't launch Media Preferences", "OK"))->Go(); - break; - } - - case SOUND_SETTINGS: - { - BPath soundsPrefsPath; - status_t status = find_directory(B_BEOS_PREFERENCES_DIRECTORY, - &soundsPrefsPath); - if (status != B_OK) { - _AlertFindDirectory(status, __PRETTY_FUNCTION__); - break; - } - soundsPrefsPath.Append("Sounds"); - - // launch the sounds prefs app - if (_LaunchBySig("application/x-vnd.Haiku-Sounds") == B_OK - || _LaunchBySig("application/x-vnd.Be.SoundsPrefs") == B_OK - || _LaunchByPath(soundsPrefsPath.Path()) == B_OK) - break; - - (new BAlert("desklink", "Couldn't launch Sounds Preferences", "OK"))->Go(); - break; - } - - case TOGGLE_DONT_BEEP: - fDontBeep = !fDontBeep; - break; - - case SET_VOLUME_WHICH: - message->FindInt32("volwhich", &fVolumeWhich); - break; - - case B_MOUSE_WHEEL_CHANGED: - { - float dy; - if (message->FindFloat("be:wheel_delta_y", &dy) == B_OK - && dy != 0.0) { - MixerControl mixerControl(fVolumeWhich); - mixerControl.ChangeVolumeBy(dy < 0 ? 20 : -20); - } - break; - } - default: - BView::MessageReceived(message); - break; - } -} - - -status_t -MediaReplicant::_LaunchByPath(const char *path) -{ - BEntry ent; - entry_ref ref; - app_info appInfo; - status_t err; - - err = ent.SetTo(path); - if (err) - return err; - err = ent.GetRef(&ref); - if (err) - return err; - err = be_roster->Launch(&ref); - if (err != B_ALREADY_RUNNING) - return err; // should be B_OK or fatal error - err = be_roster->GetAppInfo(&ref, &appInfo); - if (err) - return err; - return be_roster->ActivateApp(appInfo.team); -} - - -status_t -MediaReplicant::_LaunchBySig(const char *sig) -{ - app_info appInfo; - status_t err; - - err = be_roster->Launch(sig); - if (err != B_ALREADY_RUNNING) - return err; // should be B_OK or fatal error - err = be_roster->GetAppInfo(sig, &appInfo); - if (err) - return err; - return be_roster->ActivateApp(appInfo.team); -} - - -void -MediaReplicant::AttachedToWindow() -{ - BView *parent = Parent(); - if (parent) - SetViewColor(parent->ViewColor()); - - BView::AttachedToWindow(); -} - - -void -MediaReplicant::Draw(BRect rect) -{ - BView::Draw(rect); - - SetDrawingMode(B_OP_OVER); - DrawBitmap(fSegments); -} - - -void -MediaReplicant::MouseDown(BPoint point) -{ - uint32 mouseButtons; - BPoint where; - GetMouse(&where, &mouseButtons, true); - - where = ConvertToScreen(point); - - if (mouseButtons & B_SECONDARY_MOUSE_BUTTON) { - BPopUpMenu *menu = new BPopUpMenu("", false, false); - menu->SetFont(be_plain_font); - menu->AddItem(new BMenuItem("Media Preferences" B_UTF8_ELLIPSIS, new BMessage(MEDIA_SETTINGS))); - menu->AddItem(new BMenuItem("Sound Preferences" B_UTF8_ELLIPSIS, new BMessage(SOUND_SETTINGS))); - menu->AddSeparatorItem(); - menu->AddItem(new BMenuItem("Open MediaPlayer", new BMessage(OPEN_MEDIA_PLAYER))); - menu->AddSeparatorItem(); - BMenuItem *tmpItem = new BMenuItem("Don't beep", new BMessage(TOGGLE_DONT_BEEP)); - menu->AddItem(tmpItem); - tmpItem->SetMarked(fDontBeep); - BMenu *volMenu = new BMenu("Act On"); - volMenu->SetFont(be_plain_font); - BMessage *msg; - msg = new BMessage(SET_VOLUME_WHICH); - msg->AddInt32("volwhich", VOLUME_USE_MIXER); - tmpItem = new BMenuItem("System Mixer", msg); - tmpItem->SetMarked(fVolumeWhich == VOLUME_USE_MIXER); - volMenu->AddItem(tmpItem); - msg = new BMessage(SET_VOLUME_WHICH); - msg->AddInt32("volwhich", VOLUME_USE_PHYS_OUTPUT); - tmpItem = new BMenuItem("Physical Output", msg); - volMenu->AddItem(tmpItem); - tmpItem->SetMarked(fVolumeWhich == VOLUME_USE_PHYS_OUTPUT); - menu->AddItem(volMenu); - - menu->AddSeparatorItem(); - menu->SetFont(be_plain_font); - menu->AddItem(new BMenuItem("About" B_UTF8_ELLIPSIS, - new BMessage(B_ABOUT_REQUESTED))); - - menu->SetTargetForItems(this); - volMenu->SetTargetForItems(this); - menu->Go(where, true, true, BRect(where - BPoint(4, 4), - where + BPoint(4, 4))); - } else if (mouseButtons & B_PRIMARY_MOUSE_BUTTON) { - // Show VolumeSlider - fVolumeSlider = new VolumeSlider(BRect(where.x, where.y, where.x + 207, where.y + 19), - fDontBeep, fVolumeWhich); - fVolumeSlider->Show(); - } -} - - -void -MediaReplicant::MouseUp(BPoint point) -{ - // don't Quit() ! thanks for FFM users -} - - -void -MediaReplicant::_LoadSettings() -{ - fDontBeep = false; - fVolumeWhich = VOLUME_USE_MIXER; - - BPath p; - if (find_directory(B_USER_SETTINGS_DIRECTORY, &p, false) < B_OK) - return; - p.SetTo(p.Path(), SETTINGS_FILE); - BFile settings(p.Path(), B_READ_ONLY); - if (settings.InitCheck() < B_OK) - return; - BMessage msg; - if (msg.Unflatten(&settings) < B_OK) - return; - msg.FindInt32("volwhich", &fVolumeWhich); - msg.FindBool("dontbeep", &fDontBeep); -} - - -void -MediaReplicant::_SaveSettings() -{ - BPath p; - if (find_directory(B_USER_SETTINGS_DIRECTORY, &p, false) < B_OK) - return; - p.SetTo(p.Path(), SETTINGS_FILE); - BFile settings(p.Path(), B_WRITE_ONLY|B_CREATE_FILE|B_ERASE_FILE); - if (settings.InitCheck() < B_OK) - return; - BMessage msg('CNFG'); - msg.AddInt32("volwhich", fVolumeWhich); - msg.AddBool("dontbeep", fDontBeep); - ssize_t len=0; - if (msg.Flatten(&settings, &len) < B_OK) - return; -} - - -void -MediaReplicant::_AlertFindDirectory(status_t status, const char *where) -{ - BString errorMessage; - errorMessage << "At " << where << "\n"; - errorMessage << "find_directory() failed. \nReason: "; - errorMessage << strerror(status); - (new BAlert("AlertError", errorMessage.String(), "OK", NULL, NULL, - B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go(); -} - - -// #pragma mark - - - int main(int, char **argv) { @@ -444,31 +47,35 @@ main(int, char **argv) break; if (strcmp(argv[i], "--list") == 0) { - int32 i, found = 0, count; - count = deskbar.CountItems(); + int32 count = deskbar.CountItems(); + printf("Deskbar items:\n"); - // the API is doomed, so don't try to enum for too long - for (i = 0; (found < count) && (i >= 0) && (i < 5000); i++) { - const char scratch[2] = ""; // BDeskbar is buggy - const char *name=scratch; - if (deskbar.GetItemInfo(i, &name) >= B_OK) { - found++; + + for (int32 i = 0; i < count; i++) { + const char *name = NULL; + if (deskbar.GetItemInfo(i, &name) == B_OK) { printf("Item %ld: '%s'\n", i, name); - free((void *)name); // INTENDED + free((void *)name); } } return 0; } -#if 0 - if (strcmp(argv[i], "--volume") == 0) { + if (strcmp(argv[i], "--add-volume") == 0) { entry_ref ref; if (get_ref_for_path(argv[0], &ref) == B_OK) { deskbar.AddItem(&ref); } return 0; } -#endif + + if (strcmp(argv[i], "--volume-control") == 0) { + BWindow* window = new VolumeWindow(BRect(200, 150, 400, 200)); + window->Show(); + + wait_for_thread(window->Thread(), NULL); + return 0; + } if (strncmp(argv[i], "--remove", 8) == 0) { BString replicant = "DeskButton"; diff --git a/src/bin/desklink/desklink.h b/src/bin/desklink/desklink.h new file mode 100644 index 0000000000..577edcd21b --- /dev/null +++ b/src/bin/desklink/desklink.h @@ -0,0 +1,18 @@ +/* + * Copyright 2003-2009, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Jérôme Duval + * François Revol + * Marcus Overhagen + * Jonas Sundström + */ +#ifndef DESKLINK_H +#define DESKLINK_H + + +extern const char *kAppSignature; + + +#endif // DESKLINK_H