From 175c92ffb302e970c0c0a21e3c17cccfb0f537b8 Mon Sep 17 00:00:00 2001 From: DarkWyrm Date: Mon, 27 Jun 2005 18:44:34 +0000 Subject: [PATCH] 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 --- src/apps/cdplayer/CDButton.cpp | 301 ++++++++++++++++++++++++++------ src/apps/cdplayer/CDButton.h | 19 +- src/apps/cdplayer/CDEngine.cpp | 146 ++++++++++++---- src/apps/cdplayer/CDEngine.h | 35 ++-- src/apps/cdplayer/CDPlayer.rdef | 2 +- 5 files changed, 400 insertions(+), 103 deletions(-) diff --git a/src/apps/cdplayer/CDButton.cpp b/src/apps/cdplayer/CDButton.cpp index 126b7222b1..e1be29e955 100644 --- a/src/apps/cdplayer/CDButton.cpp +++ b/src/apps/cdplayer/CDButton.cpp @@ -24,6 +24,9 @@ #include "CDButton.h" #include "DrawButton.h" #include +#include +#include +#include enum { @@ -42,9 +45,15 @@ enum }; 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)); + + // TODO: Support multiple CD drives engine = new CDEngine(CDEngine::FindCDPlayerDevice()); BuildGUI(); @@ -65,34 +74,69 @@ CDButton::CDButton(BRect frame, const char *name, uint32 resizeMask, uint32 flag CDButton::~CDButton() { + if(fStopOnQuit) + engine->Stop(); + delete engine; } void CDButton::BuildGUI(void) { - fCDTitle = new BTextControl( BRect(5,5,230,30), "CDTitle","","",new BMessage(M_SET_CD_TITLE)); - AddChild(fCDTitle); - fCDTitle->SetDivider(0); - fCDTitle->TextView()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + BRect r(5,5,230,25); - BBox *box = new BBox(BRect(0,0,75,20),"TrackBox"); - box->MoveTo(fCDTitle->Frame().right + 15, 5); - AddChild(box); + // Assemble the CD Title box + fCDBox = new BBox(r,"TrackBox"); + AddChild(fCDBox); - BView *view = new BView( box->Bounds().InsetByCopy(2,2), "view",B_FOLLOW_NONE,B_WILL_DRAW); - view->SetViewColor(0,0,0); - box->AddChild(view); + BView *view = new BView( fCDBox->Bounds().InsetByCopy(2,2), "view",B_FOLLOW_ALL,B_WILL_DRAW); + view->SetViewColor(20,20,20); + fCDBox->AddChild(view); - fTrackNumber = new BStringView( view->Bounds(),"TrackNumber","Track: --"); - view->AddChild(fTrackNumber); - fTrackNumber->SetAlignment(B_ALIGN_CENTER); - fTrackNumber->SetHighColor(0,255,0); - fTrackNumber->SetFont(be_bold_font); + fCDTitle = new BStringView(view->Bounds(),"CDTitle",""); + view->AddChild(fCDTitle); + fCDTitle->SetHighColor(200,200,200); + fCDTitle->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()); AddChild(fVolume); - fVolume->SetEnabled(false); fStop = new DrawButton( BRect(0,0,1,1), "Stop", BTranslationUtils::GetBitmap('PNG ',"stop_up"), 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"), BTranslationUtils::GetBitmap('PNG ',"save_down"), new BMessage(M_SAVE), - B_FOLLOW_BOTTOM, B_WILL_DRAW); + B_FOLLOW_NONE, B_WILL_DRAW); fSave->ResizeToPreferred(); fSave->MoveTo(fEject->Frame().right + 20, Bounds().bottom - 5 - fSave->Frame().Height()); 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 fShuffle = new DrawButton( BRect(0,0,1,1), "Shuffle", BTranslationUtils::GetBitmap('PNG ',"shuffle_up"), BTranslationUtils::GetBitmap('PNG ',"shuffle_down"), new BMessage(M_SHUFFLE), - B_FOLLOW_BOTTOM, B_WILL_DRAW); + B_FOLLOW_NONE, B_WILL_DRAW); fShuffle->ResizeToPreferred(); fShuffle->MoveTo(fSave->Frame().right + 2, Bounds().bottom - 5 - fShuffle->Frame().Height()); 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"), BTranslationUtils::GetBitmap('PNG ',"repeat_down"), new BMessage(M_REPEAT), - B_FOLLOW_BOTTOM, B_WILL_DRAW); + B_FOLLOW_NONE, B_WILL_DRAW); fRepeat->ResizeToPreferred(); fRepeat->MoveTo(fShuffle->Frame().right + 2, Bounds().bottom - 5 - fRepeat->Frame().Height()); fRepeat->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"repeat_disabled")); @@ -183,13 +227,72 @@ void CDButton::BuildGUI(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: { // TODO: Implement + engine->SetVolume(fVolume->Value()); break; } case M_STOP: @@ -245,10 +348,10 @@ CDButton::MessageReceived(BMessage *message) default: { - if (!Observer::HandleObservingMessages(message)) + if (!Observer::HandleObservingMessages(msg)) { // just support observing messages - BView::MessageReceived(message); + BView::MessageReceived(msg); break; } } @@ -258,17 +361,17 @@ CDButton::MessageReceived(BMessage *message) void CDButton::NoticeChange(Notifier *notifier) { -// debugger(""); - PlayState *ps; TrackState *trs; TimeState *tms; CDContentWatcher *ccw; + VolumeState *vs; ps = dynamic_cast(notifier); trs = dynamic_cast(notifier); tms = dynamic_cast(notifier); ccw = dynamic_cast(notifier); + vs = dynamic_cast(notifier); if(ps) { @@ -286,6 +389,10 @@ CDButton::NoticeChange(Notifier *notifier) fRewind->SetEnabled(false); fSave->SetEnabled(false); } + fCurrentTrack->SetText("Track: "); + fTrackTime->SetText("Track --:-- / --:--"); + fDiscTime->SetText("Disc --:-- / --:--"); + printf("Notification: No CD\n"); break; } case kStopped: @@ -300,6 +407,10 @@ CDButton::NoticeChange(Notifier *notifier) fRewind->SetEnabled(true); fSave->SetEnabled(true); } + fCurrentTrack->SetText("Track: "); + fTrackTime->SetText("Track --:-- / --:--"); + fDiscTime->SetText("Disc --:-- / --:--"); + printf("Notification: CD Stopped\n"); break; } case kPaused: @@ -315,7 +426,7 @@ CDButton::NoticeChange(Notifier *notifier) fRewind->SetEnabled(true); fSave->SetEnabled(true); } - UpdateTrackInfo(); + printf("Notification: CD Paused\n"); break; } case kPlaying: @@ -330,7 +441,7 @@ CDButton::NoticeChange(Notifier *notifier) fRewind->SetEnabled(true); fSave->SetEnabled(true); } - UpdateTrackInfo(); + printf("Notification: CD Playing\n"); break; } case kSkipping: @@ -345,6 +456,7 @@ CDButton::NoticeChange(Notifier *notifier) fRewind->SetEnabled(true); fSave->SetEnabled(true); } + printf("Notification: CD Skipping\n"); break; } default: @@ -356,34 +468,69 @@ CDButton::NoticeChange(Notifier *notifier) else if(trs) { - UpdateTrackInfo(); + UpdateCDInfo(); + // TODO: Update track count indicator } else if(tms) { + UpdateTimeInfo(); } else if(ccw) { + UpdateCDInfo(); + } + else + if(vs) + { + fVolume->SetValue(engine->VolumeStateWatcher()->GetVolume()); } } void -CDButton::UpdateTrackInfo(void) +CDButton::UpdateCDInfo(void) { - - fCurrentTrack=engine->TrackStateWatcher()->GetTrack(); - fTrackCount=engine->TrackStateWatcher()->GetNumTracks(); + BString CDName, currentTrackName; + vector trackNames; - if(fCurrentTrack < 1) + int32 currentTrack = engine->TrackStateWatcher()->GetTrack(); + engine->ContentWatcher()->GetContent(&CDName,&trackNames); + + fCDTitle->SetText(CDName.String()); + + if(currentTrack > 0) { - char string[255]; - sprintf(string,"Track: %ld",fCurrentTrack); - fTrackNumber->SetText(string); + currentTrackName << "Track " << currentTrack << ": " << trackNames[ currentTrack - 1]; + fCurrentTrack->SetText(currentTrackName.String()); } 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 @@ -393,6 +540,9 @@ CDButton::AttachedToWindow() engine->AttachedToLooper(Window()); StartObserving(engine->TrackStateWatcher()); StartObserving(engine->PlayStateWatcher()); + StartObserving(engine->ContentWatcher()); + StartObserving(engine->TimeStateWatcher()); + StartObserving(engine->VolumeStateWatcher()); fVolume->SetTarget(this); fStop->SetTarget(this); @@ -407,12 +557,52 @@ CDButton::AttachedToWindow() 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 CDButton::Pulse() { engine->DoPulse(); } +void +CDButton::SetBitmap(BBitmap *bitmap) +{ + if(!bitmap) + { + ClearViewBitmap(); + return; + } + + SetViewBitmap(bitmap); + fVolume->SetViewBitmap(bitmap); + fVolume->Invalidate(); + Invalidate(); +} + class CDButtonWindow : public BWindow { public: @@ -421,8 +611,14 @@ public: }; 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) @@ -431,16 +627,23 @@ bool CDButtonWindow::QuitRequested(void) return true; } -CDButtonApplication::CDButtonApplication() - : BApplication("application/x-vnd.Be-CDPlayer") -{ - BWindow *window = new CDButtonWindow(); - - BView *button = new CDButton(window->Bounds(), "CD"); - window->AddChild(button); - window->Show(); -} +CDButtonWindow *cdbwin; +CDButton *cdbutton; +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 main(int, char **argv) diff --git a/src/apps/cdplayer/CDButton.h b/src/apps/cdplayer/CDButton.h index 04cec69163..d8ca408d08 100644 --- a/src/apps/cdplayer/CDButton.h +++ b/src/apps/cdplayer/CDButton.h @@ -35,6 +35,8 @@ public: virtual void AttachedToWindow(); virtual void Pulse(); + + virtual void FrameResized(float new_width, float new_height); virtual void MessageReceived(BMessage *); @@ -45,7 +47,11 @@ public: virtual void NoticeChange(Notifier *); private: - void UpdateTrackInfo(void); + void UpdateCDInfo(void); + void UpdateTimeInfo(void); + void SetBitmap(BBitmap *bitmap); + + bool fStopOnQuit; CDEngine *engine; @@ -54,11 +60,16 @@ private: BSlider *fVolume; - BTextControl *fCDTitle; - BStringView *fTrackNumber; + BStringView *fCDTitle; + BStringView *fCurrentTrack; + BStringView *fTrackTime; + BStringView *fDiscTime; + + BBox *fCDBox; + BBox *fTrackBox; + BBox *fTimeBox; CDState fCDState; - int32 fTrackCount, fCurrentTrack; }; diff --git a/src/apps/cdplayer/CDEngine.cpp b/src/apps/cdplayer/CDEngine.cpp index 7c5fd34f87..0befe0abad 100644 --- a/src/apps/cdplayer/CDEngine.cpp +++ b/src/apps/cdplayer/CDEngine.cpp @@ -15,6 +15,8 @@ #include "scsi.h" #include "CDEngine.h" +const bigtime_t kPulseRate = 500000; + PeriodicWatcher::PeriodicWatcher(int devicefd) : Notifier(), devicefd(devicefd) @@ -168,50 +170,67 @@ TimeState::UpdateState() status_t media_status = B_DEV_NO_MEDIA; ioctl(devicefd, B_GET_MEDIA_STATUS, &media_status, sizeof(media_status)); 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); - + if (result != B_NO_ERROR) - return CurrentState(-1, -1); - else if ((!pos.position[1]) || (pos.position[1] >= 0x13) || - ((pos.position[1] == 0x12) && (!pos.position[6]))) - return CurrentState(0, 0); + return CurrentState(-1, -1, -1, -1); + else + if ((!pos.position[1]) || (pos.position[1] >= 0x13) || + ((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 - return CurrentState(pos.position[9], pos.position[10]); + return CurrentState(pos.position[9], pos.position[10], pos.position[13], pos.position[14]); } 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; - oldMinutes = minutes; - oldSeconds = seconds; + + fDiscMinutes = dmin; + fDiscSeconds = dsec; + fTrackMinutes = tmin; + fTrackSeconds = tsec; + return true; } void -TimeState::GetTime(int32 &minutes, int32 &seconds) const +TimeState::GetDiscTime(int32 &minutes, int32 &seconds) const { - minutes = oldMinutes; - seconds = oldSeconds; + minutes = fDiscMinutes; + seconds = fDiscSeconds; +} + +void +TimeState::GetTrackTime(int32 &minutes, int32 &seconds) const +{ + minutes = fTrackMinutes; + seconds = fTrackSeconds; } CDContentWatcher::CDContentWatcher(int devicefd) : PeriodicWatcher(devicefd), - cddbQuery("us.cddb.com", 888, true), + cddbQuery("us.freedb.org", 888, true), discID(-1), - wasReady(false) + fReady(false) { } CDContentWatcher::CDContentWatcher(BMessage *message) : PeriodicWatcher(message), - cddbQuery("us.cddb.com", 888, true), + cddbQuery("us.freedb.org", 888, true), discID(-1), - wasReady(false) + fReady(false) { } @@ -224,23 +243,61 @@ CDContentWatcher::GetContent(BString *title, vector *tracks) bool CDContentWatcher::UpdateState() { - bool newReady = false; 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; ioctl(devicefd, B_SCSI_GET_TOC, &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; } +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) : BHandler("CDEngine"), devicefd(devicefd), @@ -318,12 +375,13 @@ void CDEngine::Play() { // play the CD - if (playState.GetState() == kNoCD) { + if (playState.GetState() == kNoCD) + { // no CD available, bail out ioctl(devicefd, B_LOAD_MEDIA, 0, 0); return; } - + scsi_play_track track; track.start_track = 1; @@ -332,7 +390,8 @@ CDEngine::Play() track.end_index = 1; 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))); return; } @@ -343,7 +402,8 @@ CDEngine::PlayContinue() { // continue after a pause 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))); return; } @@ -354,8 +414,9 @@ CDEngine::Stop() { // stop a playing CD status_t result = ioctl(devicefd, B_SCSI_STOP_AUDIO); - if (result != B_NO_ERROR) { - PRINT(("error %s stoping\n", strerror(errno))); + if (result != B_OK) + { + PRINT(("error %s stopping\n", strerror(errno))); return; } } @@ -371,9 +432,10 @@ CDEngine::Eject() // if door open, load the media, else eject the CD 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))); 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 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 bigtime_t time = system_time(); diff --git a/src/apps/cdplayer/CDEngine.h b/src/apps/cdplayer/CDEngine.h index 28ef3838fe..e6073db3a7 100644 --- a/src/apps/cdplayer/CDEngine.h +++ b/src/apps/cdplayer/CDEngine.h @@ -98,13 +98,18 @@ public: : PeriodicWatcher(message) {} - void GetTime(int32 &minutes, int32 &seconds) const; + void GetDiscTime(int32 &minutes, int32 &seconds) const; + void GetTrackTime(int32 &minutes, int32 &seconds) const; private: bool UpdateState(); - bool CurrentState(int32 minutes, int32 seconds); - int32 oldMinutes; - int32 oldSeconds; + bool CurrentState(int32 dmin, int32 dsec, int32 tmin, int32 tsec); + + int32 fDiscMinutes; + int32 fDiscSeconds; + + int32 fTrackMinutes; + int32 fTrackSeconds; }; class CDContentWatcher : public PeriodicWatcher { @@ -119,24 +124,24 @@ private: CDDBQuery cddbQuery; int32 discID; - bool wasReady; + bool fReady; }; 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 // currently not used yet public: - VolumeState(int devicefd) - : PeriodicWatcher(devicefd) - { } + VolumeState(int devicefd); VolumeState(BMessage *message) : PeriodicWatcher(message) {} - - bool UpdateState() { return true; } - virtual void DoPulse() {} + bool UpdateState(); int32 GetVolume() const; + +private: + int32 fVolume; + }; class CDEngine : public BHandler { @@ -168,6 +173,7 @@ public: void StopSkipping(); void SelectTrack(int32); + void SetVolume(uint8 value); TrackState *TrackStateWatcher() { return &trackState; } @@ -186,6 +192,11 @@ public: CDContentWatcher *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(); diff --git a/src/apps/cdplayer/CDPlayer.rdef b/src/apps/cdplayer/CDPlayer.rdef index e6476c71c7..bec65b8299 100644 --- a/src/apps/cdplayer/CDPlayer.rdef +++ b/src/apps/cdplayer/CDPlayer.rdef @@ -80,7 +80,7 @@ resource(101, "BEOS:M:STD_ICON") #'MICN' array { $"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;