Updated the resource signature to match the app's signature
Utilize CDDB lookups Use display controls look similar to LED panels on CD players Window is resizable and controls respond appropriately Added support to display elapsed time, both for the CD and the current track Numerous little bugfixes git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13294 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+252
-49
@@ -24,6 +24,9 @@
|
|||||||
#include "CDButton.h"
|
#include "CDButton.h"
|
||||||
#include "DrawButton.h"
|
#include "DrawButton.h"
|
||||||
#include <TranslationUtils.h>
|
#include <TranslationUtils.h>
|
||||||
|
#include <TranslatorFormats.h>
|
||||||
|
#include <TranslatorRoster.h>
|
||||||
|
#include <BitmapStream.h>
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -42,9 +45,15 @@ enum
|
|||||||
};
|
};
|
||||||
|
|
||||||
CDButton::CDButton(BRect frame, const char *name, uint32 resizeMask, uint32 flags)
|
CDButton::CDButton(BRect frame, const char *name, uint32 resizeMask, uint32 flags)
|
||||||
: BView(frame, name, resizeMask, flags)
|
: BView(frame, name, resizeMask, flags | B_FRAME_EVENTS)
|
||||||
{
|
{
|
||||||
|
// This will eventually one of a few preferences - to stop playing music
|
||||||
|
// when the app is closed
|
||||||
|
fStopOnQuit = false;
|
||||||
|
|
||||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
|
||||||
|
// TODO: Support multiple CD drives
|
||||||
engine = new CDEngine(CDEngine::FindCDPlayerDevice());
|
engine = new CDEngine(CDEngine::FindCDPlayerDevice());
|
||||||
|
|
||||||
BuildGUI();
|
BuildGUI();
|
||||||
@@ -65,34 +74,69 @@ CDButton::CDButton(BRect frame, const char *name, uint32 resizeMask, uint32 flag
|
|||||||
|
|
||||||
CDButton::~CDButton()
|
CDButton::~CDButton()
|
||||||
{
|
{
|
||||||
|
if(fStopOnQuit)
|
||||||
|
engine->Stop();
|
||||||
|
|
||||||
delete engine;
|
delete engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDButton::BuildGUI(void)
|
void CDButton::BuildGUI(void)
|
||||||
{
|
{
|
||||||
fCDTitle = new BTextControl( BRect(5,5,230,30), "CDTitle","","",new BMessage(M_SET_CD_TITLE));
|
BRect r(5,5,230,25);
|
||||||
AddChild(fCDTitle);
|
|
||||||
fCDTitle->SetDivider(0);
|
|
||||||
fCDTitle->TextView()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
|
||||||
|
|
||||||
BBox *box = new BBox(BRect(0,0,75,20),"TrackBox");
|
// Assemble the CD Title box
|
||||||
box->MoveTo(fCDTitle->Frame().right + 15, 5);
|
fCDBox = new BBox(r,"TrackBox");
|
||||||
AddChild(box);
|
AddChild(fCDBox);
|
||||||
|
|
||||||
BView *view = new BView( box->Bounds().InsetByCopy(2,2), "view",B_FOLLOW_NONE,B_WILL_DRAW);
|
BView *view = new BView( fCDBox->Bounds().InsetByCopy(2,2), "view",B_FOLLOW_ALL,B_WILL_DRAW);
|
||||||
view->SetViewColor(0,0,0);
|
view->SetViewColor(20,20,20);
|
||||||
box->AddChild(view);
|
fCDBox->AddChild(view);
|
||||||
|
|
||||||
fTrackNumber = new BStringView( view->Bounds(),"TrackNumber","Track: --");
|
fCDTitle = new BStringView(view->Bounds(),"CDTitle","");
|
||||||
view->AddChild(fTrackNumber);
|
view->AddChild(fCDTitle);
|
||||||
fTrackNumber->SetAlignment(B_ALIGN_CENTER);
|
fCDTitle->SetHighColor(200,200,200);
|
||||||
fTrackNumber->SetHighColor(0,255,0);
|
fCDTitle->SetFont(be_bold_font);
|
||||||
fTrackNumber->SetFont(be_bold_font);
|
|
||||||
|
|
||||||
fVolume = new BSlider( BRect(0,0,75,30), "VolumeSlider", "Volume", new BMessage(M_SET_VOLUME),0,100);
|
r.Set(fCDTitle->Frame().right + 15,5,Bounds().right - 5,25);
|
||||||
|
fTrackBox = new BBox(r,"TrackBox",B_FOLLOW_TOP);
|
||||||
|
AddChild(fTrackBox);
|
||||||
|
|
||||||
|
view = new BView( fTrackBox->Bounds().InsetByCopy(2,2), "view",B_FOLLOW_ALL,B_WILL_DRAW);
|
||||||
|
view->SetViewColor(0,34,7);
|
||||||
|
fTrackBox->AddChild(view);
|
||||||
|
|
||||||
|
fCurrentTrack = new BStringView( view->Bounds(),"TrackNumber","Track:",B_FOLLOW_ALL);
|
||||||
|
view->AddChild(fCurrentTrack);
|
||||||
|
fCurrentTrack->SetHighColor(40,230,40);
|
||||||
|
fCurrentTrack->SetFont(be_bold_font);
|
||||||
|
|
||||||
|
r.OffsetBy(0, r.Height() + 5);
|
||||||
|
fTimeBox = new BBox(r,"TimeBox",B_FOLLOW_LEFT_RIGHT);
|
||||||
|
AddChild(fTimeBox);
|
||||||
|
|
||||||
|
view = new BView( fTimeBox->Bounds().InsetByCopy(2,2), "view",B_FOLLOW_ALL,B_WILL_DRAW);
|
||||||
|
view->SetViewColor(0,7,34);
|
||||||
|
fTimeBox->AddChild(view);
|
||||||
|
|
||||||
|
r = view->Bounds();
|
||||||
|
r.right /= 2;
|
||||||
|
|
||||||
|
fTrackTime = new BStringView(r,"TrackTime","Track --:-- / --:--",B_FOLLOW_LEFT_RIGHT);
|
||||||
|
view->AddChild(fTrackTime);
|
||||||
|
fTrackTime->SetHighColor(120,120,255);
|
||||||
|
fTrackTime->SetFont(be_bold_font);
|
||||||
|
|
||||||
|
r.right = view->Bounds().right;
|
||||||
|
r.left = fTrackTime->Frame().right + 1;
|
||||||
|
|
||||||
|
fDiscTime = new BStringView(r,"DiscTime","Disc --:-- / --:--",B_FOLLOW_RIGHT);
|
||||||
|
view->AddChild(fDiscTime);
|
||||||
|
fDiscTime->SetHighColor(120,120,255);
|
||||||
|
fDiscTime->SetFont(be_bold_font);
|
||||||
|
|
||||||
|
fVolume = new BSlider( BRect(0,0,75,30), "VolumeSlider", "Volume", new BMessage(M_SET_VOLUME),0,255);
|
||||||
fVolume->MoveTo(5, Bounds().bottom - 10 - fVolume->Frame().Height());
|
fVolume->MoveTo(5, Bounds().bottom - 10 - fVolume->Frame().Height());
|
||||||
AddChild(fVolume);
|
AddChild(fVolume);
|
||||||
fVolume->SetEnabled(false);
|
|
||||||
|
|
||||||
fStop = new DrawButton( BRect(0,0,1,1), "Stop", BTranslationUtils::GetBitmap('PNG ',"stop_up"),
|
fStop = new DrawButton( BRect(0,0,1,1), "Stop", BTranslationUtils::GetBitmap('PNG ',"stop_up"),
|
||||||
BTranslationUtils::GetBitmap('PNG ',"stop_down"), new BMessage(M_STOP),
|
BTranslationUtils::GetBitmap('PNG ',"stop_down"), new BMessage(M_STOP),
|
||||||
@@ -154,7 +198,7 @@ void CDButton::BuildGUI(void)
|
|||||||
|
|
||||||
fSave = new DrawButton( BRect(0,0,1,1), "Save", BTranslationUtils::GetBitmap('PNG ',"save_up"),
|
fSave = new DrawButton( BRect(0,0,1,1), "Save", BTranslationUtils::GetBitmap('PNG ',"save_up"),
|
||||||
BTranslationUtils::GetBitmap('PNG ',"save_down"), new BMessage(M_SAVE),
|
BTranslationUtils::GetBitmap('PNG ',"save_down"), new BMessage(M_SAVE),
|
||||||
B_FOLLOW_BOTTOM, B_WILL_DRAW);
|
B_FOLLOW_NONE, B_WILL_DRAW);
|
||||||
fSave->ResizeToPreferred();
|
fSave->ResizeToPreferred();
|
||||||
fSave->MoveTo(fEject->Frame().right + 20, Bounds().bottom - 5 - fSave->Frame().Height());
|
fSave->MoveTo(fEject->Frame().right + 20, Bounds().bottom - 5 - fSave->Frame().Height());
|
||||||
fSave->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"save_disabled"));
|
fSave->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"save_disabled"));
|
||||||
@@ -164,7 +208,7 @@ void CDButton::BuildGUI(void)
|
|||||||
// TODO: Shuffle and Repeat are special buttons. Implement as two-state buttons
|
// TODO: Shuffle and Repeat are special buttons. Implement as two-state buttons
|
||||||
fShuffle = new DrawButton( BRect(0,0,1,1), "Shuffle", BTranslationUtils::GetBitmap('PNG ',"shuffle_up"),
|
fShuffle = new DrawButton( BRect(0,0,1,1), "Shuffle", BTranslationUtils::GetBitmap('PNG ',"shuffle_up"),
|
||||||
BTranslationUtils::GetBitmap('PNG ',"shuffle_down"), new BMessage(M_SHUFFLE),
|
BTranslationUtils::GetBitmap('PNG ',"shuffle_down"), new BMessage(M_SHUFFLE),
|
||||||
B_FOLLOW_BOTTOM, B_WILL_DRAW);
|
B_FOLLOW_NONE, B_WILL_DRAW);
|
||||||
fShuffle->ResizeToPreferred();
|
fShuffle->ResizeToPreferred();
|
||||||
fShuffle->MoveTo(fSave->Frame().right + 2, Bounds().bottom - 5 - fShuffle->Frame().Height());
|
fShuffle->MoveTo(fSave->Frame().right + 2, Bounds().bottom - 5 - fShuffle->Frame().Height());
|
||||||
fShuffle->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"shuffle_disabled"));
|
fShuffle->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"shuffle_disabled"));
|
||||||
@@ -173,7 +217,7 @@ void CDButton::BuildGUI(void)
|
|||||||
|
|
||||||
fRepeat = new DrawButton( BRect(0,0,1,1), "Repeat", BTranslationUtils::GetBitmap('PNG ',"repeat_up"),
|
fRepeat = new DrawButton( BRect(0,0,1,1), "Repeat", BTranslationUtils::GetBitmap('PNG ',"repeat_up"),
|
||||||
BTranslationUtils::GetBitmap('PNG ',"repeat_down"), new BMessage(M_REPEAT),
|
BTranslationUtils::GetBitmap('PNG ',"repeat_down"), new BMessage(M_REPEAT),
|
||||||
B_FOLLOW_BOTTOM, B_WILL_DRAW);
|
B_FOLLOW_NONE, B_WILL_DRAW);
|
||||||
fRepeat->ResizeToPreferred();
|
fRepeat->ResizeToPreferred();
|
||||||
fRepeat->MoveTo(fShuffle->Frame().right + 2, Bounds().bottom - 5 - fRepeat->Frame().Height());
|
fRepeat->MoveTo(fShuffle->Frame().right + 2, Bounds().bottom - 5 - fRepeat->Frame().Height());
|
||||||
fRepeat->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"repeat_disabled"));
|
fRepeat->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"repeat_disabled"));
|
||||||
@@ -183,13 +227,72 @@ void CDButton::BuildGUI(void)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CDButton::MessageReceived(BMessage *message)
|
CDButton::MessageReceived(BMessage *msg)
|
||||||
{
|
{
|
||||||
switch (message->what)
|
if(msg->WasDropped())
|
||||||
|
{
|
||||||
|
// We'll handle two types of drops: those from Tracker and those from ShowImage
|
||||||
|
if(msg->what==B_SIMPLE_DATA)
|
||||||
|
{
|
||||||
|
int32 actions;
|
||||||
|
if(msg->FindInt32("be:actions",&actions)==B_OK)
|
||||||
|
{
|
||||||
|
// ShowImage drop. This is a negotiated drag&drop, so send a reply
|
||||||
|
BMessage reply(B_COPY_TARGET), response;
|
||||||
|
reply.AddString("be:types","image/jpeg");
|
||||||
|
reply.AddString("be:types","image/png");
|
||||||
|
|
||||||
|
msg->SendReply(&reply,&response);
|
||||||
|
|
||||||
|
// now, we've gotten the response
|
||||||
|
if(response.what==B_MIME_DATA)
|
||||||
|
{
|
||||||
|
// Obtain and translate the received data
|
||||||
|
uint8 *imagedata;
|
||||||
|
ssize_t datasize;
|
||||||
|
|
||||||
|
// Try JPEG first
|
||||||
|
if(response.FindData("image/jpeg",B_MIME_DATA,(const void **)&imagedata,&datasize)!=B_OK)
|
||||||
|
{
|
||||||
|
// Try PNG next and piddle out if unsuccessful
|
||||||
|
if(response.FindData("image/png",B_PNG_FORMAT,(const void **)&imagedata,&datasize)!=B_OK)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up to decode into memory
|
||||||
|
BMemoryIO memio(imagedata,datasize);
|
||||||
|
BTranslatorRoster *roster=BTranslatorRoster::Default();
|
||||||
|
BBitmapStream bstream;
|
||||||
|
|
||||||
|
if(roster->Translate(&memio,NULL,NULL,&bstream, B_TRANSLATOR_BITMAP)==B_OK)
|
||||||
|
{
|
||||||
|
BBitmap *bmp;
|
||||||
|
if(bstream.DetachBitmap(&bmp)!=B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SetBitmap(bmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_ref ref;
|
||||||
|
if(msg->FindRef("refs",&ref)==B_OK)
|
||||||
|
{
|
||||||
|
// Tracker drop
|
||||||
|
BBitmap *bmp=BTranslationUtils::GetBitmap(&ref);
|
||||||
|
SetBitmap(bmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (msg->what)
|
||||||
{
|
{
|
||||||
case M_SET_VOLUME:
|
case M_SET_VOLUME:
|
||||||
{
|
{
|
||||||
// TODO: Implement
|
// TODO: Implement
|
||||||
|
engine->SetVolume(fVolume->Value());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case M_STOP:
|
case M_STOP:
|
||||||
@@ -245,10 +348,10 @@ CDButton::MessageReceived(BMessage *message)
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!Observer::HandleObservingMessages(message))
|
if (!Observer::HandleObservingMessages(msg))
|
||||||
{
|
{
|
||||||
// just support observing messages
|
// just support observing messages
|
||||||
BView::MessageReceived(message);
|
BView::MessageReceived(msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -258,17 +361,17 @@ CDButton::MessageReceived(BMessage *message)
|
|||||||
void
|
void
|
||||||
CDButton::NoticeChange(Notifier *notifier)
|
CDButton::NoticeChange(Notifier *notifier)
|
||||||
{
|
{
|
||||||
// debugger("");
|
|
||||||
|
|
||||||
PlayState *ps;
|
PlayState *ps;
|
||||||
TrackState *trs;
|
TrackState *trs;
|
||||||
TimeState *tms;
|
TimeState *tms;
|
||||||
CDContentWatcher *ccw;
|
CDContentWatcher *ccw;
|
||||||
|
VolumeState *vs;
|
||||||
|
|
||||||
ps = dynamic_cast<PlayState *>(notifier);
|
ps = dynamic_cast<PlayState *>(notifier);
|
||||||
trs = dynamic_cast<TrackState *>(notifier);
|
trs = dynamic_cast<TrackState *>(notifier);
|
||||||
tms = dynamic_cast<TimeState *>(notifier);
|
tms = dynamic_cast<TimeState *>(notifier);
|
||||||
ccw = dynamic_cast<CDContentWatcher *>(notifier);
|
ccw = dynamic_cast<CDContentWatcher *>(notifier);
|
||||||
|
vs = dynamic_cast<VolumeState *>(notifier);
|
||||||
|
|
||||||
if(ps)
|
if(ps)
|
||||||
{
|
{
|
||||||
@@ -286,6 +389,10 @@ CDButton::NoticeChange(Notifier *notifier)
|
|||||||
fRewind->SetEnabled(false);
|
fRewind->SetEnabled(false);
|
||||||
fSave->SetEnabled(false);
|
fSave->SetEnabled(false);
|
||||||
}
|
}
|
||||||
|
fCurrentTrack->SetText("Track: ");
|
||||||
|
fTrackTime->SetText("Track --:-- / --:--");
|
||||||
|
fDiscTime->SetText("Disc --:-- / --:--");
|
||||||
|
printf("Notification: No CD\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kStopped:
|
case kStopped:
|
||||||
@@ -300,6 +407,10 @@ CDButton::NoticeChange(Notifier *notifier)
|
|||||||
fRewind->SetEnabled(true);
|
fRewind->SetEnabled(true);
|
||||||
fSave->SetEnabled(true);
|
fSave->SetEnabled(true);
|
||||||
}
|
}
|
||||||
|
fCurrentTrack->SetText("Track: ");
|
||||||
|
fTrackTime->SetText("Track --:-- / --:--");
|
||||||
|
fDiscTime->SetText("Disc --:-- / --:--");
|
||||||
|
printf("Notification: CD Stopped\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kPaused:
|
case kPaused:
|
||||||
@@ -315,7 +426,7 @@ CDButton::NoticeChange(Notifier *notifier)
|
|||||||
fRewind->SetEnabled(true);
|
fRewind->SetEnabled(true);
|
||||||
fSave->SetEnabled(true);
|
fSave->SetEnabled(true);
|
||||||
}
|
}
|
||||||
UpdateTrackInfo();
|
printf("Notification: CD Paused\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kPlaying:
|
case kPlaying:
|
||||||
@@ -330,7 +441,7 @@ CDButton::NoticeChange(Notifier *notifier)
|
|||||||
fRewind->SetEnabled(true);
|
fRewind->SetEnabled(true);
|
||||||
fSave->SetEnabled(true);
|
fSave->SetEnabled(true);
|
||||||
}
|
}
|
||||||
UpdateTrackInfo();
|
printf("Notification: CD Playing\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSkipping:
|
case kSkipping:
|
||||||
@@ -345,6 +456,7 @@ CDButton::NoticeChange(Notifier *notifier)
|
|||||||
fRewind->SetEnabled(true);
|
fRewind->SetEnabled(true);
|
||||||
fSave->SetEnabled(true);
|
fSave->SetEnabled(true);
|
||||||
}
|
}
|
||||||
|
printf("Notification: CD Skipping\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -356,34 +468,69 @@ CDButton::NoticeChange(Notifier *notifier)
|
|||||||
else
|
else
|
||||||
if(trs)
|
if(trs)
|
||||||
{
|
{
|
||||||
UpdateTrackInfo();
|
UpdateCDInfo();
|
||||||
|
|
||||||
// TODO: Update track count indicator
|
// TODO: Update track count indicator
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(tms)
|
if(tms)
|
||||||
{
|
{
|
||||||
|
UpdateTimeInfo();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(ccw)
|
if(ccw)
|
||||||
{
|
{
|
||||||
|
UpdateCDInfo();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(vs)
|
||||||
|
{
|
||||||
|
fVolume->SetValue(engine->VolumeStateWatcher()->GetVolume());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CDButton::UpdateTrackInfo(void)
|
CDButton::UpdateCDInfo(void)
|
||||||
{
|
{
|
||||||
|
BString CDName, currentTrackName;
|
||||||
fCurrentTrack=engine->TrackStateWatcher()->GetTrack();
|
vector<BString> trackNames;
|
||||||
fTrackCount=engine->TrackStateWatcher()->GetNumTracks();
|
|
||||||
|
|
||||||
if(fCurrentTrack < 1)
|
int32 currentTrack = engine->TrackStateWatcher()->GetTrack();
|
||||||
|
engine->ContentWatcher()->GetContent(&CDName,&trackNames);
|
||||||
|
|
||||||
|
fCDTitle->SetText(CDName.String());
|
||||||
|
|
||||||
|
if(currentTrack > 0)
|
||||||
{
|
{
|
||||||
char string[255];
|
currentTrackName << "Track " << currentTrack << ": " << trackNames[ currentTrack - 1];
|
||||||
sprintf(string,"Track: %ld",fCurrentTrack);
|
fCurrentTrack->SetText(currentTrackName.String());
|
||||||
fTrackNumber->SetText(string);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fTrackNumber->SetText("Track: --");
|
{
|
||||||
|
fCurrentTrack->SetText("Track:");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CDButton::UpdateTimeInfo(void)
|
||||||
|
{
|
||||||
|
int32 min,sec;
|
||||||
|
char string[1024];
|
||||||
|
|
||||||
|
engine->TimeStateWatcher()->GetDiscTime(min,sec);
|
||||||
|
if(min >= 0)
|
||||||
|
sprintf(string,"Disc %ld:%.2ld / --:--",min,sec);
|
||||||
|
else
|
||||||
|
sprintf(string,"Disc --:-- / --:--");
|
||||||
|
fDiscTime->SetText(string);
|
||||||
|
|
||||||
|
engine->TimeStateWatcher()->GetTrackTime(min,sec);
|
||||||
|
if(min >= 0)
|
||||||
|
sprintf(string,"Track %ld:%.2ld / --:--",min,sec);
|
||||||
|
else
|
||||||
|
sprintf(string,"Track --:-- / --:--");
|
||||||
|
fTrackTime->SetText(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -393,6 +540,9 @@ CDButton::AttachedToWindow()
|
|||||||
engine->AttachedToLooper(Window());
|
engine->AttachedToLooper(Window());
|
||||||
StartObserving(engine->TrackStateWatcher());
|
StartObserving(engine->TrackStateWatcher());
|
||||||
StartObserving(engine->PlayStateWatcher());
|
StartObserving(engine->PlayStateWatcher());
|
||||||
|
StartObserving(engine->ContentWatcher());
|
||||||
|
StartObserving(engine->TimeStateWatcher());
|
||||||
|
StartObserving(engine->VolumeStateWatcher());
|
||||||
|
|
||||||
fVolume->SetTarget(this);
|
fVolume->SetTarget(this);
|
||||||
fStop->SetTarget(this);
|
fStop->SetTarget(this);
|
||||||
@@ -407,12 +557,52 @@ CDButton::AttachedToWindow()
|
|||||||
fRepeat->SetTarget(this);
|
fRepeat->SetTarget(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CDButton::FrameResized(float new_width, float new_height)
|
||||||
|
{
|
||||||
|
// We implement this method because there is no resizing mode to split the window's
|
||||||
|
// width into two and have a box fill each half
|
||||||
|
|
||||||
|
// The boxes are laid out with 5 pixels between the window edge and each box.
|
||||||
|
// Additionally, 15 pixels of padding are between the two boxes themselves
|
||||||
|
|
||||||
|
float half = (new_width / 2);
|
||||||
|
|
||||||
|
fCDBox->ResizeTo( half - 7, fCDBox->Bounds().Height() );
|
||||||
|
|
||||||
|
fTrackBox->MoveTo(half + 8, fTrackBox->Frame().top);
|
||||||
|
fTrackBox->ResizeTo( Bounds().right - (half + 8) - 5, fTrackBox->Bounds().Height() );
|
||||||
|
|
||||||
|
fTimeBox->MoveTo(half + 8, fTimeBox->Frame().top);
|
||||||
|
fTimeBox->ResizeTo( Bounds().right - (half + 8) - 5, fTimeBox->Bounds().Height() );
|
||||||
|
|
||||||
|
fRepeat->MoveTo(new_width - fRepeat->Bounds().right - 5, fRepeat->Frame().top);
|
||||||
|
|
||||||
|
fShuffle->MoveTo(fRepeat->Frame().left - fShuffle->Bounds().Width() - 2, fShuffle->Frame().top);
|
||||||
|
fSave->MoveTo(fShuffle->Frame().left - fSave->Bounds().Width() - 2, fSave->Frame().top);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CDButton::Pulse()
|
CDButton::Pulse()
|
||||||
{
|
{
|
||||||
engine->DoPulse();
|
engine->DoPulse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CDButton::SetBitmap(BBitmap *bitmap)
|
||||||
|
{
|
||||||
|
if(!bitmap)
|
||||||
|
{
|
||||||
|
ClearViewBitmap();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetViewBitmap(bitmap);
|
||||||
|
fVolume->SetViewBitmap(bitmap);
|
||||||
|
fVolume->Invalidate();
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
class CDButtonWindow : public BWindow
|
class CDButtonWindow : public BWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -421,8 +611,14 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
CDButtonWindow::CDButtonWindow(void)
|
CDButtonWindow::CDButtonWindow(void)
|
||||||
: BWindow(BRect (100, 100, 610, 400), "CD Player", B_TITLED_WINDOW, 0)
|
: BWindow(BRect (100, 100, 610, 200), "CD Player", B_TITLED_WINDOW, B_NOT_V_RESIZABLE)
|
||||||
{
|
{
|
||||||
|
float wmin,wmax,hmin,hmax;
|
||||||
|
|
||||||
|
GetSizeLimits(&wmin,&wmax,&hmin,&hmax);
|
||||||
|
wmin=510;
|
||||||
|
hmin=100;
|
||||||
|
SetSizeLimits(wmin,wmax,hmin,hmax);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDButtonWindow::QuitRequested(void)
|
bool CDButtonWindow::QuitRequested(void)
|
||||||
@@ -431,16 +627,23 @@ bool CDButtonWindow::QuitRequested(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDButtonApplication::CDButtonApplication()
|
CDButtonWindow *cdbwin;
|
||||||
: BApplication("application/x-vnd.Be-CDPlayer")
|
CDButton *cdbutton;
|
||||||
{
|
|
||||||
BWindow *window = new CDButtonWindow();
|
|
||||||
|
|
||||||
BView *button = new CDButton(window->Bounds(), "CD");
|
|
||||||
window->AddChild(button);
|
|
||||||
window->Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
CDButtonApplication::CDButtonApplication()
|
||||||
|
: BApplication("application/x-vnd.Haiku-CDPlayer")
|
||||||
|
{
|
||||||
|
// BWindow *window = new CDButtonWindow();
|
||||||
|
|
||||||
|
// BView *button = new CDButton(window->Bounds(), "CD");
|
||||||
|
/// window->AddChild(button);
|
||||||
|
// window->Show();
|
||||||
|
cdbwin = new CDButtonWindow();
|
||||||
|
|
||||||
|
cdbutton = new CDButton(cdbwin->Bounds(), "CD");
|
||||||
|
cdbwin->AddChild(cdbutton);
|
||||||
|
cdbwin->Show();
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int, char **argv)
|
main(int, char **argv)
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ public:
|
|||||||
virtual void AttachedToWindow();
|
virtual void AttachedToWindow();
|
||||||
|
|
||||||
virtual void Pulse();
|
virtual void Pulse();
|
||||||
|
|
||||||
|
virtual void FrameResized(float new_width, float new_height);
|
||||||
|
|
||||||
virtual void MessageReceived(BMessage *);
|
virtual void MessageReceived(BMessage *);
|
||||||
|
|
||||||
@@ -45,7 +47,11 @@ public:
|
|||||||
virtual void NoticeChange(Notifier *);
|
virtual void NoticeChange(Notifier *);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void UpdateTrackInfo(void);
|
void UpdateCDInfo(void);
|
||||||
|
void UpdateTimeInfo(void);
|
||||||
|
void SetBitmap(BBitmap *bitmap);
|
||||||
|
|
||||||
|
bool fStopOnQuit;
|
||||||
|
|
||||||
CDEngine *engine;
|
CDEngine *engine;
|
||||||
|
|
||||||
@@ -54,11 +60,16 @@ private:
|
|||||||
|
|
||||||
BSlider *fVolume;
|
BSlider *fVolume;
|
||||||
|
|
||||||
BTextControl *fCDTitle;
|
BStringView *fCDTitle;
|
||||||
BStringView *fTrackNumber;
|
BStringView *fCurrentTrack;
|
||||||
|
BStringView *fTrackTime;
|
||||||
|
BStringView *fDiscTime;
|
||||||
|
|
||||||
|
BBox *fCDBox;
|
||||||
|
BBox *fTrackBox;
|
||||||
|
BBox *fTimeBox;
|
||||||
|
|
||||||
CDState fCDState;
|
CDState fCDState;
|
||||||
int32 fTrackCount, fCurrentTrack;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+109
-37
@@ -15,6 +15,8 @@
|
|||||||
#include "scsi.h"
|
#include "scsi.h"
|
||||||
#include "CDEngine.h"
|
#include "CDEngine.h"
|
||||||
|
|
||||||
|
const bigtime_t kPulseRate = 500000;
|
||||||
|
|
||||||
PeriodicWatcher::PeriodicWatcher(int devicefd)
|
PeriodicWatcher::PeriodicWatcher(int devicefd)
|
||||||
: Notifier(),
|
: Notifier(),
|
||||||
devicefd(devicefd)
|
devicefd(devicefd)
|
||||||
@@ -168,50 +170,67 @@ TimeState::UpdateState()
|
|||||||
status_t media_status = B_DEV_NO_MEDIA;
|
status_t media_status = B_DEV_NO_MEDIA;
|
||||||
ioctl(devicefd, B_GET_MEDIA_STATUS, &media_status, sizeof(media_status));
|
ioctl(devicefd, B_GET_MEDIA_STATUS, &media_status, sizeof(media_status));
|
||||||
if (media_status != B_NO_ERROR)
|
if (media_status != B_NO_ERROR)
|
||||||
return CurrentState(-1, -1);
|
return CurrentState(-1, -1, -1, -1);
|
||||||
|
|
||||||
status_t result = ioctl(devicefd, B_SCSI_GET_POSITION, &pos);
|
status_t result = ioctl(devicefd, B_SCSI_GET_POSITION, &pos);
|
||||||
|
|
||||||
if (result != B_NO_ERROR)
|
if (result != B_NO_ERROR)
|
||||||
return CurrentState(-1, -1);
|
return CurrentState(-1, -1, -1, -1);
|
||||||
else if ((!pos.position[1]) || (pos.position[1] >= 0x13) ||
|
else
|
||||||
((pos.position[1] == 0x12) && (!pos.position[6])))
|
if ((!pos.position[1]) || (pos.position[1] >= 0x13) ||
|
||||||
return CurrentState(0, 0);
|
((pos.position[1] == 0x12) && (!pos.position[6])))
|
||||||
|
{
|
||||||
|
// This indicates that we have a CD, but we are stopped. We *could* simply
|
||||||
|
// return all 0's, but because the GUI expects valid numbers or -1's, we
|
||||||
|
// return -1's.
|
||||||
|
return CurrentState(-1, -1, -1, -1);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return CurrentState(pos.position[9], pos.position[10]);
|
return CurrentState(pos.position[9], pos.position[10], pos.position[13], pos.position[14]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TimeState::CurrentState(int32 minutes, int32 seconds)
|
TimeState::CurrentState(int32 dmin, int32 dsec, int32 tmin, int32 tsec)
|
||||||
{
|
{
|
||||||
if (minutes == oldMinutes && seconds == oldSeconds)
|
if (dmin == fDiscMinutes && dsec == fDiscSeconds)
|
||||||
return false;
|
return false;
|
||||||
oldMinutes = minutes;
|
|
||||||
oldSeconds = seconds;
|
fDiscMinutes = dmin;
|
||||||
|
fDiscSeconds = dsec;
|
||||||
|
fTrackMinutes = tmin;
|
||||||
|
fTrackSeconds = tsec;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TimeState::GetTime(int32 &minutes, int32 &seconds) const
|
TimeState::GetDiscTime(int32 &minutes, int32 &seconds) const
|
||||||
{
|
{
|
||||||
minutes = oldMinutes;
|
minutes = fDiscMinutes;
|
||||||
seconds = oldSeconds;
|
seconds = fDiscSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TimeState::GetTrackTime(int32 &minutes, int32 &seconds) const
|
||||||
|
{
|
||||||
|
minutes = fTrackMinutes;
|
||||||
|
seconds = fTrackSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CDContentWatcher::CDContentWatcher(int devicefd)
|
CDContentWatcher::CDContentWatcher(int devicefd)
|
||||||
: PeriodicWatcher(devicefd),
|
: PeriodicWatcher(devicefd),
|
||||||
cddbQuery("us.cddb.com", 888, true),
|
cddbQuery("us.freedb.org", 888, true),
|
||||||
discID(-1),
|
discID(-1),
|
||||||
wasReady(false)
|
fReady(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CDContentWatcher::CDContentWatcher(BMessage *message)
|
CDContentWatcher::CDContentWatcher(BMessage *message)
|
||||||
: PeriodicWatcher(message),
|
: PeriodicWatcher(message),
|
||||||
cddbQuery("us.cddb.com", 888, true),
|
cddbQuery("us.freedb.org", 888, true),
|
||||||
discID(-1),
|
discID(-1),
|
||||||
wasReady(false)
|
fReady(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,23 +243,61 @@ CDContentWatcher::GetContent(BString *title, vector<BString> *tracks)
|
|||||||
bool
|
bool
|
||||||
CDContentWatcher::UpdateState()
|
CDContentWatcher::UpdateState()
|
||||||
{
|
{
|
||||||
bool newReady = false;
|
|
||||||
bool newDiscID = -1;
|
bool newDiscID = -1;
|
||||||
if (engine->PlayStateWatcher()->GetState() != kNoCD) {
|
|
||||||
|
// Check the table of contents to see if the new one is different
|
||||||
|
// from the old one whenever there is a CD in the drive
|
||||||
|
if (engine->PlayStateWatcher()->GetState() != kNoCD)
|
||||||
|
{
|
||||||
scsi_toc toc;
|
scsi_toc toc;
|
||||||
ioctl(devicefd, B_SCSI_GET_TOC, &toc);
|
ioctl(devicefd, B_SCSI_GET_TOC, &toc);
|
||||||
newDiscID = cddbQuery.GetDiscID(&toc);
|
newDiscID = cddbQuery.GetDiscID(&toc);
|
||||||
if (discID != newDiscID)
|
|
||||||
cddbQuery.SetToCD(&toc);
|
if (discID == newDiscID)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// We have changed CDs, so we are not ready until the CDDB lookup finishes
|
||||||
|
cddbQuery.SetToCD(&toc);
|
||||||
|
fReady=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the CD has changed and the CDDB query is ready, we set to true so that
|
||||||
|
// when UpdateState returns, a notification is sent
|
||||||
|
bool result = ( (fReady != cddbQuery.Ready()) && (newDiscID != discID) );
|
||||||
|
|
||||||
|
if(result)
|
||||||
|
{
|
||||||
|
fReady = true;
|
||||||
|
discID = newDiscID;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool result = newReady != cddbQuery.Ready() && newDiscID != discID;
|
|
||||||
newReady = cddbQuery.Ready();
|
|
||||||
newDiscID = discID;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VolumeState::VolumeState(int devicefd)
|
||||||
|
: PeriodicWatcher(devicefd),
|
||||||
|
fVolume(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
VolumeState::UpdateState(void)
|
||||||
|
{
|
||||||
|
scsi_volume vol;
|
||||||
|
ioctl(devicefd, B_SCSI_GET_VOLUME, &vol);
|
||||||
|
if(vol.port0_volume == fVolume)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
fVolume = vol.port0_volume;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
VolumeState::GetVolume(void) const
|
||||||
|
{
|
||||||
|
return fVolume;
|
||||||
|
}
|
||||||
|
|
||||||
CDEngine::CDEngine(int devicefd)
|
CDEngine::CDEngine(int devicefd)
|
||||||
: BHandler("CDEngine"),
|
: BHandler("CDEngine"),
|
||||||
devicefd(devicefd),
|
devicefd(devicefd),
|
||||||
@@ -318,12 +375,13 @@ void
|
|||||||
CDEngine::Play()
|
CDEngine::Play()
|
||||||
{
|
{
|
||||||
// play the CD
|
// play the CD
|
||||||
if (playState.GetState() == kNoCD) {
|
if (playState.GetState() == kNoCD)
|
||||||
|
{
|
||||||
// no CD available, bail out
|
// no CD available, bail out
|
||||||
ioctl(devicefd, B_LOAD_MEDIA, 0, 0);
|
ioctl(devicefd, B_LOAD_MEDIA, 0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
scsi_play_track track;
|
scsi_play_track track;
|
||||||
|
|
||||||
track.start_track = 1;
|
track.start_track = 1;
|
||||||
@@ -332,7 +390,8 @@ CDEngine::Play()
|
|||||||
track.end_index = 1;
|
track.end_index = 1;
|
||||||
|
|
||||||
status_t result = ioctl(devicefd, B_SCSI_PLAY_TRACK, &track);
|
status_t result = ioctl(devicefd, B_SCSI_PLAY_TRACK, &track);
|
||||||
if (result != B_NO_ERROR) {
|
if (result != B_NO_ERROR)
|
||||||
|
{
|
||||||
PRINT(("error %s playing track\n", strerror(errno)));
|
PRINT(("error %s playing track\n", strerror(errno)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -343,7 +402,8 @@ CDEngine::PlayContinue()
|
|||||||
{
|
{
|
||||||
// continue after a pause
|
// continue after a pause
|
||||||
status_t result = ioctl(devicefd, B_SCSI_RESUME_AUDIO);
|
status_t result = ioctl(devicefd, B_SCSI_RESUME_AUDIO);
|
||||||
if (result != B_NO_ERROR) {
|
if (result != B_NO_ERROR)
|
||||||
|
{
|
||||||
PRINT(("error %s resuming\n", strerror(errno)));
|
PRINT(("error %s resuming\n", strerror(errno)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -354,8 +414,9 @@ CDEngine::Stop()
|
|||||||
{
|
{
|
||||||
// stop a playing CD
|
// stop a playing CD
|
||||||
status_t result = ioctl(devicefd, B_SCSI_STOP_AUDIO);
|
status_t result = ioctl(devicefd, B_SCSI_STOP_AUDIO);
|
||||||
if (result != B_NO_ERROR) {
|
if (result != B_OK)
|
||||||
PRINT(("error %s stoping\n", strerror(errno)));
|
{
|
||||||
|
PRINT(("error %s stopping\n", strerror(errno)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,9 +432,10 @@ CDEngine::Eject()
|
|||||||
|
|
||||||
// if door open, load the media, else eject the CD
|
// if door open, load the media, else eject the CD
|
||||||
status_t result = ioctl(devicefd,
|
status_t result = ioctl(devicefd,
|
||||||
media_status == B_DEV_DOOR_OPEN ? B_LOAD_MEDIA : B_EJECT_DEVICE);
|
media_status == B_DEV_DOOR_OPEN ? B_LOAD_MEDIA : B_EJECT_DEVICE);
|
||||||
|
|
||||||
if (result != B_NO_ERROR) {
|
if (result != B_OK)
|
||||||
|
{
|
||||||
PRINT(("error %s ejecting\n", strerror(errno)));
|
PRINT(("error %s ejecting\n", strerror(errno)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -506,12 +568,22 @@ CDEngine::SelectTrack(int32 trackNumber)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bigtime_t kPulseRate = 500000;
|
void
|
||||||
|
CDEngine::SetVolume(uint8 value)
|
||||||
|
{
|
||||||
|
scsi_volume vol;
|
||||||
|
|
||||||
|
// change only port0's volume
|
||||||
|
vol.flags=2;
|
||||||
|
vol.port0_volume=value;
|
||||||
|
|
||||||
|
ioctl(devicefd,B_SCSI_SET_VOLUME,&vol);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CDEngine::DoPulse()
|
CDEngine::DoPulse()
|
||||||
{
|
{
|
||||||
// this is the CDEngine's hearbeat; Since it is a Notifier, it checks if
|
// this is the CDEngine's heartbeat; Since it is a Notifier, it checks if
|
||||||
// any values changed since the last hearbeat and sends notices to observers
|
// any values changed since the last hearbeat and sends notices to observers
|
||||||
|
|
||||||
bigtime_t time = system_time();
|
bigtime_t time = system_time();
|
||||||
|
|||||||
@@ -98,13 +98,18 @@ public:
|
|||||||
: PeriodicWatcher(message)
|
: PeriodicWatcher(message)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void GetTime(int32 &minutes, int32 &seconds) const;
|
void GetDiscTime(int32 &minutes, int32 &seconds) const;
|
||||||
|
void GetTrackTime(int32 &minutes, int32 &seconds) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool UpdateState();
|
bool UpdateState();
|
||||||
bool CurrentState(int32 minutes, int32 seconds);
|
bool CurrentState(int32 dmin, int32 dsec, int32 tmin, int32 tsec);
|
||||||
int32 oldMinutes;
|
|
||||||
int32 oldSeconds;
|
int32 fDiscMinutes;
|
||||||
|
int32 fDiscSeconds;
|
||||||
|
|
||||||
|
int32 fTrackMinutes;
|
||||||
|
int32 fTrackSeconds;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDContentWatcher : public PeriodicWatcher {
|
class CDContentWatcher : public PeriodicWatcher {
|
||||||
@@ -119,24 +124,24 @@ private:
|
|||||||
|
|
||||||
CDDBQuery cddbQuery;
|
CDDBQuery cddbQuery;
|
||||||
int32 discID;
|
int32 discID;
|
||||||
bool wasReady;
|
bool fReady;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VolumeState : public PeriodicWatcher {
|
class VolumeState : public PeriodicWatcher {
|
||||||
// this watcher sends notices to observers that are interrested
|
// this watcher sends notices to observers that are interested
|
||||||
// about changes in the current volume
|
// about changes in the current volume
|
||||||
// currently not used yet
|
// currently not used yet
|
||||||
public:
|
public:
|
||||||
VolumeState(int devicefd)
|
VolumeState(int devicefd);
|
||||||
: PeriodicWatcher(devicefd)
|
|
||||||
{ }
|
|
||||||
VolumeState(BMessage *message)
|
VolumeState(BMessage *message)
|
||||||
: PeriodicWatcher(message)
|
: PeriodicWatcher(message)
|
||||||
{}
|
{}
|
||||||
|
bool UpdateState();
|
||||||
bool UpdateState() { return true; }
|
|
||||||
virtual void DoPulse() {}
|
|
||||||
int32 GetVolume() const;
|
int32 GetVolume() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32 fVolume;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDEngine : public BHandler {
|
class CDEngine : public BHandler {
|
||||||
@@ -168,6 +173,7 @@ public:
|
|||||||
void StopSkipping();
|
void StopSkipping();
|
||||||
void SelectTrack(int32);
|
void SelectTrack(int32);
|
||||||
|
|
||||||
|
void SetVolume(uint8 value);
|
||||||
|
|
||||||
TrackState *TrackStateWatcher()
|
TrackState *TrackStateWatcher()
|
||||||
{ return &trackState; }
|
{ return &trackState; }
|
||||||
@@ -186,6 +192,11 @@ public:
|
|||||||
|
|
||||||
CDContentWatcher *ContentWatcher()
|
CDContentWatcher *ContentWatcher()
|
||||||
{ return &contentWatcher; }
|
{ return &contentWatcher; }
|
||||||
|
|
||||||
|
VolumeState *VolumeStateWatcher()
|
||||||
|
// to find the current location on the CD, you may call the GetVolume function
|
||||||
|
// VolumeState defines
|
||||||
|
{ return &volumeState; }
|
||||||
|
|
||||||
static int FindCDPlayerDevice();
|
static int FindCDPlayerDevice();
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ resource(101, "BEOS:M:STD_ICON") #'MICN' array {
|
|||||||
$"FFFFFFFFFFFF000000000EFFFFFFFFFF"
|
$"FFFFFFFFFFFF000000000EFFFFFFFFFF"
|
||||||
};
|
};
|
||||||
|
|
||||||
resource(1, "BEOS:APP_SIG") #'MIMS' "application/x-vnd.Haiku.CDPlayer";
|
resource(1, "BEOS:APP_SIG") #'MIMS' "application/x-vnd.Haiku-CDPlayer";
|
||||||
|
|
||||||
resource(1, "BEOS:FILE_TYPES") message;
|
resource(1, "BEOS:FILE_TYPES") message;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user