I didn't feel like working on the app_server today. 'Hope Sikosis doesn't mind. :D

Definitely a work in progress, but it'll play CDs at the moment.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13267 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
DarkWyrm 2005-06-24 21:29:28 +00:00
parent c641898150
commit 238e9fd71b
24 changed files with 3411 additions and 382 deletions

View File

@ -0,0 +1,451 @@
// Copyright 1992-1999, Be Incorporated, All Rights Reserved.
// This file may be used under the terms of the Be Sample Code License.
//
// send comments/suggestions/feedback to pavel@be.com
//
#include <Alert.h>
#include <Application.h>
#include <Bitmap.h>
#include <Box.h>
#include <Button.h>
#include <Debug.h>
#include <Deskbar.h>
#include <Dragger.h>
#include <Entry.h>
#include <MenuItem.h>
#include <PopUpMenu.h>
#include <Roster.h>
#include <Window.h>
#include <stdlib.h>
#include <string.h>
#include "CDButton.h"
#include "DrawButton.h"
#include <TranslationUtils.h>
enum
{
M_STOP='mstp',
M_PLAY,
M_NEXT_TRACK,
M_PREV_TRACK,
M_FFWD,
M_REWIND,
M_EJECT,
M_SAVE,
M_SHUFFLE,
M_REPEAT,
M_SET_VOLUME,
M_SET_CD_TITLE
};
CDButton::CDButton(BRect frame, const char *name, uint32 resizeMask, uint32 flags)
: BView(frame, name, resizeMask, flags)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
engine = new CDEngine(CDEngine::FindCDPlayerDevice());
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);
}
}
CDButton::~CDButton()
{
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));
BBox *box = new BBox(BRect(0,0,75,20),"TrackBox");
box->MoveTo(fCDTitle->Frame().right + 15, 5);
AddChild(box);
BView *view = new BView( box->Bounds().InsetByCopy(2,2), "view",B_FOLLOW_NONE,B_WILL_DRAW);
view->SetViewColor(0,0,0);
box->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);
fVolume = new BSlider( BRect(0,0,75,30), "VolumeSlider", "Volume", new BMessage(M_SET_VOLUME),0,100);
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),
B_FOLLOW_BOTTOM, B_WILL_DRAW);
fStop->ResizeToPreferred();
fStop->MoveTo(fVolume->Frame().right + 10, Bounds().bottom - 5 - fStop->Frame().Height());
fStop->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"stop_disabled"));
AddChild(fStop);
// TODO: Play is a special button. Implement as two-state buttons
fPlay = new DrawButton( BRect(0,0,1,1), "Play", BTranslationUtils::GetBitmap('PNG ',"play_up"),
BTranslationUtils::GetBitmap('PNG ',"play_down"), new BMessage(M_PLAY),
B_FOLLOW_BOTTOM, B_WILL_DRAW);
fPlay->ResizeToPreferred();
fPlay->MoveTo(fStop->Frame().right + 2, Bounds().bottom - 5 - fPlay->Frame().Height());
fPlay->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"play_disabled"));
AddChild(fPlay);
fPrevTrack = new DrawButton( BRect(0,0,1,1), "PrevTrack", BTranslationUtils::GetBitmap('PNG ',"prev_up"),
BTranslationUtils::GetBitmap('PNG ',"prev_down"), new BMessage(M_PREV_TRACK),
B_FOLLOW_BOTTOM, B_WILL_DRAW);
fPrevTrack->ResizeToPreferred();
fPrevTrack->MoveTo(fPlay->Frame().right + 10, Bounds().bottom - 5 - fPrevTrack->Frame().Height());
fPrevTrack->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"prev_disabled"));
AddChild(fPrevTrack);
fNextTrack = new DrawButton( BRect(0,0,1,1), "NextTrack", BTranslationUtils::GetBitmap('PNG ',"next_up"),
BTranslationUtils::GetBitmap('PNG ',"next_down"), new BMessage(M_NEXT_TRACK),
B_FOLLOW_BOTTOM, B_WILL_DRAW);
fNextTrack->ResizeToPreferred();
fNextTrack->MoveTo(fPrevTrack->Frame().right + 2, Bounds().bottom - 5 - fNextTrack->Frame().Height());
fNextTrack->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"next_disabled"));
AddChild(fNextTrack);
// TODO: Fast Forward and Rewind are special buttons. Implement as two-state buttons
fRewind = new DrawButton( BRect(0,0,1,1), "Rewind", BTranslationUtils::GetBitmap('PNG ',"rew_up"),
BTranslationUtils::GetBitmap('PNG ',"rew_down"), new BMessage(M_PREV_TRACK),
B_FOLLOW_BOTTOM, B_WILL_DRAW);
fRewind->ResizeToPreferred();
fRewind->MoveTo(fNextTrack->Frame().right + 10, Bounds().bottom - 5 - fRewind->Frame().Height());
fRewind->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"rew_disabled"));
AddChild(fRewind);
fFastFwd = new DrawButton( BRect(0,0,1,1), "FastFwd", BTranslationUtils::GetBitmap('PNG ',"ffwd_up"),
BTranslationUtils::GetBitmap('PNG ',"ffwd_down"), new BMessage(M_NEXT_TRACK),
B_FOLLOW_BOTTOM, B_WILL_DRAW);
fFastFwd->ResizeToPreferred();
fFastFwd->MoveTo(fRewind->Frame().right + 2, Bounds().bottom - 5 - fFastFwd->Frame().Height());
fFastFwd->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"ffwd_disabled"));
AddChild(fFastFwd);
fEject = new DrawButton( BRect(0,0,1,1), "Eject", BTranslationUtils::GetBitmap('PNG ',"eject_up"),
BTranslationUtils::GetBitmap('PNG ',"eject_down"), new BMessage(M_EJECT),
B_FOLLOW_BOTTOM, B_WILL_DRAW);
fEject->ResizeToPreferred();
fEject->MoveTo(fFastFwd->Frame().right + 20, Bounds().bottom - 5 - fEject->Frame().Height());
fEject->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"eject_disabled"));
AddChild(fEject);
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);
fSave->ResizeToPreferred();
fSave->MoveTo(fEject->Frame().right + 20, Bounds().bottom - 5 - fSave->Frame().Height());
fSave->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"save_disabled"));
AddChild(fSave);
fSave->SetEnabled(false);
// 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);
fShuffle->ResizeToPreferred();
fShuffle->MoveTo(fSave->Frame().right + 2, Bounds().bottom - 5 - fShuffle->Frame().Height());
fShuffle->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"shuffle_disabled"));
AddChild(fShuffle);
fShuffle->SetEnabled(false);
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);
fRepeat->ResizeToPreferred();
fRepeat->MoveTo(fShuffle->Frame().right + 2, Bounds().bottom - 5 - fRepeat->Frame().Height());
fRepeat->SetDisabled(BTranslationUtils::GetBitmap('PNG ',"repeat_disabled"));
AddChild(fRepeat);
fRepeat->SetEnabled(false);
}
void
CDButton::MessageReceived(BMessage *message)
{
switch (message->what)
{
case M_SET_VOLUME:
{
// TODO: Implement
break;
}
case M_STOP:
{
engine->Stop();
break;
}
case M_PLAY:
{
engine->PlayOrPause();
break;
}
case M_NEXT_TRACK:
{
engine->SkipOneForward();
break;
}
case M_PREV_TRACK:
{
engine->SkipOneBackward();
break;
}
case M_FFWD:
{
// TODO: Implement
break;
}
case M_REWIND:
{
// TODO: Implement
break;
}
case M_EJECT:
{
engine->Eject();
break;
}
case M_SAVE:
{
// TODO: Implement
break;
}
case M_SHUFFLE:
{
// TODO: Implement
break;
}
case M_REPEAT:
{
// TODO: Implement
break;
}
default:
{
if (!Observer::HandleObservingMessages(message))
{
// just support observing messages
BView::MessageReceived(message);
break;
}
}
}
}
void
CDButton::NoticeChange(Notifier *notifier)
{
// debugger("");
PlayState *ps;
TrackState *trs;
TimeState *tms;
CDContentWatcher *ccw;
ps = dynamic_cast<PlayState *>(notifier);
trs = dynamic_cast<TrackState *>(notifier);
tms = dynamic_cast<TimeState *>(notifier);
ccw = dynamic_cast<CDContentWatcher *>(notifier);
if(ps)
{
switch(ps->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);
}
break;
}
case kStopped:
{
if(!fStop->IsEnabled())
{
fStop->SetEnabled(true);
fPlay->SetEnabled(true);
fNextTrack->SetEnabled(true);
fPrevTrack->SetEnabled(true);
fFastFwd->SetEnabled(true);
fRewind->SetEnabled(true);
fSave->SetEnabled(true);
}
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);
fSave->SetEnabled(true);
}
UpdateTrackInfo();
break;
}
case kPlaying:
{
if(!fStop->IsEnabled())
{
fStop->SetEnabled(true);
fPlay->SetEnabled(true);
fNextTrack->SetEnabled(true);
fPrevTrack->SetEnabled(true);
fFastFwd->SetEnabled(true);
fRewind->SetEnabled(true);
fSave->SetEnabled(true);
}
UpdateTrackInfo();
break;
}
case kSkipping:
{
if(!fStop->IsEnabled())
{
fStop->SetEnabled(true);
fPlay->SetEnabled(true);
fNextTrack->SetEnabled(true);
fPrevTrack->SetEnabled(true);
fFastFwd->SetEnabled(true);
fRewind->SetEnabled(true);
fSave->SetEnabled(true);
}
break;
}
default:
{
break;
}
}
}
else
if(trs)
{
UpdateTrackInfo();
// TODO: Update track count indicator
}
else
if(tms)
{
}
else
if(ccw)
{
}
}
void
CDButton::UpdateTrackInfo(void)
{
fCurrentTrack=engine->TrackStateWatcher()->GetTrack();
fTrackCount=engine->TrackStateWatcher()->GetNumTracks();
if(fCurrentTrack < 1)
{
char string[255];
sprintf(string,"Track: %ld",fCurrentTrack);
fTrackNumber->SetText(string);
}
else
fTrackNumber->SetText("Track: --");
}
void
CDButton::AttachedToWindow()
{
// start observing
engine->AttachedToLooper(Window());
StartObserving(engine->TrackStateWatcher());
StartObserving(engine->PlayStateWatcher());
fVolume->SetTarget(this);
fStop->SetTarget(this);
fPlay->SetTarget(this);
fNextTrack->SetTarget(this);
fPrevTrack->SetTarget(this);
fFastFwd->SetTarget(this);
fRewind->SetTarget(this);
fEject->SetTarget(this);
fSave->SetTarget(this);
fShuffle->SetTarget(this);
fRepeat->SetTarget(this);
}
void
CDButton::Pulse()
{
engine->DoPulse();
}
class CDButtonWindow : public BWindow
{
public:
CDButtonWindow(void);
bool QuitRequested(void);
};
CDButtonWindow::CDButtonWindow(void)
: BWindow(BRect (100, 100, 610, 400), "CD Player", B_TITLED_WINDOW, 0)
{
}
bool CDButtonWindow::QuitRequested(void)
{
be_app->PostMessage(B_QUIT_REQUESTED);
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();
}
int
main(int, char **argv)
{
(new CDButtonApplication())->Run();
return 0;
}

View File

@ -0,0 +1,72 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
// This defines the replicant button
#ifndef __CD_BUTTON__
#define __CD_BUTTON__
#include <Application.h>
#include <View.h>
#include <Window.h>
#include <View.h>
#include <Button.h>
#include <Slider.h>
#include <TextControl.h>
#include <StringView.h>
#include "Observer.h"
#include "CDEngine.h"
class DrawButton;
class CDButton : public BView, private Observer
{
public:
CDButton(BRect frame, const char *name, uint32 resizeMask = B_FOLLOW_ALL,
uint32 flags = B_WILL_DRAW | B_NAVIGABLE | B_PULSE_NEEDED);
virtual ~CDButton();
void BuildGUI(void);
// misc BView overrides
virtual void AttachedToWindow();
virtual void Pulse();
virtual void MessageReceived(BMessage *);
// observing overrides
virtual BHandler *RecipientHandler() const
{ return (BHandler *)this; }
virtual void NoticeChange(Notifier *);
private:
void UpdateTrackInfo(void);
CDEngine *engine;
DrawButton *fStop, *fPlay, *fNextTrack, *fPrevTrack;
DrawButton *fFastFwd, *fRewind, *fEject, *fSave, *fShuffle, *fRepeat;
BSlider *fVolume;
BTextControl *fCDTitle;
BStringView *fTrackNumber;
CDState fCDState;
int32 fTrackCount, fCurrentTrack;
};
class CDButtonApplication : public BApplication
{
public:
CDButtonApplication();
};
#endif

View File

@ -0,0 +1,583 @@
// Copyright 1992-2000, Be Incorporated, All Rights Reserved.
// This file may be used under the terms of the Be Sample Code License.
//
// send comments/suggestions/feedback to pavel@be.com
//
#include "CDDBSupport.h"
#include <Debug.h>
#include <Directory.h>
#include <Entry.h>
#include <File.h>
#include <FindDirectory.h>
#include <NetAddress.h>
#include <Path.h>
#include <Query.h>
#include <Volume.h>
#include <VolumeRoster.h>
#include <errno.h>
#include <fs_index.h>
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
// #pragma mark -
// some glue
template <class InitCheckable>
void
InitCheck(InitCheckable *item)
{
if (!item)
throw B_ERROR;
status_t error = item->InitCheck();
if (error != B_OK)
throw error;
}
inline void
ThrowOnError(status_t error)
{
if (error != B_OK)
throw error;
}
inline void
ThrowIfNotSize(ssize_t size)
{
if (size < 0)
throw (status_t)size;
}
// #pragma mark -
CDDBQuery::CDDBQuery(const char *server, int32 port, bool log)
: log(log),
serverName(server),
port(port),
connected(false),
discID(-1),
state(kInitial)
{
}
void
CDDBQuery::SetToSite(const char *server, int32 port)
{
Disconnect();
serverName = server;
port = port;
state = kInitial;
}
void
CDDBQuery::SetToCD(const scsi_toc *toc)
{
if (state == kInitial) {
GetDiscID(toc, discID, numTracks, discLength, frameOffsetString, discIDStr);
} else {
int32 tmpDiscID;
int32 tmpDiscLength;
int32 tmpNumTracks;
BString tmpFrameOffsetString;
BString tmpDiscIDStr;
GetDiscID(toc, tmpDiscID, tmpNumTracks, tmpDiscLength, tmpFrameOffsetString,
tmpDiscIDStr);
if (discID == tmpDiscID && discLength == tmpDiscLength && numTracks == tmpNumTracks
&& frameOffsetString == frameOffsetString)
return;
discID = tmpDiscID;
discLength = tmpDiscLength;
numTracks = tmpNumTracks;
frameOffsetString = tmpFrameOffsetString;
discIDStr = tmpDiscIDStr;
}
// ToDo:
// add interrupting here
result = B_OK;
state = kReading;
thread = spawn_thread(&CDDBQuery::LookupBinder, "CDDBLookup", B_NORMAL_PRIORITY, this);
if (thread >= 0)
resume_thread(thread);
else {
state = kError;
result = thread;
}
}
const int kTerminatingSignal = SIGINT; // SIGCONT;
static void
DoNothing(int)
{
}
int32
CDDBQuery::LookupBinder(void *castToThis)
{
CDDBQuery *query = (CDDBQuery *)castToThis;
BFile file;
entry_ref ref;
bool newFile = false;
try {
signal(kTerminatingSignal, DoNothing);
if (!query->FindOrCreateContentFileForDisk(&file, &ref, query->discID)) {
// new content file, read it in from the server
Connector connection(query);
query->ReadFromServer(&file);
file.Seek(0, SEEK_SET);
newFile = true;
}
query->ParseResult(&file);
query->state = kDone;
query->thread = -1;
query->result = B_OK;
if (newFile) {
BString newTitle(query->title);
int32 length = newTitle.Length();
for (int32 index = 0; index < length; index++) {
if (newTitle[index] == '/' || newTitle[index] == ':')
newTitle[index] = '-';
}
file.Sync();
BEntry entry(&ref);
entry.Rename(newTitle.String(), false);
}
} catch (status_t error) {
query->state = kError;
query->result = error;
// the cached file is messed up, remove it
BEntry entry(&ref);
BPath path;
entry.GetPath(&path);
printf("removing bad CD content file %s\n", path.Path());
entry.Remove();
}
return 0;
}
const char *
CDDBQuery::GetToken(const char *stream, BString &result)
{
result = "";
while (*stream && *stream <= ' ')
stream++;
while (*stream && *stream > ' ')
result += *stream++;
return stream;
}
void
CDDBQuery::GetSites(bool (*eachFunc)(const char *site, int port, const char *latitude,
const char *longitude, const char *description, void *state), void *passThru)
{
// ToDo:
// add interrupting here
Connector connection(this);
BString tmp;
tmp = "sites\n";
if (log)
printf(">%s", tmp.String());
ThrowIfNotSize( socket.Send(tmp.String(), tmp.Length()) );
ReadLine(tmp);
if (tmp.FindFirst("210") == -1)
throw (status_t)B_ERROR;
for (;;) {
BString site;
int32 sitePort;
BString latitude;
BString longitude;
BString description;
ReadLine(tmp);
if (tmp == ".")
break;
const char *scanner = tmp.String();
scanner = GetToken(scanner, site);
BString portString;
scanner = GetToken(scanner, portString);
sitePort = atoi(portString.String());
scanner = GetToken(scanner, latitude);
scanner = GetToken(scanner, longitude);
description = scanner;
if (eachFunc(site.String(), sitePort, latitude.String(), longitude.String(),
description.String(), passThru))
break;
}
}
bool
CDDBQuery::GetTitles(BString *resultingTitle, vector<BString> *tracks, bigtime_t timeout)
{
bigtime_t deadline = system_time() + timeout;
while (state == kReading) {
snooze(50000);
if (system_time() > deadline)
break;
}
if (state != kDone)
return false;
if (resultingTitle)
*resultingTitle = title;
if (tracks)
*tracks = trackNames;
return true;
}
static int32
cddb_sum(int n)
{
char buf[12];
int32 ret = 0;
sprintf(buf, "%u", n);
for (const char *p = buf; *p != '\0'; p++)
ret += (*p - '0');
return ret;
}
struct ConvertedToc {
int32 min;
int32 sec;
int32 frame;
};
int32
CDDBQuery::GetDiscID(const scsi_toc *toc)
{
int32 tmpDiscID;
int32 tmpDiscLength;
int32 tmpNumTracks;
BString tmpFrameOffsetString;
BString tmpDiscIDStr;
GetDiscID(toc, tmpDiscID, tmpNumTracks, tmpDiscLength, tmpFrameOffsetString,
tmpDiscIDStr);
return tmpDiscID;
}
void
CDDBQuery::GetDiscID(const scsi_toc *toc, int32 &id, int32 &numTracks,
int32 &length, BString &frameOffsetsString, BString &discIDString)
{
ConvertedToc tocData[100];
// figure out the disc ID
for (int index = 0; index < 100; index++) {
tocData[index].min = toc->toc_data[9 + 8*index];
tocData[index].sec = toc->toc_data[10 + 8*index];
tocData[index].frame = toc->toc_data[11 + 8*index];
}
numTracks = toc->toc_data[3] - toc->toc_data[2] + 1;
int32 sum1 = 0;
int32 sum2 = 0;
for (int index = 0; index < numTracks; index++) {
sum1 += cddb_sum((tocData[index].min * 60) + tocData[index].sec);
// the following is probably running over too far
sum2 += (tocData[index + 1].min * 60 + tocData[index + 1].sec) -
(tocData[index].min * 60 + tocData[index].sec);
}
id = ((sum1 % 0xff) << 24) + (sum2 << 8) + numTracks;
discIDString = "";
sprintf(discIDString.LockBuffer(10), "%08lx", id);
discIDString.UnlockBuffer();
// compute the total length of the CD.
length = tocData[numTracks].min * 60 + tocData[numTracks].sec;
for (int index = 0; index < numTracks; index++)
frameOffsetsString << tocData[index].min * 4500 + tocData[index].sec * 75
+ tocData[index].frame << ' ';
}
void
CDDBQuery::ReadFromServer(BDataIO *stream)
{
// Format the query
BString query;
query << "cddb query " << discIDStr << ' ' << numTracks << ' '
// Add frame offsets
<< frameOffsetString << ' '
// Finish it off with the total CD length.
<< discLength << '\n';
if (log)
printf(">%s", query.String());
// Send it off.
ThrowIfNotSize( socket.Send(query.String(), query.Length()) );
BString tmp;
ReadLine(tmp);
if (tmp.FindFirst("200") != 0)
return;
BString category;
GetToken(tmp.String() + 3, category);
if (!category.Length())
category = "misc";
query = "";
query << "cddb read " << category << ' ' << discIDStr << '\n' ;
ThrowIfNotSize( socket.Send(query.String(), query.Length()) );
for (;;) {
BString tmp;
ReadLine(tmp);
tmp += '\n';
ThrowIfNotSize( stream->Write(tmp.String(), tmp.Length()) );
if (tmp == "." || tmp == ".\n")
break;
}
state = kDone;
}
void
CDDBQuery::ParseResult(BDataIO *source)
{
title = "";
trackNames.clear();
for (;;) {
BString tmp;
ReadLine(source, tmp);
if (tmp == ".")
break;
if (tmp == "")
throw (status_t)B_ERROR;
if (tmp.FindFirst("DTITLE=") == 0)
title = tmp.String() + sizeof("DTITLE");
else if (tmp.FindFirst("TTITLE") == 0) {
int32 afterIndex = tmp.FindFirst('=');
if (afterIndex > 0) {
BString trackName(tmp.String() + afterIndex + 1);
trackNames.push_back(trackName);
}
}
}
state = kDone;
}
void
CDDBQuery::Connect()
{
BNetAddress address(serverName.String(), port);
InitCheck(&address);
ThrowOnError( socket.Connect(address) );
connected = true;
BString tmp;
ReadLine(tmp);
IdentifySelf();
}
bool
CDDBQuery::IsConnected() const
{
return connected;
}
void
CDDBQuery::Disconnect()
{
socket.Close();
connected = false;
}
void
CDDBQuery::ReadLine(BString &buffer)
{
buffer = "";
char ch;
for (;;) {
if (socket.Receive(&ch, 1) <= 0)
break;
if (ch >= ' ')
buffer += ch;
if (ch == '\n')
break;
}
if (log)
printf("<%s\n", buffer.String());
}
void
CDDBQuery::ReadLine(BDataIO *stream, BString &buffer)
{
// this is super-lame, should use better buffering
// ToDo:
// redo using LockBuffer, growing the buffer by 2k and reading into it
buffer = "";
char ch;
for (;;) {
ssize_t result = stream->Read(&ch, 1);
if (result < 0)
// read error
throw (status_t)result;
if (result == 0)
break;
if (ch >= ' ')
buffer += ch;
if (ch == '\n')
break;
}
}
void
CDDBQuery::IdentifySelf()
{
char username[256];
if (!getusername(username,256))
strcpy(username, "unknown");
char hostname[MAXHOSTNAMELEN + 1];
if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
strcpy(hostname, "unknown");
BString tmp;
tmp << "cddb hello " << username << " " << hostname << " CDButton v1.0\n";
if (log)
printf(">%s", tmp.String());
ThrowIfNotSize( socket.Send(tmp.String(), tmp.Length()) );
ReadLine(tmp);
}
bool
CDDBQuery::FindOrCreateContentFileForDisk(BFile *file, entry_ref *fileRef, int32 discID)
{
BString predicate;
predicate << "cddb:discID == " << discID;
entry_ref ref;
BVolumeRoster roster;
BVolume volume;
roster.Rewind();
while (roster.GetNextVolume(&volume) == B_OK) {
if (volume.IsReadOnly() || !volume.IsPersistent()
|| !volume.KnowsAttr() || !volume.KnowsQuery())
continue;
// make sure the volume we are looking at is indexed right
fs_create_index(volume.Device(), "cddb:discID", B_INT32_TYPE, 0);
BQuery query;
query.SetVolume(&volume);
query.SetPredicate(predicate.String());
if (query.Fetch() != B_OK)
continue;
while (query.GetNextRef(&ref) == B_OK) {
// we have one already, return
file->SetTo(&ref, O_RDONLY);
*fileRef = ref;
return true;
}
}
BPath path;
ThrowOnError( find_directory(B_USER_SETTINGS_DIRECTORY, &path, true) );
path.Append("CDContentFiles");
ThrowOnError( create_directory(path.Path(), 0755) );
BDirectory dir(path.Path());
BString name("CDContent");
for (int32 index = 0; ;index++) {
if (dir.CreateFile(name.String(), file, true) != B_FILE_EXISTS) {
BEntry entry(&dir, name.String());
entry.GetRef(fileRef);
file->WriteAttr("cddb:discID", B_INT32_TYPE, 0, &discID, sizeof(int32));
break;
}
name = "CDContent";
name << index;
}
return false;
}
#if 0
bool
PrintSite(const char *site, int port, const char *latitude,
const char *longitude, const char *description, void *)
{
printf("server:%s port:%d latitude:%s longitude:%s description: %s\n",
site, port, latitude, longitude, description);
return false;
}
int
main()
{
try {
CDDBQuery query("us.cddb.com", 888, true);
// query.GetSites(&PrintSite, NULL);
int32 device = CDEngine::FindCDPlayerDevice();
if (!device) {
printf("no device %s\n", strerror(device));
return 0;
}
CDEngine engine(device);
scsi_toc toc;
engine.GetToc(&toc);
query.SetToCD(&toc);
BString title;
vector<BString> trackTitles;
query.GetTitles(title, trackTitles, 10000000);
printf("CD Title:%s\n", title.String());
int32 index = 0;
for (vector<BString>::iterator iterator = trackTitles.begin();
iterator != trackTitles.end(); index++, iterator++)
printf("%d: %s\n", index, (*iterator).String());
} catch(status_t error) {
printf("error %s\n", strerror(error));
}
return 0;
}
#endif

View File

@ -0,0 +1,107 @@
#ifndef __CDDBSUPPORT__
#define __CDDBSUPPORT__
#include <NetEndpoint.h>
#include <String.h>
#include <scsi.h>
#include <vector>
// based on Jukebox by Chip Paul
class CDDBQuery {
public:
CDDBQuery(const char *server, int32 port = 888, bool log = false);
void SetToSite(const char *server, int32 port);
void GetSites(bool (*)(const char *site, int port, const char *latitude,
const char *longitude, const char *description, void *state), void *);
void SetToCD(const scsi_toc *);
bool GetTitles(BString *title, vector<BString> *tracks, bigtime_t timeout);
// title or tracks may be NULL if you are only interrested in one, not the other
bool Ready() const
{ return state == kDone; }
int32 CurrentDiscID() const
{ return discID; }
static int32 GetDiscID(const scsi_toc *);
private:
static void GetDiscID(const scsi_toc *, int32 &id, int32 &numTracks, int32 &length,
BString &tmpFrameOffsetString, BString &discIDString);
void Connect();
void Disconnect();
bool IsConnected() const;
static int32 LookupBinder(void *);
class Connector {
public:
Connector(CDDBQuery *client)
: client(client),
wasConnected(client->IsConnected())
{
if (!wasConnected)
client->Connect();
}
~Connector()
{
if (!wasConnected)
client->Disconnect();
}
private:
CDDBQuery *client;
bool wasConnected;
};
bool FindOrCreateContentFileForDisk(BFile *file, entry_ref *ref, int32 discID);
void ReadFromServer(BDataIO *);
void ParseResult(BDataIO *);
void ReadLine(BString &);
static void ReadLine(BDataIO *, BString &);
void IdentifySelf();
const char *GetToken(const char *, BString &);
bool log;
// connection description
BString serverName;
BNetEndpoint socket;
int32 port;
bool connected;
// disc identification
int32 discID;
int32 discLength;
int32 numTracks;
BString frameOffsetString;
BString discIDStr;
// cached retrieved data
enum State {
kInitial,
kReading,
kDone,
kInterrupting,
kError
};
thread_id thread;
State state;
BString title;
vector<BString> trackNames;
status_t result;
friend class Connector;
};
#endif

View File

@ -0,0 +1,607 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Debug.h>
#include <Entry.h>
#include <Directory.h>
#include <Path.h>
#include <errno.h>
#include "scsi.h"
#include "CDEngine.h"
PeriodicWatcher::PeriodicWatcher(int devicefd)
: Notifier(),
devicefd(devicefd)
{
}
PeriodicWatcher::PeriodicWatcher(BMessage *)
: devicefd(-1)
{
// not implemented yet
PRINT(("under construction"));
}
BHandler *
PeriodicWatcher::RecipientHandler() const
{
return engine;
}
void
PeriodicWatcher::DoPulse()
{
// control the period here
if (UpdateState())
Notify();
}
void
PeriodicWatcher::UpdateNow()
{
UpdateState();
}
PlayState::PlayState(int devicefd)
: PeriodicWatcher(devicefd),
oldState(kNoCD)
{
}
bool
PlayState::UpdateState()
{
// check the current CD play state and force a notification to
// be sent if it changed from last time
scsi_position pos;
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(kNoCD);
status_t result = ioctl(devicefd, B_SCSI_GET_POSITION, &pos);
if (result != B_NO_ERROR)
return CurrentState(kNoCD);
else if ((!pos.position[1]) || (pos.position[1] >= 0x13) ||
((pos.position[1] == 0x12) && (!pos.position[6])))
return CurrentState(kStopped);
else if (pos.position[1] == 0x11)
return CurrentState(kPlaying);
else
return CurrentState(kPaused);
}
CDState
PlayState::GetState() const
{
return oldState;
}
bool
PlayState::CurrentState(CDState newState)
{
if (newState != oldState) {
oldState = newState;
return true;
}
return false;
}
TrackState::TrackState(int devicefd)
: PeriodicWatcher(devicefd),
currentTrack(0)
{
}
int32
TrackState::GetTrack() const
{
return currentTrack;
}
bool
TrackState::UpdateState()
{
// check the current CD track number and force a notification to
// be sent if it changed from last time
scsi_position pos;
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);
status_t result = ioctl(devicefd, B_SCSI_GET_POSITION, &pos);
if (result != B_NO_ERROR)
return CurrentState(-1);
if (!pos.position[1] || pos.position[1] >= 0x13
|| (pos.position[1] == 0x12 && !pos.position[6]))
return CurrentState(0);
else
return CurrentState(pos.position[6]);
}
int32
TrackState::GetNumTracks() const
{
// get the number of tracks on the current CD
scsi_toc toc;
status_t result = ioctl(devicefd, B_SCSI_GET_TOC, &toc);
if (result != B_NO_ERROR)
return 0;
return toc.toc_data[3];
}
bool
TrackState::CurrentState(int32 track)
{
if (track != currentTrack) {
currentTrack = track;
return true;
}
return false;
}
bool
TimeState::UpdateState()
{
// check the current CD time and force a notification to
// be sent if it changed from last time
// currently only supports global time
scsi_position pos;
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);
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);
else
return CurrentState(pos.position[9], pos.position[10]);
}
bool
TimeState::CurrentState(int32 minutes, int32 seconds)
{
if (minutes == oldMinutes && seconds == oldSeconds)
return false;
oldMinutes = minutes;
oldSeconds = seconds;
return true;
}
void
TimeState::GetTime(int32 &minutes, int32 &seconds) const
{
minutes = oldMinutes;
seconds = oldSeconds;
}
CDContentWatcher::CDContentWatcher(int devicefd)
: PeriodicWatcher(devicefd),
cddbQuery("us.cddb.com", 888, true),
discID(-1),
wasReady(false)
{
}
CDContentWatcher::CDContentWatcher(BMessage *message)
: PeriodicWatcher(message),
cddbQuery("us.cddb.com", 888, true),
discID(-1),
wasReady(false)
{
}
bool
CDContentWatcher::GetContent(BString *title, vector<BString> *tracks)
{
return cddbQuery.GetTitles(title, tracks, 1000000);
}
bool
CDContentWatcher::UpdateState()
{
bool newReady = false;
bool newDiscID = -1;
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);
}
bool result = newReady != cddbQuery.Ready() && newDiscID != discID;
newReady = cddbQuery.Ready();
newDiscID = discID;
return result;
}
CDEngine::CDEngine(int devicefd)
: BHandler("CDEngine"),
devicefd(devicefd),
playState(devicefd),
trackState(devicefd),
timeState(devicefd),
volumeState(devicefd),
contentWatcher(devicefd)
{
}
CDEngine::CDEngine(BMessage *message)
: BHandler(message),
devicefd(-1),
playState(message),
trackState(message),
timeState(message),
volumeState(message),
contentWatcher(devicefd)
{
}
CDEngine::~CDEngine()
{
if(devicefd >= 0)
close(devicefd);
}
void
CDEngine::AttachedToLooper(BLooper *looper)
{
looper->AddHandler(this);
playState.AttachedToLooper(this);
trackState.AttachedToLooper(this);
timeState.AttachedToLooper(this);
volumeState.AttachedToLooper(this);
contentWatcher.AttachedToLooper(this);
}
void
CDEngine::PlayOrPause()
{
// if paused, or stopped, plays, if playing, pauses
playState.UpdateNow();
switch (playState.GetState()) {
case kNoCD:
Play();
return;
case kStopped:
Play();
break;
case kPaused:
PlayContinue();
break;
case kPlaying:
Pause();
break;
default:
break;
}
}
void
CDEngine::Pause()
{
// pause the CD
status_t result = ioctl(devicefd, B_SCSI_PAUSE_AUDIO);
if (result != B_NO_ERROR) {
PRINT(("error %s pausing\n", strerror(errno)));
return;
}
}
void
CDEngine::Play()
{
// play the CD
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;
track.start_index = 1;
track.end_track = 99;
track.end_index = 1;
status_t result = ioctl(devicefd, B_SCSI_PLAY_TRACK, &track);
if (result != B_NO_ERROR) {
PRINT(("error %s playing track\n", strerror(errno)));
return;
}
}
void
CDEngine::PlayContinue()
{
// continue after a pause
status_t result = ioctl(devicefd, B_SCSI_RESUME_AUDIO);
if (result != B_NO_ERROR) {
PRINT(("error %s resuming\n", strerror(errno)));
return;
}
}
void
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)));
return;
}
}
void
CDEngine::Eject()
{
// eject or load a CD
status_t media_status = B_DEV_NO_MEDIA;
// get the status first
ioctl(devicefd, B_GET_MEDIA_STATUS, &media_status, sizeof(media_status));
// 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);
if (result != B_NO_ERROR) {
PRINT(("error %s ejecting\n", strerror(errno)));
return;
}
}
void
CDEngine::SkipOneForward()
{
// skip forward by one track
CDState state = playState.GetState();
if (state == kNoCD)
return;
bool wasPaused = state == kPaused
|| state == kStopped;
SelectTrack(trackState.GetTrack() + 1);
if (wasPaused)
// make sure we don't start playing if we were paused before
Pause();
}
void
CDEngine::SkipOneBackward()
{
// skip backward by one track
CDState state = playState.GetState();
if (state == kNoCD)
return;
bool wasPaused = state == kPaused
|| state == kStopped;
int32 track = trackState.GetTrack();
if (track > 1)
track--;
SelectTrack(track);
if (wasPaused)
// make sure we don't start playing if we were paused before
Pause();
}
void
CDEngine::StartSkippingBackward()
{
// start skipping
CDState state = playState.GetState();
if (state == kNoCD)
return;
scsi_scan scan;
scan.direction = -1;
scan.speed = 1;
status_t result = ioctl(devicefd, B_SCSI_SCAN, &scan);
if (result != B_NO_ERROR) {
PRINT(("error %s skipping backward\n", strerror(errno)));
return;
}
}
void
CDEngine::StartSkippingForward()
{
// start skipping
CDState state = playState.GetState();
if (state == kNoCD)
return;
scsi_scan scan;
scan.direction = 1;
scan.speed = 1;
status_t result = ioctl(devicefd, B_SCSI_SCAN, &scan);
if (result != B_NO_ERROR) {
PRINT(("error %s skipping forward\n", strerror(errno)));
return;
}
}
void
CDEngine::StopSkipping()
{
// stop skipping
CDState state = playState.GetState();
if (state == kNoCD)
return;
scsi_scan scan;
scan.direction = 0;
scan.speed = 1;
status_t result = ioctl(devicefd, B_SCSI_SCAN, &scan);
if (result != B_NO_ERROR) {
PRINT(("error %s in stop skipping\n", strerror(errno)));
return;
}
result = ioctl(devicefd, B_SCSI_RESUME_AUDIO);
if (result != B_NO_ERROR) {
PRINT(("error %s resuming\n", strerror(errno)));
return;
}
}
void
CDEngine::SelectTrack(int32 trackNumber)
{
// go to a selected track
if (playState.GetState() == kNoCD)
return;
scsi_play_track track;
track.start_track = trackNumber;
track.start_index = 1;
track.end_track = 99;
track.end_index = 1;
status_t result = ioctl(devicefd, B_SCSI_PLAY_TRACK, &track);
if (result != B_NO_ERROR) {
PRINT(("error %s playing track\n", strerror(errno)));
return;
}
}
const bigtime_t kPulseRate = 500000;
void
CDEngine::DoPulse()
{
// this is the CDEngine's hearbeat; 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();
if (time > lastPulse && time < lastPulse + kPulseRate)
return;
// every pulse rate have all the different state watchers check the
// curent state and send notifications if anything changed
lastPulse = time;
playState.DoPulse();
trackState.DoPulse();
timeState.DoPulse();
volumeState.DoPulse();
contentWatcher.DoPulse();
}
void
CDEngine::MessageReceived(BMessage *message)
{
if (message->what == 'slTk') {
// handle message from menu selection
int32 track;
if (message->FindInt32("track", &track) == B_OK)
SelectTrack(track);
} else
// handle observing
if (!Notifier::HandleObservingMessages(message)
&& !CDEngineFunctorFactory::DispatchIfFunctionObject(message))
BHandler::MessageReceived(message);
}
static int
try_dir(const char *directory)
{
BDirectory dir;
dir.SetTo(directory);
if(dir.InitCheck() != B_NO_ERROR) {
return false;
}
dir.Rewind();
BEntry entry;
while(dir.GetNextEntry(&entry) >= 0) {
BPath path;
const char *name;
entry_ref e;
if(entry.GetPath(&path) != B_NO_ERROR)
continue;
name = path.Path();
if(entry.GetRef(&e) != B_NO_ERROR)
continue;
if(entry.IsDirectory()) {
if(strcmp(e.name, "floppy") == 0)
continue; // ignore floppy (it is not silent)
int devfd = try_dir(name);
if(devfd >= 0)
return devfd;
}
else {
int devfd;
device_geometry g;
if(strcmp(e.name, "raw") != 0)
continue; // ignore partitions
devfd = open(name, O_RDONLY);
if(devfd < 0)
continue;
if(ioctl(devfd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0) {
if(g.device_type == B_CD)
{
return devfd;
}
}
close(devfd);
}
}
return B_ERROR;
}
int
CDEngine::FindCDPlayerDevice()
{
return try_dir("/dev/disk");
}

View File

@ -0,0 +1,226 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
// This defines an engine that tracks the state of the CD player
// and supports the CD player control and status calls
#ifndef __CD_ENGINE__
#define __CD_ENGINE__
#include <Looper.h>
#include <String.h>
#include <View.h>
#include <vector>
#include "Observer.h"
#include "FunctionObjectMessage.h"
#include "CDDBSupport.h"
class CDEngine;
class PeriodicWatcher : public Notifier {
// watcher sits somewhere were it can get pulses and makes sure
// notices get sent if state changes
public:
PeriodicWatcher(int devicefd);
PeriodicWatcher(BMessage *);
virtual ~PeriodicWatcher() {}
void DoPulse();
void UpdateNow();
void AttachedToLooper(CDEngine *engine)
{ this->engine = engine; }
virtual BHandler *RecipientHandler() const;
protected:
virtual bool UpdateState() = 0;
int devicefd;
CDEngine *engine;
};
enum CDState {
kNoCD=0,
kStopped,
kPaused,
kPlaying,
kSkipping
};
class PlayState : public PeriodicWatcher {
// this watcher sends notices to observers that are interrested
// about play state changes
public:
PlayState(int devicefd);
PlayState(BMessage *message)
: PeriodicWatcher(message)
{}
CDState GetState() const;
private:
bool UpdateState();
bool CurrentState(CDState);
CDState oldState;
};
class TrackState : public PeriodicWatcher {
// this watcher sends notices to observers that are interrested
// about changes in the current track
public:
TrackState(int devicefd);
TrackState(BMessage *message)
: PeriodicWatcher(message)
{}
int32 GetTrack() const;
int32 GetNumTracks() const;
private:
bool UpdateState();
bool CurrentState(int32);
int32 currentTrack;
};
class TimeState : public PeriodicWatcher {
// this watcher sends notices to observers that are interrested
// about changes in the current time
public:
TimeState(int devicefd)
: PeriodicWatcher(devicefd)
{ }
TimeState(BMessage *message)
: PeriodicWatcher(message)
{}
void GetTime(int32 &minutes, int32 &seconds) const;
private:
bool UpdateState();
bool CurrentState(int32 minutes, int32 seconds);
int32 oldMinutes;
int32 oldSeconds;
};
class CDContentWatcher : public PeriodicWatcher {
public:
CDContentWatcher(int devicefd);
CDContentWatcher(BMessage *message);
bool GetContent(BString *title, vector<BString> *tracks);
private:
bool UpdateState();
CDDBQuery cddbQuery;
int32 discID;
bool wasReady;
};
class VolumeState : public PeriodicWatcher {
// this watcher sends notices to observers that are interrested
// about changes in the current volume
// currently not used yet
public:
VolumeState(int devicefd)
: PeriodicWatcher(devicefd)
{ }
VolumeState(BMessage *message)
: PeriodicWatcher(message)
{}
bool UpdateState() { return true; }
virtual void DoPulse() {}
int32 GetVolume() const;
};
class CDEngine : public BHandler {
// The CD engine defines all the different CD control calls; also,
// it hosts the different state watchers and helps them send notices
// to observers about the CD state changes
public:
CDEngine(int devicefd);
CDEngine(BMessage *);
virtual ~CDEngine();
// observing supprt
virtual void MessageReceived(BMessage *);
void AttachedToLooper(BLooper *);
void DoPulse();
// control calls
void PlayOrPause();
void PlayContinue();
void Play();
void Pause();
void Stop();
void Eject();
void SkipOneForward();
void SkipOneBackward();
void StartSkippingBackward();
void StartSkippingForward();
void StopSkipping();
void SelectTrack(int32);
TrackState *TrackStateWatcher()
{ return &trackState; }
// to find the current Track, you may call the GetTrack function
// TrackState defines
PlayState *PlayStateWatcher()
{ return &playState; }
// to find the current play state, you may call the GetState function
// PlayState defines
TimeState *TimeStateWatcher()
{ return &timeState; }
// to find the current location on the CD, you may call the GetTime function
// TimeState defines
CDContentWatcher *ContentWatcher()
{ return &contentWatcher; }
static int FindCDPlayerDevice();
private:
int devicefd;
PlayState playState;
TrackState trackState;
TimeState timeState;
VolumeState volumeState;
CDContentWatcher contentWatcher;
bigtime_t lastPulse;
};
// some function object glue
class CDEngineFunctorFactory : public FunctorFactoryCommon {
public:
static BMessage *NewFunctorMessage(void (CDEngine::*func)(),
CDEngine *target)
{
PlainMemberFunctionObject<void (CDEngine::*)(),
CDEngine> tmp(func, target);
return NewMessage(&tmp);
}
static BMessage *NewFunctorMessage(void (CDEngine::*func)(ulong),
CDEngine *target, ulong param)
{
SingleParamMemberFunctionObject<void (CDEngine::*)(ulong),
CDEngine, ulong> tmp(func, target, param);
return NewMessage(&tmp);
}
};
#endif

View File

@ -1,76 +0,0 @@
/*
CDPlayer
Author: Sikosis
(C)2004 Haiku - http://haiku-os.org/
*/
// Includes ------------------------------------------------------------------------------------------ //
#include <Alert.h>
#include <Application.h>
#include <Button.h>
#include <Entry.h>
#include <File.h>
#include <FilePanel.h>
#include <ListView.h>
#include <Path.h>
#include <Screen.h>
#include <ScrollView.h>
#include <stdio.h>
#include <string.h>
#include <TextControl.h>
#include <Window.h>
#include <View.h>
#include "CDPlayer.h"
#include "CDPlayerWindows.h"
#include "CDPlayerViews.h"
#include "CDPlayerConstants.h"
// Constants ---------------------------------------------------------------------------------------- //
const char *APP_SIGNATURE = "application/x-vnd.Haiku.CDPlayer"; // Application Signature and Title
// -------------------------------------------------------------------------------------------------- //
CDPlayerWindow *ptrCDPlayerWindow;
// CDPlayer - Constructor
CDPlayer::CDPlayer() : BApplication (APP_SIGNATURE)
{
// Default Window Size - Position doesn't matter as we centre the form to the current screen size
BRect screenFrame = (BScreen(B_MAIN_SCREEN_ID).Frame());
float FormTopDefault = 0;
float FormLeftDefault = 0;
float FormWidthDefault = 500;
float FormHeightDefault = 100;
BRect CDPlayerWindowRect(FormTopDefault,FormLeftDefault,FormLeftDefault+FormWidthDefault,FormTopDefault+FormHeightDefault);
ptrCDPlayerWindow = new CDPlayerWindow(CDPlayerWindowRect);
}
// ------------------------------------------------------------------------------------------------- //
// CDPlayer::MessageReceived -- handles incoming messages
void CDPlayer::MessageReceived (BMessage *message)
{
switch(message->what)
{
default:
BApplication::MessageReceived(message); // pass it along ...
break;
}
}
// ------------------------------------------------------------------------------------------------- //
// CDPlayer Main
int main(void)
{
CDPlayer theApp;
theApp.Run();
return 0;
}
// end --------------------------------------------------------------------------------------------- //

View File

@ -1,25 +0,0 @@
/*
CDPlayer Header
Author: Sikosis
(C)2004 Haiku - http://haiku-os.org/
*/
#ifndef __CDPLAYER_H__
#define __CDPLAYER_H__
extern const char *APP_SIGNATURE;
class CDPlayer : public BApplication
{
public:
CDPlayer();
virtual void MessageReceived(BMessage *message);
private:
};
#endif

View File

@ -1,8 +1,32 @@
resource(1, "BEOS:FILE_TYPES") message;
resource(1, "BEOS:APP_FLAGS") #'APPF' $"00000000";
resource(101, "BEOS:L:STD_ICON") #'ICON' array
{
resource(1, "BEOS:APP_VERSION") #'APPV' array {
$"00000000000000000100000001000000000000004344506C6179657200000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000426173696320434420506C61"
$"79657220666F72204861696B7500000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000"
};
resource(101, "BEOS:L:STD_ICON") #'ICON' array {
$"FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFF00F90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
@ -37,8 +61,7 @@ resource(101, "BEOS:L:STD_ICON") #'ICON' array
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000E0F0FFFFFFFFFFFFFFFFFFFFFFFFF"
};
resource(101, "BEOS:M:STD_ICON") #'MICN' array
{
resource(101, "BEOS:M:STD_ICON") #'MICN' array {
$"FFFFFFFF000000FFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFF005D0000FFFFFFFFFFFFFF"
$"FFFFFFFFFFFF007D7D0000FFFFFFFFFF"
@ -59,30 +82,387 @@ resource(101, "BEOS:M:STD_ICON") #'MICN' array
resource(1, "BEOS:APP_SIG") #'MIMS' "application/x-vnd.Haiku.CDPlayer";
resource(1, "BEOS:APP_VERSION") #'APPV' array
{
$"00000000000000000100000001000000000000004344506C6179657200000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000426173696320434420506C61"
$"79657220666F72204861696B7500000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000000000000000000000000000000000000000000000000000"
$"0000000000000000"
resource(1, "BEOS:FILE_TYPES") message;
resource(1, "play_up") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C770000009549444154789C8591BB11C5200C04578C4A"
$"51AD8E5FE0F22076074E79013F83E5E112E058A10324030492A4243901920122"
$"448980E484C502351504104DCD0B8059E77A45AC151DAC32AD6343A60ED62695"
$"EA88AF1EA84BAF7B367E613979B4335B9DE10DA765D065ED657C547D4AF2B521"
$"8E53E1DE40230F94DB396FA5ABE1706E66B369F93AC7E9A69BFD17F3F1B7CAE1"
$"6F3CF407D134242111EC44A10000000049454E44AE426082"
};
resource(1, "BEOS:APP_FLAGS") #'APPF' $"00000000";
resource(2, "play_down") #'PNG ' array {
$"89504E470D0A1A0A0000000D49484452000000230000001308060000001AA3B4"
$"F40000008D49444154789CCDD6C10904210C40D13F8B4DD84E4AB00E2BB038CB"
$"B18DEC6109CC6D5123E69F151E6AC0075002A4AA24805AEB55486B0DE0870128"
$"A55CC3589FDB8077D3181141444E58D64FE6046AFB9A3C516E6FC603E5FE8077"
$"50A1A629FD5F3257EF7D79AF1B6607616D633C10D632C613614D634E20AC50D3"
$"140AF3003AC6B8ED20E74C520DF1D103E00B489821B04B2C9C09000000004945"
$"4E44AE426082"
};
resource(3, "play_disabled") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C770000009B49444154789C8591BB15C4200C04473C95"
$"7265509FE30BAE249571C4EEC0290ECCC760F9B109B08CD0029201946411C909"
$"900C6832A2FC01C9098B00812AC975A2A97A01306B5CAB88A5A281451FBD46AB"
$"C8D0C1EAA4500DF1D50235E97E8CC6374C27F77666B3D3BDEED40C3AADBD8CB7"
$"AA5749DE17C4F653381650CF03D7ED9CB7D2D9703837B3D9B07C9CE374D3C5FE"
$"8379F95B65F3376E3A010B1C24319A2F2A100000000049454E44AE426082"
};
resource(4, "stop_up") #'PNG ' array {
$"89504E470D0A1A0A0000000D49484452000000230000001308060000001AA3B4"
$"F40000006E49444154789CEDD6310E80300840D18FE9517AD69EB27B6FD01507"
$"63D481585D60E0CF0C2F0C04515525402242011863B8425A6B00070660CEE986"
$"39DBBC01F7CAFBC8B35AEBD25CEFFD3326D46612639518ABC45825C6EAF305FE"
$"7359570BB599509802D73FE19D00213E3D801DE2CC137C9B1F7C290000000049"
$"454E44AE426082"
};
resource(5, "stop_down") #'PNG ' array {
$"89504E470D0A1A0A0000000D49484452000000230000001308060000001AA3B4"
$"F40000007649444154789CEDD6B10DC0200C00C1276209D66104E6600286631C"
$"D6708A285252A0401ABBF0D72E4E2E2C074030908810016AADAA90D61AC08501"
$"28A5A861EE0E6DC0B3F83DF22EE7BC34D77BDFC698DA8C636639669663663966"
$"D6F605FE73595733B519539800C81843DB414A892862E2D103E004602A1406AE"
$"0663330000000049454E44AE426082"
};
resource(6, "stop_disabled") #'PNG ' array {
$"89504E470D0A1A0A0000000D49484452000000230000001308060000001AA3B4"
$"F40000006F49444154789CEDD6310E80300840D18FE9B17ABE9EAC77E90DBAE2"
$"608C3A10AB0B0CFC99E1858120AAAA0448442800630C57486B0DE0C000CC39DD"
$"30679B37E05E791F79D67B5F9AABB57EC684DA4C62AC12639518ABC4587DBEC0"
$"7F2EEB6AA136130A53E0FA27BC1320C4A707B0036170119C944D95F600000000"
$"49454E44AE426082"
};
resource(7, "next_up") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C770000009649444154789C858E3B1684300C03C73C1F"
$"C567A5DE628FA7D4DC80365B04F221B0A84AEC9125CB000BC952B29C00CB0002"
$"9900CB8950814E1504304F00217020A89C004C0717E574AF38CE45C469EC12A2"
$"454D4666D54255BEEDE3E0B334F71817EDA24F21AD922E8CEAC6DB5F57D7B32C"
$"6F2FC4FA75D85FA0D699525BC74B0FCCC83D3327F79FD144F9B49FE5B7842ECC"
$"7AEBEDF50309A3288D19DE43630000000049454E44AE426082"
};
resource(8, "next_down") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C770000009649444154789C858ECB1583400C03C73C37"
$"410769232E813AA880E2544EDA2007F6C3624874F27AC792E090900C417B2313"
$"608810C044D2EE0208810341E30460D5EF7DB62EAB621711F5F0941075B839B4"
$"3D1749B2751917AFA91B8F71D1C2F094DF2BE9C2F45EDEDFBA5EB53EA9B4B13E"
$"952FDA6687E50FD43B73D45699F4C08CDC3353B9DF8C12E5E93FCB6F8991353E"
$"B7B727CD5FEB601F32B3AD1E6C0000000049454E44AE426082"
};
resource(9, "next_disabled") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C770000009A49444154789C858EBB1584300C04473C95"
$"4219AA8FF8822B4965E0980E487D01FE1B8E8D646B56BB120194E086C4004804"
$"3438263B2031E006B09025310F1A00DC4001A77006207BE2D6EB74AB359D73F7"
$"6C6C12BC464D46669542457A9CFDC767A987FB38F7EA9AF26B251B182B1BAD6F"
$"1B5DCF9278BC10DB57E17C816A67AEDA96267B607AEE99C9DC7FC6264AA7FD2C"
$"BD256C60B65B6FAB1F14962A7DEE40835F0000000049454E44AE426082"
};
resource(10, "prev_up") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C770000009649444154789C858FB911C3300C04171A94"
$"825A153B707960AC0E94D201FF67CC8B38C4DEE12011E022480812032011C0C1"
$"C5018901F30401584500D100600E9A6789F3CE515246D945C9334BC6CCD720F6"
$"4656D54255FABCE3C7A7D52F11BA44EAB22257F2E5279FD85CDE611767497C0E"
$"C4FD55780F50BB02B0DCC0182A0F4C99FFCBD91333E35B6EDEB5E3749ACEAFC4"
$"DCDB0EBD7E98BA296A78A62B700000000049454E44AE426082"
};
resource(11, "prev_down") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C770000009949444154789C858FC115C3200C43BF792C"
$"910DBA463D42E6C804194EE3748DF41008E0D04627B064498613423204D71F99"
$"0043B80012004E87230BC005F9E212A06EA3BA8C789F240EEEC53455B2854C16"
$"EDE019B6ADE3E0D5D52FF6F91697637CADA4DBA49CD8B6D4C91211F7D2C6F6AB"
$"7CC1BE64581F44ED0AC04B0367A83C682AFFCF67AE881A4D75316BA6CB818D2F"
$"00E333EDD061F902FBC91FF2833D9C250000000049454E44AE426082"
};
resource(12, "prev_disabled") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C770000009C49444154789C858FB911C3300C04171A94"
$"E232509F62072E096598B13A504A07FC9FB12EE2F0F68083440025B821310012"
$"010D8EC917901870033800F0820088060037D0EC25CEBA84E529A35EC9C4C13D"
$"05335F07B10FB2AA16AAD2EB1E3FDEAD7E19AFCB3A9DD7974AB6FCE4135BCA3A"
$"ECE05912AF07E2FC28DC0F50BB02F0DCC0192A0F4CF1FFCDD91333635B6EDEB5"
$"E37472E75762CE6D875E3FEE602ABACC9639B80000000049454E44AE426082"
};
resource(13, "ffwd_up") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C770000009F49444154789C858F3B16843008452F1E96"
$"92B55A4F31CB7BD6EEC0365324928F8EBE8243E0022F9601C8802C6F80650081"
$"4C80E52D09800580140860BE01A5AF4289051012982A97CAEA5EC9EB3695D02E"
$"941B257033C8556128E4FB31163ECBB4393E94CE003E1A50B3541CAA31F1AE95"
$"EEDD4D3DC8F2FE42AC5F87E3050ACFA430D0B29979E006E6EC9E996E1905D55D"
$"F3B13F6723F39700679D4B17FD00CCDC346454415F090000000049454E44AE42"
$"6082"
};
resource(14, "ffwd_down") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C770000009F49444154789C858FCB15C3300804073F35"
$"E10ED24628C175B88214B7E5A40DE720097DE2441CF46019C1021132D40A9009"
$"30E459DE0070BAB892001790C0C1111B2024B03AEFD98F2E522AD3949FB6A1EC"
$"C88B6E3EDAC53AEC3C46E1B14D93E320AF0FA4D1809AA56C438D89BA285DDDFD"
$"6A7EBE4C1BE7E286D79EE05840E1190F032D9B993FDCC0D46ECD74CB28A86E5B"
$"1AFB7336323F0930DEB334C7FE0115B3282C4AE639D10000000049454E44AE42"
$"6082"
};
resource(15, "ffwd_disabled") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C77000000A849444154789C858FBB15844008452F1E4A"
$"B10CEA33DE601BD85E28C389EDC0740CC6F9EAEA0B38C05CE08D4400E5072631"
$"0012010D8EC90A480C6E004C007846004403E006283838C604186620EBC9CD69"
$"75AB59CF6D9642BD906EA4C0CD2057154345BAED7DE3330D9BCB873C07D0DE80"
$"554BC9A155A6D467A7A99BA90749DC5E88E5ABB0BF40C5335E0CD46C641EB88E"
$"C9AF39B35BC60AD55CD3FE7DCC7AE62F01CA32B62E3A00C80630E7BA72D89A00"
$"00000049454E44AE426082"
};
resource(16, "rew_up") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C77000000A149444154789C8590311684200C447F7839"
$"4ACE6ABD85C71B6B6F60CB160882ACEB14BCBCF09319B00C40066479032C0308"
$"64022C6F10021200444500F3ADF484439466022101A6938BB2BA57785BA77254"
$"876847B51F0799D50235F97E8C8D4FEAE703C0273BBFDB9328D150DF29CF93AE"
$"A911AB5EFF64797F2196D5E17881AAFBA96819AEAA67E2473532CFC4C5A8DD6A"
$"E2FA3C4FDC98B9FBDCAE7296C9FFAE2FF13F3064D77552650000000049454E44"
$"AE426082"
};
resource(17, "rew_down") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C77000000AA49444154789C8592BB0DC3300C441F052D"
$"E12675D60847F01C9E20C3DD24A95C780DA7D0CFB26C9885209147DE2320A821"
$"43ED01320186C0058454F1D6C11E53878B582B0184045899F7398ECEA958C729"
$"1DC5C18F2E178DB6F31CB6CC7DE29DF1F3F8171007BB78B62790D01A4600D27A"
$"52EB6AB2B52ED2F10CD0C6F2B0C3778A303F888A7B0EAFA80EFCD6B3C62F6EBD"
$"E65ED134AA550DBA23CF9DAE67A6FB771919631BFC4F31FD01075828D428AF1D"
$"AC0000000049454E44AE426082"
};
resource(18, "rew_disabled") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C77000000AA49444154789C8590B911C3300C04171A94"
$"A232509F62076EC0BDB00C3156074AE9007C45CBBA00830197B8232501281F30"
$"49119004680C98EC80A408C180050042460044A3CF0C85E0C3050C3340F6CCAD"
$"BEBAD7AA759D79290EA196623F5E64560D54A5C7390E5E397EB75E273BBDDAB3"
$"E0D1BC94893FCFACDD1AB1E2F54F928E07627B2B9C0F5071CF0A3543EB7A26FC"
$"E846E69E688CD5539BB83ECF1D3766EE3EB7EB946DF2BFEA0B7B823033032405"
$"7B0000000049454E44AE426082"
};
resource(19, "eject_up") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C770000008E49444154789C8D913116C4200805071F47"
$"E1ACA953ECF1629D1B6C6B0A233ED164F737CA6704542900892C394BC9801440"
$"339000AA490BA12100A22D59B3E6BB239E70F09679D26CA851CB58B0DEE503B9"
$"F4FC8EC6DEFBC5765D7D80E7FE7AAF4774ACBB1A9185A49C6F6960FB28846BD8"
$"54739AB00FFFC8184C509A91094A0B2442FFFC980ED1FA9994ED679D0B07B91C"
$"F1A3B1DDDF0000000049454E44AE426082"
};
resource(20, "eject_down") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C770000009049444154789C8591D111C3200C431F9C97"
$"C8065DA31E217364820CE771B246FA110E834DAEFA010B5916000F0CB382B58A"
$"62400570B292704BEFA800DA7736770CD60DDF7EA83A793C361AA801E5CE5C16"
$"1DFB4C7C7C5E1CE7F000EFF3A5AD16197556A26411BA702C728F383781700D8D"
$"EF98137AF8578D4212D52C49A2BA9044D1E2C71264AAD29500285CFF6CB61FF3"
$"3B15C0D5E713DD0000000049454E44AE426082"
};
resource(21, "eject_disabled") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C770000009149444154789C8D91BB11C4200C051746A5"
$"5C19D4E7D8C195A43688DD81532E309F41C2F6BD04F4B44802420110B22642C9"
$"402880642002D5A485D01080202D7965B5EF923DD1C1AA4F4FAA4E35AE326AAC"
$"67F581BAE43867631FFD6CBBA131C07D7FA96BB28E0E572CB25028C7531AD8BE"
$"02E61AEA6ABA09C7F0B78C8283A2471C14178885FEF93199A2F53309DB6B9D1F"
$"5A8523B87099497F0000000049454E44AE426082"
};
resource(22, "save_up") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C77000000AD49444154789CA5D0316EC4300C04C0A1E0"
$"2AAF70A1EFE51BA953DCF32440A9EE07AE0E500ACB675C622306C2462477B15C"
$"6D7448AA5A1395E84835D428885E650A13348F418198AA8126F4CECAFBB2750F"
$"9B0A322890935F358DB7615EDB03D6413D0DED52F7E579B0C0E7AA943B7A3ED1"
$"DE0CF49F9B68078EC6E254A78CCF9F79BE1F030B6FE0E336B16CEBBCBB0A6507"
$"AE24748533BD4C7181A3C1DCE67FDD2A7904397B492BFAFB5F32B76F1913323C"
$"2181DF6C0000000049454E44AE426082"
};
resource(23, "save_down") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C77000000A549444154789CA590CB11C3200C449F189A"
$"F08D63DA3025B80E5790E2E44E32E492369403E0908013CF642FE8B3B3BB0200"
$"049D371C6C1428A6A2794504050790120DCC2BCDD60CC003776A75A3AA00B168"
$"03B3A3832F6F02422E072CB17ED693D6653754804B568A06583CD0AE01EC7322"
$"6990A80C0E75B41C3F0E2DACDF4FE03A79586A175FA964971DBAF738C3F16F9D"
$"9CE09000420A7F79692C1F1968CF4278FC92999E50C526E88C462E9A00000000"
$"49454E44AE426082"
};
resource(24, "save_disabled") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C77000000B649444154789CA5D0BB6DC4301004D04781"
$"A5B80C06EC84DD5C7C811B50270A18BA043370741D5C74802E10751F5B020478"
$"13EE67767638618641D3DA4023CC18DAA8856F84B9A9242264B70E81109B3E1D"
$"500A0BEEC79ADDA4CE820A127C0CFE44EC6FC6B4A41BA88D78087A525DAE8F83"
$"09CE0B532D2875877B15507E77C6BCA1A837767952FFFC9EE6CBEE6C89D367E4"
$"BA56F5A96A7CA53DE2D0114C7CABC6031819A63CFDEB56AADDC8C99B5BD16973"
$"F7EB25BF0326ED2E5BFED7474F0000000049454E44AE426082"
};
resource(25, "repeat_up") #'PNG ' array {
$"89504E470D0A1A0A0000000D49484452000000230000001308030000015A7A74"
$"5000000012504C5445FFFFFF000000E6E6E6DCDCDC6C6C6C008300BB001C5100"
$"0000096F464673000000000000000000DA2AB6CE000000097048597300000FA0"
$"00000FA001A06A8C770000007E49444154789CAD8F510EC0200843ADD5FB5F79"
$"90AA1B62B264593FB6525E104A9148D0BFE4ACCDA9244CAB6D662026A80976A8"
$"E9FDA39B16F31723448A21C2D49885A49255C930AC59A24334A8C31204889F93"
$"6DC5B6BDEEC961E77A96E1320DE98CE7D3E8DDCE1283CC605562B6AD9F10FF66"
$"4ED01DE5BBB29C696FC205B240065004A187160000000049454E44AE426082"
};
resource(26, "repeat_down") #'PNG ' array {
$"89504E470D0A1A0A0000000D49484452000000230000001308030000015A7A74"
$"5000000012504C5445000000FFFFFF6C6C6CE6E6E6BEBEBE0083004C8424AC00"
$"0000096F464673000000000000000000DA2AB6CE000000097048597300000FA0"
$"00000FA001A06A8C770000007C49444154789CAD90510EC0200843CBACF7BFF2"
$"40D40D313159D60F85478320E022413BF5EEB991963632CB4631245E04AB7851"
$"B58F4688714584E86240F3B9DE4B92907591A15951E28B78A30A2508267E26CB"
$"886579DDC866E6EBA022698DF041B5EA5AEE41F66066EE59A67E9BF8B767677A"
$"50DE2BCB3CE524B9012C9D0763558616CC0000000049454E44AE426082"
};
resource(27, "repeat_up_on") #'PNG ' array {
$"89504E470D0A1A0A0000000D49484452000000230000001308030000015A7A74"
$"5000000012504C5445FFFFFF000000E6E6E66C6C6CDCDCDC00FF00911226CA00"
$"0000096F464673000000000000000000DA2AB6CE000000097048597300000FA0"
$"00000FA001A06A8C770000007B49444154789CAD8FDB0EC0200843AD96FFFFE5"
$"6110276262B2AC0F0AE5844B292612EC2FE9B9469612AA59D660202A58111458"
$"B1D78F9187F02F5A88148305D7E885A49255C9D0ACA963875823813A08103F3B"
$"DB8A6D9BDE9DC3CEF5A28674C63A1A227A9631C80C6666CCB6F50AF16FE604BD"
$"56BE2BAB33ED263C9CF907A6D61A86EF0000000049454E44AE426082"
};
resource(28, "repeat_down_on") #'PNG ' array {
$"89504E470D0A1A0A0000000D49484452000000230000001308030000015A7A74"
$"5000000012504C5445000000FFFFFF6C6C6CE6E6E6BEBEBE00FF00CF0E125600"
$"0000096F464673000000000000000000DA2AB6CE000000097048597300000FA0"
$"00000FA001A06A8C770000007C49444154789CAD90510EC0200843CBACF7BFF2"
$"40D40D313159D60F85478320E022413BF5EEB991963632CB4631245E04AB7851"
$"B58F4688714584E86240F3B9DE4B92907591A15951E28B78A30A2508267E26CB"
$"886579DDC866E6EBA022698DF041B5EA5AEE41F66066EE59A67E9BF8B767677A"
$"50DE2BCB3CE524B9012C9D0763558616CC0000000049454E44AE426082"
};
resource(29, "repeat_disabled") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C77000000B749444154789C8D90BD15C3200C843FF254"
$"658E8CA13A63A574ED22D3B8D618A18D37704B0AC008E2FCA841EF743A4E1712"
$"8010310D290221011281134048D100AD634C330520483400BD111E05BB9CA8D5"
$"BAB20BA6E57134C0401D5FF781E4E1080FB51B6A7BEBD6E9EB2C59482D0B2D10"
$"9E4BAF38779E86133E2392459D45F9E2B5795E8F071B9C0198EE02FD194E76B3"
$"85ABE6846AAC1D57B31DA5A4E828B5D54AE2E8AEF7FA97D3F218FC789D83843C"
$"244C3FFF7A014CCF345764741A860000000049454E44AE426082"
};
resource(30, "shuffle_up") #'PNG ' array {
$"89504E470D0A1A0A0000000D49484452000000230000001308030000015A7A74"
$"5000000012504C5445FFFFFF000000E6E6E66C6C6CDCDCDC0083001298103000"
$"0000096F464673000000000000000000DA2AB6CE000000097048597300000FA0"
$"00000FA001A06A8C770000008E49444154789C85925B16802008449DC4FD6F39"
$"E46581E57C100EF720786A4D452C8F715E26113803C05F4758B0228DC8088D21"
$"E19E5EA4DEAD5842CDEE8012D22559DABFA8555DE9BE9E9C81EC5061D4818C02"
$"1B881D9845E1F86131A5CF66E6EBA08EBCC67BA73178AD7F46063B3132E064E0"
$"3BC9EBFBABEB91EC2EAD58D9330DD830FE2B44D8311F77F5937003992A073AE8"
$"E0FDC50000000049454E44AE426082"
};
resource(31, "shuffle_down") #'PNG ' array {
$"89504E470D0A1A0A0000000D49484452000000230000001308030000015A7A74"
$"5000000012504C5445000000FFFFFF6C6C6CE6E6E6BEBEBE0083004C8424AC00"
$"0000096F464673000000000000000000DA2AB6CE000000097048597300000FA0"
$"00000FA001A06A8C770000008749444154789C85925B168020084487C4FD6F39"
$"792847B09C0F8E0CD7800A30F1D08C2B0F5312F3B19021F222F775621248B9DD"
$"DB846A298518430FD9528A8A50F5A47E2D391DD9E1C29803D8C63A86DC825BBC"
$"9C9904539E7398F9B9A8515E63DFA9F7B1D63FA383DD181D509878D9B00FCE91"
$"B2F7B28A97E7C9020E8CFF0A114ECC47AF7613BD278906D3979AD3BB00000000"
$"49454E44AE426082"
};
resource(32, "shuffle_up_on") #'PNG ' array {
$"89504E470D0A1A0A0000000D49484452000000230000001308030000015A7A74"
$"5000000012504C5445FFFFFF000000E6E6E66C6C6CDCDCDC00FF00911226CA00"
$"0000096F464673000000000000000000DA2AB6CE000000097048597300000FA0"
$"00000FA001A06A8C770000008E49444154789C85925B16802008449DC4FD6F39"
$"E46581E57C100EF720786A4D452C8F715E26113803C05F4758B0228DC8088D21"
$"E19E5EA4DEAD5842CDEE8012D22559DABFA8555DE9BE9E9C81EC5061D4818C02"
$"1B881D9845E1F86131A5CF66E6EBA08EBCC67BA73178AD7F46063B3132E064E0"
$"3BC9EBFBABEB91EC2EAD58D9330DD830FE2B44D8311F77F5937003992A073AE8"
$"E0FDC50000000049454E44AE426082"
};
resource(33, "shuffle_down_on") #'PNG ' array {
$"89504E470D0A1A0A0000000D49484452000000230000001308030000015A7A74"
$"5000000012504C5445000000FFFFFF6C6C6CE6E6E6BEBEBE00FF00CF0E125600"
$"0000096F464673000000000000000000DA2AB6CE000000097048597300000FA0"
$"00000FA001A06A8C770000008749444154789C85925B168020084487C4FD6F39"
$"792847B09C0F8E0CD7800A30F1D08C2B0F5312F3B19021F222F775621248B9DD"
$"DB846A298518430FD9528A8A50F5A47E2D391DD9E1C29803D8C63A86DC825BBC"
$"9C9904539E7398F9B9A8515E63DFA9F7B1D63FA383DD181D509878D9B00FCE91"
$"B2F7B28A97E7C9020E8CFF0A114ECC47AF7613BD278906D3979AD3BB00000000"
$"49454E44AE426082"
};
resource(34, "shuffle_disabled") #'PNG ' array {
$"89504E470D0A1A0A0000000D494844520000002300000013080000000148CFDB"
$"BE000000096F464673000000000000000000DA2AB6CE00000009704859730000"
$"0FA000000FA001A06A8C77000000C449444154789C7D91B115C2301043BFFD3C"
$"0A63A8661B56A0A4A66001D648AD31480B1BA43585ED042721AA2C9DDE597717"
$"324062042200210369E6218F0058213F4156B50084548A5C09AFAA9DA2B131FC"
$"68AD4B83758AF410440CD8002E8FB431ED610E34237DA6FEBFFBAAD300E13DF5"
$"DA7D9D091218614018998885D112262217E29667D3792FF3677F9819B74782E9"
$"6FD903676D36D4A3A63CF4D43922D86DFF06B743148A8B07C958AA2AA2D13A7D"
$"BF43999EEF781065CBB29703877C394C0D3CBE855E4A1104D8C6E70000000049"
$"454E44AE426082"
};

View File

@ -1,22 +0,0 @@
/*
CDPlayer Constants
Author: Sikosis
(C)2004 Haiku - http://haiku-os.org/
*/
#ifndef __CDPLAYERCONSTANTS_H__
#define __CDPLAYERCONSTANTS_H__
// Pointers to BWindows
extern CDPlayerWindow* ptrCDPlayerWindow;
// Product Name and Properties
const char projtitle[]="CDPlayer";
const char projversion[]="v0.1";
const char projauthor[]="Sikosis";
#endif

View File

@ -1,35 +0,0 @@
/*
CDPlayer View
Author: Sikosis
(C)2004 Haiku - http://haiku-os.org/
*/
// Includes ------------------------------------------------------------------------------------------ //
#include <Alert.h>
#include <Application.h>
#include <Screen.h>
#include <stdio.h>
#include <Window.h>
#include <View.h>
#include "CDPlayerWindows.h"
#include "CDPlayerViews.h"
// -------------------------------------------------------------------------------------------------- //
// CDPlayerView - Constructor
CDPlayerView::CDPlayerView (BRect frame) : BView (frame, "CDPlayerView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW )
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
}
// ------------------------------------------------------------------------------------------------- //
void CDPlayerView::Draw(BRect /*updateRect*/)
{
BRect r;
r = Bounds();
}
// ------------------------------------------------------------------------------------------------- //

View File

@ -1,24 +0,0 @@
/*
CDPlayer Views Header
Author: Sikosis
(C)2004 Haiku - http://haiku-os.org/
*/
#ifndef __CDPlayerVIEWS_H__
#define __CDPlayerVIEWS_H__
#include "CDPlayer.h"
#include "CDPlayerWindows.h"
class CDPlayerView : public BView
{
public:
CDPlayerView(BRect frame);
virtual void Draw(BRect updateRect);
};
#endif

View File

@ -1,134 +0,0 @@
/*
CDPlayerWindow
Author: Sikosis
(C)2004 Haiku - http://haiku-os.org/
*/
// Includes ------------------------------------------------------------------------------------------ //
#include <Alert.h>
#include <Application.h>
#include <Button.h>
#include <File.h>
#include <FindDirectory.h>
#include <Path.h>
#include <Screen.h>
#include <ScrollView.h>
#include <stdio.h>
#include <string.h>
#include <TextControl.h>
#include <Window.h>
#include <View.h>
#include "CDPlayer.h"
#include "CDPlayerWindows.h"
#include "CDPlayerViews.h"
// -------------------------------------------------------------------------------------------------- //
// CenterWindowOnScreen -- Centers the BWindow to the Current Screen
static void CenterWindowOnScreen(BWindow* w)
{
BRect screenFrame = (BScreen(B_MAIN_SCREEN_ID).Frame()); BPoint pt;
pt.x = screenFrame.Width()/2 - w->Bounds().Width()/2;
pt.y = screenFrame.Height()/2 - w->Bounds().Height()/2;
if (screenFrame.Contains(pt))
w->MoveTo(pt);
}
// -------------------------------------------------------------------------------------------------- //
// CDPlayerWindow - Constructor
CDPlayerWindow::CDPlayerWindow(BRect frame) : BWindow (frame, "CD Player", B_TITLED_WINDOW, B_NORMAL_WINDOW_FEEL , 0)
{
InitWindow();
CenterWindowOnScreen(this);
// Load User Settings
BPath path;
find_directory(B_USER_SETTINGS_DIRECTORY,&path);
path.Append("CDPlayer_Settings",true);
BFile file(path.Path(),B_READ_ONLY);
BMessage msg;
msg.Unflatten(&file);
LoadSettings (&msg);
Show();
}
// -------------------------------------------------------------------------------------------------- //
// CDPlayerWindow - Destructor
CDPlayerWindow::~CDPlayerWindow()
{
//exit(0); - this is bad i seem to remember someone telling me ...
}
// -------------------------------------------------------------------------------------------------- //
// CDPlayerWindow::InitWindow -- Initialization Commands here
void CDPlayerWindow::InitWindow(void)
{
BRect r;
r = Bounds(); // the whole view
// Create the Views
AddChild(ptrCDPlayerView = new CDPlayerView(r));
}
// -------------------------------------------------------------------------------------------------- //
// CDPlayerWindow::QuitRequested -- Post a message to the app to quit
bool CDPlayerWindow::QuitRequested()
{
SaveSettings();
be_app->PostMessage(B_QUIT_REQUESTED);
return true;
}
// -------------------------------------------------------------------------------------------------- //
// CDPlayerWindow::LoadSettings -- Loads your current settings
void CDPlayerWindow::LoadSettings(BMessage *msg)
{
BRect frame;
if (B_OK == msg->FindRect("windowframe",&frame)) {
MoveTo(frame.left,frame.top);
ResizeTo(frame.right-frame.left,frame.bottom-frame.top);
}
}
// -------------------------------------------------------------------------------------------------- //
// CDPlayerWindow::SaveSettings -- Saves the Users settings
void CDPlayerWindow::SaveSettings(void)
{
BMessage msg;
msg.AddRect("windowframe",Frame());
BPath path;
status_t result = find_directory(B_USER_SETTINGS_DIRECTORY,&path);
if (result == B_OK) {
path.Append("CDPlayer_Settings",true);
BFile file(path.Path(),B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
msg.Flatten(&file);
}
}
// -------------------------------------------------------------------------------------------------- //
// CDPlayerWindow::MessageReceived -- receives messages
void CDPlayerWindow::MessageReceived (BMessage *message)
{
switch(message->what)
{
default:
BWindow::MessageReceived(message);
break;
}
}
// -------------------------------------------------------------------------------------------------- //

View File

@ -1,34 +0,0 @@
/*
CDPlayer Windows Header
Author: Sikosis
(C)2004 Haiku - http://haiku-os.org/
*/
#ifndef __CDPLAYERWINDOWS_H__
#define __CDPLAYERWINDOWS_H__
#include "CDPlayer.h"
#include "CDPlayerViews.h"
class CDPlayerView;
class CDPlayerWindow : public BWindow
{
public:
CDPlayerWindow(BRect frame);
~CDPlayerWindow();
virtual bool QuitRequested();
virtual void MessageReceived(BMessage *message);
private:
void InitWindow(void);
void LoadSettings(BMessage *msg);
void SaveSettings(void);
CDPlayerView* ptrCDPlayerView;
};
#endif

View File

@ -0,0 +1,69 @@
#include "DrawButton.h"
DrawButton::DrawButton(BRect frame, const char *name, BBitmap *up, BBitmap *down,
BMessage *msg, int32 resize, int32 flags)
: BButton(frame, name, "", msg, resize, flags)
{
fUp=up;
fDown=down;
fDisabled=NULL;
}
DrawButton::~DrawButton(void)
{
}
void DrawButton::SetBitmaps(BBitmap *up, BBitmap *down)
{
delete fUp;
delete fDown;
fUp=up;
fDown=down;
}
void DrawButton::SetDisabled(BBitmap *disabled)
{
delete fDisabled;
fDisabled=disabled;
}
void DrawButton::Draw(BRect update)
{
if(!IsEnabled())
{
if(fDisabled)
DrawBitmap(fDisabled, BPoint(0,0));
else
StrokeRect(Bounds());
return;
}
if(Value() == B_CONTROL_ON)
{
if(fDown)
DrawBitmap(fDown, BPoint(0,0));
else
StrokeRect(Bounds());
}
else
{
if(fUp)
DrawBitmap(fUp, BPoint(0,0));
else
StrokeRect(Bounds());
}
}
void DrawButton::ResizeToPreferred(void)
{
if(fUp)
ResizeTo(fUp->Bounds().Width(),fUp->Bounds().Height());
else
if(fDown)
ResizeTo(fDown->Bounds().Width(),fDown->Bounds().Height());
else
if(fDisabled)
ResizeTo(fDisabled->Bounds().Width(),fDisabled->Bounds().Height());
}

View File

@ -0,0 +1,31 @@
#ifndef _DRAW_BUTTON_H
#define _DRAW_BUTTON_H
#include <Looper.h>
#include <Application.h>
#include <Window.h>
#include <Button.h>
#include <Bitmap.h>
#include <Rect.h>
class DrawButton : public BButton
{
public:
DrawButton(BRect frame, const char *name, BBitmap *up, BBitmap *down,
BMessage *msg, int32 resize, int32 flags);
~DrawButton(void);
void Draw(BRect update);
void SetBitmaps(BBitmap *up, BBitmap *down);
void ResizeToPreferred(void);
void SetDisabled(BBitmap *disabled);
private:
BBitmap *fUp, *fDown, *fDisabled;
};
#endif

View File

@ -0,0 +1,50 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
// This defines code for sending funciton objects in messages
#ifndef _BE_H
#include <Debug.h>
#endif
#include "FunctionObjectMessage.h"
BMessage *
FunctorFactoryCommon::NewMessage(const FunctionObject *functor)
{
BMessage *result = new BMessage('fCmG');
ASSERT(result);
long error = result->AddData("functor", B_RAW_TYPE,
functor, functor->Size());
if (error != B_NO_ERROR) {
delete result;
result = NULL;
}
return result;
}
bool
FunctorFactoryCommon::DispatchIfFunctionObject(BMessage *message)
{
if (message->what != 'fCmG')
return false;
// find the functor
long size;
FunctionObject *functor;
status_t error = message->FindData("functor", B_RAW_TYPE, (const void**)&functor, &size);
if (error != B_NO_ERROR)
return false;
ASSERT(functor);
// functor found, call it
(*functor)();
return true;
}

View File

@ -0,0 +1,73 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
// This defines some function object glue code
// See the Be Newsletter article about using Function Objects in the Be messaging
// model for more information
#ifndef __FUNCTION_OBJECT_MESSAGE__
#define __FUNCTION_OBJECT_MESSAGE__
#ifndef _BE_H
#include <Message.h>
#include <MessageFilter.h>
#endif
class FunctionObject {
public:
virtual void operator()() = 0;
virtual ~FunctionObject() {}
virtual ulong Size() const = 0;
};
template<class FT, class T>
class PlainMemberFunctionObject : public FunctionObject {
public:
PlainMemberFunctionObject(FT callThis, T *onThis)
: function(callThis),
target(onThis)
{
}
virtual ~PlainMemberFunctionObject() {}
virtual void operator()()
{ (target->*function)(); }
virtual ulong Size() const { return sizeof(*this); }
private:
FT function;
T *target;
};
template<class FT, class T, class P>
class SingleParamMemberFunctionObject : public FunctionObject {
public:
SingleParamMemberFunctionObject(FT callThis, T *onThis, P withThis)
: function(callThis),
target(onThis),
parameter(withThis)
{
}
virtual ~SingleParamMemberFunctionObject() {}
virtual void operator()()
{ (target->*function)(parameter); }
virtual ulong Size() const { return sizeof(*this); }
private:
FT function;
T *target;
P parameter;
};
class FunctorFactoryCommon {
public:
static bool DispatchIfFunctionObject(BMessage *);
protected:
static BMessage *NewMessage(const FunctionObject *);
};
#endif

View File

@ -1,5 +1,13 @@
SubDir OBOS_TOP src apps cdplayer ;
AddResources CDPlayer : CDPlayer.rdef ;
App CDPlayer : CDPlayer.cpp CDPlayerWindow.cpp CDPlayerView.cpp ;
LinkSharedOSLibs CDPlayer : be ;
App CDPlayer :
CDButton.cpp
CDDBSupport.cpp
CDEngine.cpp
DrawButton.cpp
FunctionObjectMessage.cpp
Observer.cpp
TypedList.cpp
;
LinkSharedOSLibs CDPlayer : be net netapi translation ;

31
src/apps/cdplayer/LICENSE Normal file
View File

@ -0,0 +1,31 @@
----------------------
Be Sample Code License
----------------------
Copyright 1991-1999, Be Incorporated.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,180 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
// This defines the Observer and Notifier classes
#include <Message.h>
#include <Looper.h>
#include <Debug.h>
#include "Observer.h"
Observer::Observer(Notifier *target)
: observedList(4, true)
{
if (target)
StartObserving(target);
}
Observer::~Observer()
{
StopObserving();
// tell everyone to stop sending us notices
}
void
Observer::StartObserving(Notifier *target)
{
ASSERT(target->RecipientHandler());
ASSERT(RecipientHandler()->Looper());
// send a message to the notifier to start sending us notices
if (target->RecipientHandler()->Looper()) {
BMessage *message = new BMessage(kStartObserving);
message->AddPointer("observer", this);
message->AddPointer("observed", target);
// send the message to the looper associated with the
// notifier
target->RecipientHandler()->Looper()->PostMessage(message,
target->RecipientHandler());
NotifierListEntry *entry = new NotifierListEntry;
entry->observed = target;
entry->handler = target->RecipientHandler();
entry->looper = target->RecipientHandler()->Looper();
observedList.AddItem(entry);
}
}
void
Observer::SendStopObserving(NotifierListEntry *target)
{
// send a message to the notifier to start sending us notices
if (target->looper) {
BMessage *message = new BMessage(kEndObserving);
message->AddPointer("observer", this);
message->AddPointer("observed", target->observed);
target->looper->PostMessage(message, target->handler);
}
}
NotifierListEntry *
StopObservingOne(NotifierListEntry *observed, void *castToObserver)
{
((Observer *)castToObserver)->SendStopObserving(observed);
return 0;
}
void
Observer::StopObserving()
{
// send a message to all the notifiers to start sending us notices
observedList.EachElement(StopObservingOne, this);
observedList.MakeEmpty();
}
bool
Observer::HandleObservingMessages(const BMessage *message)
{
switch (message->what) {
case kNoticeChange:
{
// look for notice messages from notifiers
Notifier *observed = NULL;
Observer *observer = NULL;
message->FindPointer("observed", (void**)&observed);
message->FindPointer("observer", (void**)&observer);
ASSERT(observed);
ASSERT(observer);
if (!observed || !observer)
return false;
ASSERT(dynamic_cast<Observer *>(observer));
// this is a notice for us, call the NoticeChange function
observer->NoticeChange(observed);
return true;
}
default:
return false;
}
}
static ObserverListEntry *
NotifyOne(ObserverListEntry *observer, void *castToObserved)
{
if (observer->looper) {
BMessage *message = new BMessage(kNoticeChange);
message->AddPointer("observed", castToObserved);
message->AddPointer("observer", observer->observer);
observer->looper->PostMessage(message, observer->handler);
}
return 0;
}
void
Notifier::Notify()
{
// send notices to all the observers
observerList.EachElement(NotifyOne, this);
}
static ObserverListEntry *
FindItemWithObserver(ObserverListEntry *item, void *castToObserver)
{
if (item->observer == castToObserver)
return item;
return 0;
}
void
Notifier::AddObserver(Observer *observer)
{
ObserverListEntry *item = new ObserverListEntry;
item->observer = observer;
item->handler = observer->RecipientHandler();
item->looper = observer->RecipientHandler()->Looper();
ASSERT(item->looper);
observerList.AddUnique(item);
}
void
Notifier::RemoveObserver(Observer *observer)
{
ObserverListEntry *item = observerList.EachElement(
FindItemWithObserver, observer);
observerList.RemoveItem(item);
delete item;
}
bool
Notifier::HandleObservingMessages(const BMessage *message)
{
switch (message->what) {
case kStartObserving:
case kEndObserving:
{
// handle messages about stopping and starting observing
Observer *observer = 0;
Notifier *observed = 0;
message->FindPointer("observer", (void**)&observer);
message->FindPointer("observed", (void**)&observed);
ASSERT(observer);
ASSERT(observed);
if (!observer || !observed)
return false;
if (message->what == kStartObserving)
observed->AddObserver(observer);
else
observed->RemoveObserver(observer);
return true;
}
default:
return false;
}
}

View File

@ -0,0 +1,98 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
// This defines the Observer and Notifier classes
// The idea of observing is make it easier to support a client-server
// setup where a client want's to react to changes in the server state,
// for instance a view displaying a track number needs to change whenever
// a track changes. Normally this is done by the client periodically checking
// the server from within a Pulse call or a simillar mechanism. With Observer
// and Notifier, the Observer (client) starts observing a Notifier (server)
// and then just sits back and wait to get a notice, whenever the Notifier
// changes.
#ifndef __OBSERVER__
#define __OBSERVER__
#include "TypedList.h"
#include <Handler.h>
const uint32 kNoticeChange = 'notc';
const uint32 kStartObserving = 'stob';
const uint32 kEndObserving = 'edob';
class Notifier;
class NotifierListEntry {
public:
Notifier *observed;
BHandler *handler;
BLooper *looper;
};
class Observer {
public:
Observer(Notifier *target = NULL);
virtual ~Observer();
void StartObserving(Notifier *);
// start observing a speficied notifier
void StopObserving(Notifier *);
// stop observing a speficied notifier
void StopObserving();
// stop observing all the observed notifiers
virtual void NoticeChange(Notifier *) = 0;
// override this to get your job done, your class will get called
// whenever the Notifier changes
static bool HandleObservingMessages(const BMessage *message);
// call this from subclasses MessageReceived
virtual BHandler *RecipientHandler() const = 0;
// hook this up to return subclasses looper
private:
void SendStopObserving(NotifierListEntry *);
// keep a list of all the observed notifiers
TypedList<NotifierListEntry *> observedList;
friend NotifierListEntry *StopObservingOne(NotifierListEntry *, void *);
};
class ObserverListEntry {
public:
Observer *observer;
BHandler *handler;
BLooper *looper;
};
class Notifier {
public:
Notifier()
{}
virtual ~Notifier()
{}
virtual void Notify();
// call this when the notifier object changes to send notices
// to all the observers
static bool HandleObservingMessages(const BMessage *message);
// call this from subclasses MessageReceived
virtual BHandler *RecipientHandler() const = 0;
// hook this up to return subclasses looper
// keep a list of all the observers so that we can send them notices
void AddObserver(Observer *);
void RemoveObserver(Observer *);
private:
TypedList<ObserverListEntry *> observerList;
friend class Observer;
};
#endif

View File

@ -0,0 +1,87 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
// TypedList is a type-safe template version of BList
#include <Debug.h>
#include "TypedList.h"
void *
_PointerList::EachElement(GenericEachFunction func, void *passThru)
{
// iterates through all elements, calling func on each
// if each function returns a nonzero value, terminates early
void *result = NULL;
int32 numElements = CountItems();
for (int32 index = 0; index < numElements; index++)
if ((result = func(ItemAtFast(index), passThru)) != NULL)
break;
return result;
}
_PointerList::_PointerList(const _PointerList &list)
: BList(list),
owning(list.owning)
{
}
_PointerList::_PointerList(int32 itemsPerBlock = 20, bool owningList)
: BList(itemsPerBlock),
owning(owningList)
{
}
_PointerList::~_PointerList()
{
}
bool
_PointerList::Owning() const
{
return owning;
}
bool
_PointerList::AddUnique(void *newItem)
{
if (IndexOf(newItem) >= 0)
return false;
return AddItem(newItem);
}
struct OneMatchParams {
void *matchThis;
_PointerList::GenericCompareFunction matchFunction;
};
static void *
MatchOne(void *item, void *castToParams)
{
OneMatchParams *params = (OneMatchParams *)castToParams;
if (params->matchFunction(item, params->matchThis) == 0)
// got a match, terminate search
return item;
return 0;
}
bool
_PointerList::AddUnique(void *newItem, GenericCompareFunction function)
{
OneMatchParams params;
params.matchThis = newItem;
params.matchFunction = function;
if (EachElement(MatchOne, &params))
// already in list
return false;
return AddItem(newItem);
}

View File

@ -0,0 +1,326 @@
/*
Copyright 1999, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
// TypedList is a garden-variety of a type-safe template version of BList
#ifndef __LIST_TEMPLATE__
#define __LIST_TEMPLATE__
#ifndef _BE_H
#include <List.h>
#endif
#include <Debug.h>
class _PointerList : public BList {
public:
_PointerList(const _PointerList &list);
_PointerList(int32 itemsPerBlock = 20, bool owning = false);
virtual ~_PointerList();
typedef void *(* GenericEachFunction)(void *, void *);
typedef int (* GenericCompareFunction)(const void *, const void *);
void *EachElement(GenericEachFunction, void *);
bool AddUnique(void *);
// return true if item added or already in the list
bool AddUnique(void *, GenericCompareFunction);
bool Owning() const;
private:
const bool owning;
};
// TypedList -
// to be used as a list of pointers to objects; this class should contain
// pretty much no code, just stubs that do proper type conversion
// it uses BetterEachBList for all of it's functionality and provides a
// typed interface
template<class T>
class TypedList : public _PointerList {
public:
TypedList(int32 itemsPerBlock = 20, bool owning = false);
TypedList(const TypedList&);
virtual ~TypedList();
TypedList &operator=(const TypedList &);
// iteration and sorting
typedef T (* EachFunction)(T, void *);
typedef const T (* ConstEachFunction)(const T, void *);
typedef int (* CompareFunction)(const T *, const T *);
// adding and removing
bool AddItem(T);
bool AddItem(T, int32);
bool AddList(TypedList *);
bool AddList(TypedList *, int32);
bool AddUnique(T);
bool AddUnique(T, CompareFunction);
bool RemoveItem(T);
T RemoveItem(int32);
T RemoveItemAt(int32);
// same as RemoveItem(int32), RemoveItem does not work when T is a scalar
void MakeEmpty();
// item access
T ItemAt(int32) const;
T ItemAtFast(int32) const;
// does not do an index range check
T FirstItem() const;
T LastItem() const;
T Items() const;
// misc. getters
int32 IndexOf(const T) const;
bool HasItem(const T) const;
bool IsEmpty() const;
int32 CountItems() const;
T EachElement(EachFunction, void *);
const T EachElement(ConstEachFunction, void *) const;
// Do for each are obsoleted by this list, possibly add
// them for convenience
void SortItems(CompareFunction);
bool ReplaceItem(int32 index, T item);
bool SwapItems(int32 a, int32 b);
bool MoveItem(int32 from, int32 to);
private:
friend class ParseArray;
};
template<class T>
TypedList<T>::TypedList(int32 itemsPerBlock, bool owning)
: _PointerList(itemsPerBlock, owning)
{
}
template<class T>
TypedList<T>::TypedList(const TypedList<T> &list)
: _PointerList(list)
{
ASSERT(!list.Owning());
// copying owned lists does not work yet
}
template<class T>
TypedList<T>::~TypedList()
{
if (Owning())
// have to nuke elements first
MakeEmpty();
}
template<class T>
TypedList<T> &
TypedList<T>::operator=(const TypedList<T> &from)
{
ASSERT(!from.Owning());
// copying owned lists does not work yet
return (TypedList<T> &)BList::operator=(from);
}
template<class T>
bool
TypedList<T>::AddItem(T item)
{
return _PointerList::AddItem(item);
}
template<class T>
bool
TypedList<T>::AddItem(T item, int32 atIndex)
{
return _PointerList::AddItem(item, atIndex);
}
template<class T>
bool
TypedList<T>::AddList(TypedList<T> *newItems)
{
return _PointerList::AddList(newItems);
}
template<class T>
bool
TypedList<T>::AddList(TypedList<T> *newItems, int32 atIndex)
{
return _PointerList::AddList(newItems, atIndex);
}
template<class T>
bool
TypedList<T>::AddUnique(T item)
{
return _PointerList::AddUnique(item);
}
template<class T>
bool
TypedList<T>::AddUnique(T item, CompareFunction function)
{
return _PointerList::AddUnique(item, (GenericCompareFunction)function);
}
template<class T>
bool
TypedList<T>::RemoveItem(T item)
{
bool result = _PointerList::RemoveItem(item);
if (result && Owning()) {
delete item;
}
return result;
}
template<class T>
T
TypedList<T>::RemoveItem(int32 index)
{
return (T)_PointerList::RemoveItem(index);
}
template<class T>
T
TypedList<T>::RemoveItemAt(int32 index)
{
return (T)_PointerList::RemoveItem(index);
}
template<class T>
T
TypedList<T>::ItemAt(int32 index) const
{
return (T)_PointerList::ItemAt(index);
}
template<class T>
T
TypedList<T>::ItemAtFast(int32 index) const
{
return (T)_PointerList::ItemAtFast(index);
}
template<class T>
int32
TypedList<T>::IndexOf(const T item) const
{
return _PointerList::IndexOf(item);
}
template<class T>
T
TypedList<T>::FirstItem() const
{
return (T)_PointerList::FirstItem();
}
template<class T>
T
TypedList<T>::LastItem() const
{
return (T)_PointerList::LastItem();
}
template<class T>
bool
TypedList<T>::HasItem(const T item) const
{
return _PointerList::HasItem(item);
}
template<class T>
bool
TypedList<T>::IsEmpty() const
{
return _PointerList::IsEmpty();
}
template<class T>
int32
TypedList<T>::CountItems() const
{
return _PointerList::CountItems();
}
template<class T>
void
TypedList<T>::MakeEmpty()
{
if (Owning()) {
int32 numElements = CountItems();
for (int32 count = 0; count < numElements; count++)
// this is probably not the most efficient, but
// is relatively indepenent of BList implementation
// details
RemoveItem(LastItem());
}
_PointerList::MakeEmpty();
}
template<class T>
T
TypedList<T>::EachElement(EachFunction func, void *params)
{
return (T)_PointerList::EachElement((GenericEachFunction)func, params);
}
template<class T>
const T
TypedList<T>::EachElement(ConstEachFunction func, void *params) const
{
return (const T)
const_cast<TypedList<T> *>(this)->_PointerList::EachElement(
(GenericEachFunction)func, params);
}
template<class T>
T
TypedList<T>::Items() const
{
return (T)_PointerList::Items();
}
template<class T>
void
TypedList<T>::SortItems(CompareFunction function)
{
ASSERT(sizeof(T) == sizeof(void *));
_PointerList::SortItems((GenericCompareFunction)function);
}
template<class T>
bool TypedList<T>::ReplaceItem(int32 index, T item)
{
return _PointerList::ReplaceItem(index, (void *)item);
}
template<class T>
bool TypedList<T>::SwapItems(int32 a, int32 b)
{
return _PointerList::SwapItems(a, b);
}
template<class T>
bool TypedList<T>::MoveItem(int32 from, int32 to)
{
return _PointerList::MoveItem(from, to);
}
#endif