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;