Fixes to monitoring of the CD drive's state

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13638 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
DarkWyrm
2005-07-11 20:05:50 +00:00
parent 0ca3e71c1e
commit 6105ba9382
9 changed files with 232 additions and 224 deletions
+5 -2
View File
@@ -421,8 +421,11 @@ CDAudioDevice::GetTimeForTrack(const int16 &index, cdaudio_time &track)
TrackDescriptor *desc = (TrackDescriptor*)&(toc.toc_data[4]); TrackDescriptor *desc = (TrackDescriptor*)&(toc.toc_data[4]);
track.minutes = desc[index].min - desc[index-1].min; int32 tracktime = (desc[index].min * 60) + desc[index].sec;
track.seconds = desc[index].sec - desc[index-1].sec;
tracktime -= (desc[index-1].min * 60) + desc[index-1].sec;
track.minutes = tracktime / 60;
track.seconds = tracktime % 60;
return true; return true;
} }
+2 -1
View File
@@ -11,7 +11,8 @@ enum CDState {
kPaused, kPaused,
kPlaying, kPlaying,
kSkipping, kSkipping,
kError kError,
kInit
}; };
typedef struct typedef struct
+41 -3
View File
@@ -48,7 +48,7 @@ PeriodicWatcher::UpdateNow()
PlayState::PlayState(CDEngine *engine) PlayState::PlayState(CDEngine *engine)
: oldState(kNoCD), : oldState(kInit),
fEngine(engine) fEngine(engine)
{ {
} }
@@ -57,7 +57,7 @@ bool
PlayState::UpdateState(void) PlayState::UpdateState(void)
{ {
CDState state = sCDDevice.GetState(); CDState state = sCDDevice.GetState();
if( state == kStopped && fEngine->GetState() == kPlaying) if(state == kStopped && fEngine->GetState() == kPlaying)
{ {
// this means we have come to the end of a song, but probably not // this means we have come to the end of a song, but probably not
// the last song in the playlist // the last song in the playlist
@@ -69,6 +69,17 @@ PlayState::UpdateState(void)
} }
} }
/* if(state == kPlaying && fEngine->GetState() == kStopped)
{
// This happens when the CD drive is started by R5's player
// or this app is started while the drive is playing. We should
// reset the to start at the current track and finish at the
// last one and send a notification.
sPlayList.SetTrackCount(sCDDevice.CountTracks());
sPlayList.SetStartingTrack(sCDDevice.GetTrack());
return CurrentState(kPlaying);
}
*/
return CurrentState(state); return CurrentState(state);
} }
@@ -103,7 +114,16 @@ TrackState::GetTrack() const
bool bool
TrackState::UpdateState() TrackState::UpdateState()
{ {
return CurrentState(sPlayList.GetCurrentTrack()); // It's possible that the state of the cd drive was changed by outside means
// As a result, we want to make sure this hasn't happened. If it has, then we
// need to update the playlist's position.
int16 cdTrack = sCDDevice.GetTrack();
if(cdTrack != sPlayList.GetCurrentTrack())
sPlayList.SetCurrentTrack(cdTrack);
return CurrentState(cdTrack);
} }
int32 int32
@@ -210,6 +230,14 @@ CDContentWatcher::CDContentWatcher(void)
bool bool
CDContentWatcher::GetContent(BString *title, vector<BString> *tracks) CDContentWatcher::GetContent(BString *title, vector<BString> *tracks)
{ {
if(discID == -1)
{
title->SetTo("");
tracks->empty();
tracks->push_back("");
return true;
}
return cddbQuery.GetTitles(title, tracks, 1000000); return cddbQuery.GetTitles(title, tracks, 1000000);
} }
@@ -231,6 +259,16 @@ CDContentWatcher::UpdateState()
cddbQuery.SetToCD(sCDDevice.GetDrivePath()); cddbQuery.SetToCD(sCDDevice.GetDrivePath());
fReady=false; fReady=false;
} }
else
{
if(discID != -1)
{
discID = -1;
return true;
}
else
return false;
}
// If the CD has changed and the CDDB query is ready, we set to true so that // If the CD has changed and the CDDB query is ready, we set to true so that
// when UpdateState returns, a notification is sent // when UpdateState returns, a notification is sent
+144 -215
View File
@@ -54,21 +54,6 @@ CDPlayer::CDPlayer(BRect frame, const char *name, uint32 resizeMask, uint32 flag
engine = new CDEngine; engine = new CDEngine;
BuildGUI(); BuildGUI();
fCDState = engine->PlayStateWatcher()->GetState();
if(fCDState == kNoCD)
{
fStop->SetEnabled(false);
fPlay->SetEnabled(false);
fNextTrack->SetEnabled(false);
fPrevTrack->SetEnabled(false);
fFastFwd->SetEnabled(false);
fRewind->SetEnabled(false);
fSave->SetEnabled(false);
fCurrentTrack->SetHighColor(fStopColor);
}
} }
CDPlayer::~CDPlayer() CDPlayer::~CDPlayer()
@@ -153,12 +138,17 @@ void CDPlayer::BuildGUI(void)
fStop->SetDisabled(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"stop_disabled")); fStop->SetDisabled(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"stop_disabled"));
AddChild(fStop); AddChild(fStop);
fPlay = new DrawButton( BRect(0,0,1,1), "Play", BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_up"), fPlay = new TwoStateDrawButton( BRect(0,0,1,1), "Play",
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_down"), BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_up"),
new BMessage(M_PLAY), B_FOLLOW_BOTTOM, B_WILL_DRAW); BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_down"),
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"pause_up"),
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"pause_down"),
new BMessage(M_PLAY), B_FOLLOW_NONE, B_WILL_DRAW);
fPlay->ResizeToPreferred(); fPlay->ResizeToPreferred();
fPlay->MoveTo(fStop->Frame().right + 2, Bounds().bottom - 5 - fPlay->Frame().Height()); fPlay->MoveTo(fStop->Frame().right + 2, Bounds().bottom - 5 - fPlay->Frame().Height());
fPlay->SetDisabled(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_disabled")); fPlay->SetDisabled(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_disabled"),
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"pause_disabled"));
AddChild(fPlay); AddChild(fPlay);
fPrevTrack = new DrawButton( BRect(0,0,1,1), "PrevTrack", BTranslationUtils::GetBitmap(B_PNG_FORMAT,"prev_up"), fPrevTrack = new DrawButton( BRect(0,0,1,1), "PrevTrack", BTranslationUtils::GetBitmap(B_PNG_FORMAT,"prev_up"),
@@ -236,64 +226,6 @@ void CDPlayer::BuildGUI(void)
void void
CDPlayer::MessageReceived(BMessage *msg) CDPlayer::MessageReceived(BMessage *msg)
{ {
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) switch (msg->what)
{ {
case M_SET_VOLUME: case M_SET_VOLUME:
@@ -304,10 +236,8 @@ CDPlayer::MessageReceived(BMessage *msg)
case M_STOP: case M_STOP:
{ {
if(engine->GetState()==kPlaying) if(engine->GetState()==kPlaying)
{ fPlay->SetState(0);
fPlay->SetBitmaps(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_up"),
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_down"));
}
engine->Stop(); engine->Stop();
break; break;
} }
@@ -317,16 +247,14 @@ CDPlayer::MessageReceived(BMessage *msg)
// the pause images and will want to switch back to the play images // the pause images and will want to switch back to the play images
if(engine->GetState()==kPlaying) if(engine->GetState()==kPlaying)
{ {
fPlay->SetBitmaps(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_up"), fPlay->SetState(0);
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_down")); engine->Pause();
} }
else else
{ {
// Currently not playing and going to be playing, so show pause icons fPlay->SetState(1);
fPlay->SetBitmaps(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"pause_up"), engine->Play();
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"pause_down"));
} }
engine->Play();
break; break;
} }
case M_NEXT_TRACK: case M_NEXT_TRACK:
@@ -339,6 +267,14 @@ CDPlayer::MessageReceived(BMessage *msg)
engine->SkipOneBackward(); engine->SkipOneBackward();
break; break;
} }
case M_EJECT:
{
engine->Eject();
break;
}
case M_FFWD: case M_FFWD:
{ {
// TODO: Implement // TODO: Implement
@@ -349,16 +285,12 @@ CDPlayer::MessageReceived(BMessage *msg)
// TODO: Implement // TODO: Implement
break; break;
} }
case M_EJECT:
{
engine->Eject();
break;
}
case M_SAVE: case M_SAVE:
{ {
// TODO: Implement // TODO: Implement
break; break;
} }
case M_SHUFFLE: case M_SHUFFLE:
{ {
engine->ToggleShuffle(); engine->ToggleShuffle();
@@ -369,6 +301,7 @@ CDPlayer::MessageReceived(BMessage *msg)
engine->ToggleRepeat(); engine->ToggleRepeat();
break; break;
} }
default: default:
{ {
@@ -399,104 +332,7 @@ CDPlayer::NoticeChange(Notifier *notifier)
if(ps) if(ps)
{ {
switch(ps->GetState()) HandlePlayState();
{
case kNoCD:
{
if(fStop->IsEnabled())
{
fStop->SetEnabled(false);
fPlay->SetEnabled(false);
fNextTrack->SetEnabled(false);
fPrevTrack->SetEnabled(false);
fFastFwd->SetEnabled(false);
fRewind->SetEnabled(false);
fSave->SetEnabled(false);
}
fCurrentTrack->SetHighColor(fStopColor);
fCurrentTrack->SetText("Track: ");
fTrackTime->SetText("Track --:-- / --:--");
fDiscTime->SetText("Disc --:-- / --:--");
break;
}
case kStopped:
{
if(!fStop->IsEnabled())
{
fStop->SetEnabled(true);
fPlay->SetEnabled(true);
fNextTrack->SetEnabled(true);
fPrevTrack->SetEnabled(true);
fFastFwd->SetEnabled(true);
fRewind->SetEnabled(true);
// TODO: Enable when Save is implemented
// fSave->SetEnabled(true);
}
fCurrentTrack->SetHighColor(fStopColor);
fCurrentTrack->Invalidate();
fTrackTime->SetText("Track --:-- / --:--");
fDiscTime->SetText("Disc --:-- / --:--");
break;
}
case kPaused:
{
// TODO: Set play button to Pause
if(!fStop->IsEnabled())
{
fStop->SetEnabled(true);
fPlay->SetEnabled(true);
fNextTrack->SetEnabled(true);
fPrevTrack->SetEnabled(true);
fFastFwd->SetEnabled(true);
fRewind->SetEnabled(true);
// TODO: Enable when Save is implemented
// fSave->SetEnabled(true);
}
fCurrentTrack->SetHighColor(fPlayColor);
break;
}
case kPlaying:
{
if(!fStop->IsEnabled())
{
fStop->SetEnabled(true);
fPlay->SetEnabled(true);
fNextTrack->SetEnabled(true);
fPrevTrack->SetEnabled(true);
fFastFwd->SetEnabled(true);
fRewind->SetEnabled(true);
// TODO: Enable when Save is implemented
// fSave->SetEnabled(true);
}
fCurrentTrack->SetHighColor(fPlayColor);
fCurrentTrack->Invalidate();
break;
}
case kSkipping:
{
if(!fStop->IsEnabled())
{
fStop->SetEnabled(true);
fPlay->SetEnabled(true);
fNextTrack->SetEnabled(true);
fPrevTrack->SetEnabled(true);
fFastFwd->SetEnabled(true);
fRewind->SetEnabled(true);
// TODO: Enable when Save is implemented
// fSave->SetEnabled(true);
}
fCurrentTrack->SetHighColor(fStopColor);
break;
}
default:
{
break;
}
}
} }
else else
if(trs) if(trs)
@@ -521,6 +357,104 @@ CDPlayer::NoticeChange(Notifier *notifier)
} }
} }
void
CDPlayer::HandlePlayState(void)
{
switch(engine->PlayStateWatcher()->GetState())
{
case kNoCD:
{
if(fStop->IsEnabled())
{
fStop->SetEnabled(false);
fPlay->SetEnabled(false);
fNextTrack->SetEnabled(false);
fPrevTrack->SetEnabled(false);
fFastFwd->SetEnabled(false);
fRewind->SetEnabled(false);
fSave->SetEnabled(false);
}
fCurrentTrack->SetHighColor(fStopColor);
break;
}
case kStopped:
{
if(!fStop->IsEnabled())
{
fStop->SetEnabled(true);
fPlay->SetEnabled(true);
fNextTrack->SetEnabled(true);
fPrevTrack->SetEnabled(true);
fFastFwd->SetEnabled(true);
fRewind->SetEnabled(true);
// TODO: Enable when Save is implemented
// fSave->SetEnabled(true);
}
fCurrentTrack->SetHighColor(fStopColor);
break;
}
case kPaused:
{
// TODO: Set play button to Pause
if(!fStop->IsEnabled())
{
fStop->SetEnabled(true);
fPlay->SetEnabled(true);
fNextTrack->SetEnabled(true);
fPrevTrack->SetEnabled(true);
fFastFwd->SetEnabled(true);
fRewind->SetEnabled(true);
// TODO: Enable when Save is implemented
// fSave->SetEnabled(true);
}
fCurrentTrack->SetHighColor(fPlayColor);
break;
}
case kPlaying:
{
if(!fStop->IsEnabled())
{
fStop->SetEnabled(true);
fPlay->SetEnabled(true);
fNextTrack->SetEnabled(true);
fPrevTrack->SetEnabled(true);
fFastFwd->SetEnabled(true);
fRewind->SetEnabled(true);
// TODO: Enable when Save is implemented
// fSave->SetEnabled(true);
}
fPlay->SetState(1);
fCurrentTrack->SetHighColor(fPlayColor);
fCurrentTrack->Invalidate();
break;
}
case kSkipping:
{
if(!fStop->IsEnabled())
{
fStop->SetEnabled(true);
fPlay->SetEnabled(true);
fNextTrack->SetEnabled(true);
fPrevTrack->SetEnabled(true);
fFastFwd->SetEnabled(true);
fRewind->SetEnabled(true);
// TODO: Enable when Save is implemented
// fSave->SetEnabled(true);
}
fCurrentTrack->SetHighColor(fStopColor);
break;
}
default:
{
break;
}
}
}
void void
CDPlayer::UpdateCDInfo(void) CDPlayer::UpdateCDInfo(void)
{ {
@@ -528,26 +462,35 @@ CDPlayer::UpdateCDInfo(void)
vector<BString> trackNames; vector<BString> trackNames;
int32 currentTrack = engine->TrackStateWatcher()->GetTrack(); int32 currentTrack = engine->TrackStateWatcher()->GetTrack();
if(currentTrack < 1)
bool trackresult = engine->ContentWatcher()->GetContent(&CDName,&trackNames);
if(currentTrack < 0)
return; return;
bool trackresult =engine->ContentWatcher()->GetContent(&CDName,&trackNames); if(currentTrack == 0)
currentTrack++;
if(trackresult) if(trackresult)
fCDTitle->SetText(CDName.String());
else
fCDTitle->SetText("Audio CD");
if(currentTrack > 0)
{ {
if(trackresult) if(CDName.CountChars()<1)
{
// if the CD name is NULL, then it means we have no disc in the drive.
fCDTitle->SetText("");
fCurrentTrack->SetText("");
}
else
{ {
currentTrackName << "Track " << currentTrack << ": " << trackNames[ currentTrack - 1]; currentTrackName << "Track " << currentTrack << ": " << trackNames[ currentTrack - 1];
fCurrentTrack->SetText(currentTrackName.String()); fCurrentTrack->SetText(currentTrackName.String());
fCDTitle->SetText(CDName.String());
return;
} }
return;
}
else
{
fCDTitle->SetText("Audio CD");
currentTrackName << "Track " << currentTrack; currentTrackName << "Track " << currentTrack;
fCurrentTrack->SetText(currentTrackName.String()); fCurrentTrack->SetText(currentTrackName.String());
} }
@@ -587,6 +530,7 @@ CDPlayer::UpdateTimeInfo(void)
void void
CDPlayer::AttachedToWindow() CDPlayer::AttachedToWindow()
{ {
// start observing // start observing
engine->AttachedToLooper(Window()); engine->AttachedToLooper(Window());
StartObserving(engine->TrackStateWatcher()); StartObserving(engine->TrackStateWatcher());
@@ -639,21 +583,6 @@ CDPlayer::Pulse()
engine->DoPulse(); engine->DoPulse();
} }
void
CDPlayer::SetBitmap(BBitmap *bitmap)
{
if(!bitmap)
{
ClearViewBitmap();
return;
}
SetViewBitmap(bitmap);
fVolume->SetViewBitmap(bitmap);
fVolume->Invalidate();
Invalidate();
}
class CDPlayerWindow : public BWindow class CDPlayerWindow : public BWindow
{ {
public: public:
+4 -3
View File
@@ -45,14 +45,14 @@ public:
virtual void NoticeChange(Notifier *); virtual void NoticeChange(Notifier *);
private: private:
void HandlePlayState(void);
void UpdateCDInfo(void); void UpdateCDInfo(void);
void UpdateTimeInfo(void); void UpdateTimeInfo(void);
void SetBitmap(BBitmap *bitmap);
CDEngine *engine; CDEngine *engine;
DrawButton *fStop, DrawButton *fStop,
*fPlay, // *fPlay,
*fNextTrack, *fNextTrack,
*fPrevTrack, *fPrevTrack,
*fFastFwd, *fFastFwd,
@@ -61,7 +61,8 @@ private:
*fSave; *fSave;
TwoStateDrawButton *fShuffle, TwoStateDrawButton *fShuffle,
*fRepeat; *fRepeat,
*fPlay;
BSlider *fVolume; BSlider *fVolume;
+20
View File
@@ -96,6 +96,26 @@ PlayList::SetLoop(const bool &loop)
fLocker.Unlock(); fLocker.Unlock();
} }
void
PlayList::SetCurrentTrack(const int16 &track)
{
if(track < 0 || track > fTrackCount)
return;
fLocker.Lock();
for(int16 i=0; i<fTrackCount; i++)
{
if(fTrackList[i] == track)
{
fTrackIndex = i;
break;
}
}
fLocker.Unlock();
}
int16 int16
PlayList::GetCurrentTrack(void) PlayList::GetCurrentTrack(void)
{ {
+2
View File
@@ -23,7 +23,9 @@ public:
void SetLoop(const bool &loop); void SetLoop(const bool &loop);
bool IsLoop(void) const { return fLoop; } bool IsLoop(void) const { return fLoop; }
void SetCurrentTrack(const int16 &track);
int16 GetCurrentTrack(void); int16 GetCurrentTrack(void);
int16 GetNextTrack(void); int16 GetNextTrack(void);
int16 GetPreviousTrack(void); int16 GetPreviousTrack(void);
+13
View File
@@ -80,6 +80,19 @@ void TwoStateDrawButton::MouseUp(BPoint pt)
Invalidate(); Invalidate();
} }
void
TwoStateDrawButton::SetState(int32 value)
{
if(fButtonState!=value)
{
if(value==0)
fButtonState = false;
else
fButtonState = true;
Invalidate();
}
}
void TwoStateDrawButton::Draw(BRect update) void TwoStateDrawButton::Draw(BRect update)
{ {
if(fButtonState) if(fButtonState)
+1
View File
@@ -26,6 +26,7 @@ public:
// void MessageReceived(BMessage *msg); // void MessageReceived(BMessage *msg);
int32 GetState(void) { return fButtonState ? 1 : 0; }; int32 GetState(void) { return fButtonState ? 1 : 0; };
void SetState(int32 value);
private: private: